static int[] shiftLeftMultiPrecision(int[] number, int length, int shifts)
    {
        if (shifts == 0) {
            return number;
        }
        // wordShifts = shifts / 32
        int wordShifts = shifts >>> 5;
        // we don't want to lose any leading bits
        for (int i = 0; i < wordShifts; i++) {
            checkState(number[length - i - 1] == 0);
        }
        if (wordShifts > 0) {
            arraycopy(number, 0, number, wordShifts, length - wordShifts);
            fill(number, 0, wordShifts, 0);
        }
        // bitShifts = shifts % 32
        int bitShifts = shifts & 0b11111;
        if (bitShifts > 0) {
            // we don't want to lose any leading bits
            checkState(number[length - 1] >>> (Integer.SIZE - bitShifts) == 0);
            for (int position = length - 1; position > 0; position--) {
                number[position] = (number[position] << bitShifts) | (number[position - 1] >>> (Integer.SIZE - bitShifts));
            }
            number[0] = number[0] << bitShifts;
        }
        return number;
    }
@Test
    public void testShiftLeftMultiPrecision()
    {
        assertEquals(shiftLeftMultiPrecision(
                new int[] {0b10100001010001011010000101000101, 0b01010110100101101011010101010101, 0b01010010111110001111100010101010,
                        0b11111111000000011010101010101011, 0b00000000000000000000000000000000}, 4, 0),
                new int[] {0b10100001010001011010000101000101, 0b01010110100101101011010101010101, 0b01010010111110001111100010101010,
                        0b11111111000000011010101010101011, 0b00000000000000000000000000000000});
        assertEquals(shiftLeftMultiPrecision(
                new int[] {0b10100001010001011010000101000101, 0b01010110100101101011010101010101, 0b01010010111110001111100010101010,
                        0b11111111000000011010101010101011, 0b00000000000000000000000000000000}, 5, 1),
                new int[] {0b01000010100010110100001010001010, 0b10101101001011010110101010101011, 0b10100101111100011111000101010100,
                        0b11111110000000110101010101010110, 0b00000000000000000000000000000001});
        assertEquals(shiftLeftMultiPrecision(
                new int[] {0b10100001010001011010000101000101, 0b01010110100101101011010101010101, 0b01010010111110001111100010101010,
                        0b11111111000000011010101010101011, 0b00000000000000000000000000000000}, 5, 31),
                new int[] {0b10000000000000000000000000000000, 0b11010000101000101101000010100010, 0b00101011010010110101101010101010,
                        0b10101001011111000111110001010101, 0b1111111100000001101010101010101});
        assertEquals(shiftLeftMultiPrecision(
                new int[] {0b10100001010001011010000101000101, 0b01010110100101101011010101010101, 0b01010010111110001111100010101010,
                        0b11111111000000011010101010101011, 0b00000000000000000000000000000000}, 5, 32),
                new int[] {0b00000000000000000000000000000000, 0b10100001010001011010000101000101, 0b01010110100101101011010101010101,
                        0b01010010111110001111100010101010, 0b11111111000000011010101010101011});
        assertEquals(shiftLeftMultiPrecision(
                new int[] {0b10100001010001011010000101000101, 0b01010110100101101011010101010101, 0b01010010111110001111100010101010,
                        0b11111111000000011010101010101011, 0b00000000000000000000000000000000, 0b00000000000000000000000000000000}, 6, 33),
                new int[] {0b00000000000000000000000000000000, 0b01000010100010110100001010001010, 0b10101101001011010110101010101011,
                        0b10100101111100011111000101010100, 0b11111110000000110101010101010110, 0b00000000000000000000000000000001});
        assertEquals(shiftLeftMultiPrecision(
                new int[] {0b10100001010001011010000101000101, 0b01010110100101101011010101010101, 0b01010010111110001111100010101010,
                        0b11111111000000011010101010101011, 0b00000000000000000000000000000000, 0b00000000000000000000000000000000}, 6, 37),
                new int[] {0b00000000000000000000000000000000, 0b00101000101101000010100010100000, 0b11010010110101101010101010110100,
                        0b01011111000111110001010101001010, 0b11100000001101010101010101101010, 0b00000000000000000000000000011111});
        assertEquals(shiftLeftMultiPrecision(
                new int[] {0b10100001010001011010000101000101, 0b01010110100101101011010101010101, 0b01010010111110001111100010101010,
                        0b11111111000000011010101010101011, 0b00000000000000000000000000000000, 0b00000000000000000000000000000000}, 6, 64),
                new int[] {0b00000000000000000000000000000000, 0b00000000000000000000000000000000, 0b10100001010001011010000101000101,
                        0b01010110100101101011010101010101, 0b01010010111110001111100010101010, 0b11111111000000011010101010101011});
    }