Я хочу использовать Excel для умножения 32-битных целых чисел и получить нижние 32 бита. Другими словами, для заданных чисел n1, n2 я хочу вычислить MOD(n1*n2, 2^32)
. Однако эта формула не работает в Excel, потому что (для больших n1 и n2) произведение превышает точность Excel и, следовательно, округляет нижние цифры. Есть ли способ избежать этого, продолжая использовать Excel?
Одно из примитивных решений, которое мне удалось придумать, состояло в том, чтобы просто разбить одно из чисел на 8-битные части и умножить их соответствующим образом ( MOD
при необходимости используя усечение), но я ищу что-то менее запутанное, надеюсь.
решение1
Если вы используете 64-битный офис, то вы можетесоздать пользовательскую функциюи используйте новыйLongLong
типдля расчета. Нажмите Alt+ F11, чтобы открыть редактор Visual Basic, щелкнитеВставить > Модульзатем вставьте приведенный ниже код
Public Function MulMod32(number1, number2) As Double
Dim n1 As LongLong, n2 As LongLong
n1 = CLngLng(number1)
n2 = CLngLng(number2)
' Sign-extend the numbers
n1 = IIf((n1 And &H80000000&) = 0, n1, n1 Or &HFFFFFFFF00000000^)
n2 = IIf((n2 And &H80000000&) = 0, n2, n2 Or &HFFFFFFFF00000000^)
MulMod32 = CDbl((n1 * n2) And &HFFFFFFFF^)
End Function
После этого вы можете использовать MulMod32()
в любой формуле, например=MulMod32(HEX2DEC("fffffffe"), HEX2DEC("ffff1234"))
Если у вас нет, LongLong
то вы можете разбить число на более мелкие части для работы, но вам не нужно работать с 8-битными частями, потому что 16-битных значений достаточно. Если у нас есть a и b, то после разделения их на (ah, al) и (bh, bl) и их произведение можно вычислить следующим образом
а × б = (ах × 2 16 + ал)(бх × 2 16 + бл) = ах × бх × 2 32 + (ах × бл + ал × бх) × 2 16 + ал × бл
Таким образом, у нас может быть 4 столбца для ah, al, bh, bl и столбец для продукта со следующими формулами:
А1 | В1 |
---|---|
ах | =БИТСДВИГ(a, 16) |
аль | =БИТИ(a, 65535) |
бх | =БИТСДВИГ(b, 16) |
бл | =БИТИ(b, 65535) |
продукт | =БИТИ(БИТИ((ah*bl + bh*al), 65535)*2^16 + al*bl, 4294967295) |
решение2
Если вы посмотрите наспецификации и ограничениявы обнаружите, что по крайней мере с версии Excel 2007 действуют следующие ограничения:
Особенность Максимальный предел Точность чисел 15 цифр Наименьшее допустимое отрицательное число -2.2251E-308 Наименьшее допустимое положительное число 2.2251E-308 Наибольшее допустимое положительное число 9.999999999999999E+307 Наибольшее допустимое отрицательное число -9.99999999999999E+307 Наибольшее допустимое положительное число по формуле 1.7976931348623158e+308 Наибольшее допустимое отрицательное число по формуле -1.7976931348623158e+308
Как видите, вы неизбежно потеряете точность в зависимости от используемых вами чисел.
Поскольку вы указали 32-битные числа (предполагая, что это целые числа без знака), максимальное значение, которое вам нужно будет вычислить, составит 18 446 744 073 709 551 616 (2 32 * 2 32 = 2 64 ), что явно превышает ограничение в 15 цифр, хотя и не превышает ограничение максимального числа, которое можно вычислить.
Кроме того, если вы планируете получить нижние 32 бита результата, вероятно, будет лучше прибегнуть к реальному языку программирования или скриптовому языку для выполнения таких вычислений.
решение3
Одно из примитивных решений, которое мне удалось придумать, состояло в том, чтобы просто разбить одно из чисел на 8-битные части и умножить их соответствующим образом (используя MOD, когда это необходимо для усечения), но я, надеюсь, ищу что-то менее запутанное.