result = result << shift */
| 999 | |
| 1000 | /* result = result << shift */ |
| 1001 | static void |
| 1002 | BigInt_ShiftLeft(BigInt *result, npy_uint32 shift) |
| 1003 | { |
| 1004 | npy_uint32 shiftBlocks = shift / 32; |
| 1005 | npy_uint32 shiftBits = shift % 32; |
| 1006 | |
| 1007 | /* process blocks high to low so that we can safely process in place */ |
| 1008 | const npy_uint32 *pInBlocks = result->blocks; |
| 1009 | npy_int32 inLength = result->length; |
| 1010 | npy_uint32 *pInCur, *pOutCur; |
| 1011 | |
| 1012 | DEBUG_ASSERT(inLength + shiftBlocks < c_BigInt_MaxBlocks); |
| 1013 | DEBUG_ASSERT(shift != 0); |
| 1014 | |
| 1015 | /* check if the shift is block aligned */ |
| 1016 | if (shiftBits == 0) { |
| 1017 | npy_uint32 i; |
| 1018 | |
| 1019 | /* copy blocks from high to low */ |
| 1020 | for (pInCur = result->blocks + result->length, |
| 1021 | pOutCur = pInCur + shiftBlocks; |
| 1022 | pInCur >= pInBlocks; |
| 1023 | --pInCur, --pOutCur) { |
| 1024 | *pOutCur = *pInCur; |
| 1025 | } |
| 1026 | |
| 1027 | /* zero the remaining low blocks */ |
| 1028 | for (i = 0; i < shiftBlocks; ++i) { |
| 1029 | result->blocks[i] = 0; |
| 1030 | } |
| 1031 | |
| 1032 | result->length += shiftBlocks; |
| 1033 | } |
| 1034 | /* else we need to shift partial blocks */ |
| 1035 | else { |
| 1036 | npy_uint32 i; |
| 1037 | npy_int32 inBlockIdx = inLength - 1; |
| 1038 | npy_uint32 outBlockIdx = inLength + shiftBlocks; |
| 1039 | |
| 1040 | /* output the initial blocks */ |
| 1041 | const npy_uint32 lowBitsShift = (32 - shiftBits); |
| 1042 | npy_uint32 highBits = 0; |
| 1043 | npy_uint32 block = result->blocks[inBlockIdx]; |
| 1044 | npy_uint32 lowBits = block >> lowBitsShift; |
| 1045 | |
| 1046 | /* set the length to hold the shifted blocks */ |
| 1047 | DEBUG_ASSERT(outBlockIdx < c_BigInt_MaxBlocks); |
| 1048 | result->length = outBlockIdx + 1; |
| 1049 | |
| 1050 | while (inBlockIdx > 0) { |
| 1051 | result->blocks[outBlockIdx] = highBits | lowBits; |
| 1052 | highBits = block << shiftBits; |
| 1053 | |
| 1054 | --inBlockIdx; |
| 1055 | --outBlockIdx; |
| 1056 | |
| 1057 | block = result->blocks[inBlockIdx]; |
| 1058 | lowBits = block >> lowBitsShift; |