Неправильное переполнение VBA с использованием Doubles (Excel)

По какой-то причине следующий оператор оценивается как нуль. Я предполагаю, что это связано с переполнением, но все промежуточные значения, похоже, находятся в пределах двойного значения.

DiffieHellmanKey = (43 ^ 47) - (53 * Fix((43 ^ 47) / 53))

Я думаю, что это переполнение, потому что когда я выполняю его с разными числами (ниже), это приводит к правильному значению 29.

DiffieHellmanKey = (5 ^ 22) - (53 * Fix((5 ^ 22) / 53))

Что дает? Теперь вернемся к исходным числам, которые дают мне переполнение. Все задействованные переменные являются двойными. Это даже не работает, если я вычисляю его как формулу рабочего листа, а не в VBA:

=(43 ^ 47) - (53 * ROUNDDOWN(((43 ^ 47) / 53), 0))

И если я реализую приведенный выше пример в VBA, используя эквивалентную форму (ниже), я получаю неверный результат -1,75357E+62.

DiffieHellmanKey = (43 ^ 47) - (53 * WorksheetFunction.RoundDown(((43 ^ 47) / 53), 0))

person ndgibson    schedule 19.10.2012    source источник


Ответы (2)


Вы вроде правы, но ваша проблема не в переполнении, а в значащих цифрах.

Числа в Microsoft Excel никогда не могут иметь более 15 значащих цифр, но десятичные дроби могут достигать 127.

источник: http://msdn.microsoft.com/en-us/library/office/ff838588.aspx

Вот что происходило с вашей исходной формулой:

(43 ^ 47) - (53 * Fix((43 ^ 47) / 53)) упрощается до (43 ^ 47) - fix(43 ^ 47) Тогда (43 ^ 47) имеет длину около 76 цифр, поэтому они обе сокращаются до одинаковой суммы и приравниваются к 0.

Самый большой тип переменной в VBA — «Десятичный», который содержит только 29 значащих цифр. Вы не сможете выполнять такие большие математические вычисления, используя Visual Basic изначально.

person danielpiestrak    schedule 19.10.2012
comment
Я понимаю логику здесь, но для меня ваша фиксированная функция: (.43 ^ 47) - (53 * Fix((.43 ^ 47)/53))*10000 оценивается как 5,92949097309764E-18, а не 29. - person ndgibson; 19.10.2012
comment
Сделал двойную проверку и понял, что даже мой ответ все еще достигает максимума. Пробовал несколько других вещей и в итоге получил ответ выше. Суть в том, что нам нужно до 74 цифр точности для вашего примера, и ни одна из переменных в VBA не достигает такого высокого значения. - person danielpiestrak; 19.10.2012
comment
Хорошо спасибо. Так что, похоже, единственным выходом были бы струны. - person ndgibson; 19.10.2012
comment
Мне было бы интересно узнать, есть ли в VBA обходной путь для выполнения таких больших вычислений. Я предполагаю, что вы сможете создать массив, содержащий, скажем, 300 цифр от 0 до 9, и использовать его как массивную переменную. Затем написать функции, которые выполняют над ним математические функции. - person danielpiestrak; 19.10.2012

person    schedule
comment
В некоторых примерах я поменял номера, извините. Исправлена. - person ndgibson; 19.10.2012
comment
Я смотрел на ваш первый пример, и он все еще выглядит для меня так же. Что вы ожидаете в результате там? - person Tim Williams; 19.10.2012
comment
Он должен оцениваться как 29. Это базовая криптография RSA, поэтому все четыре приведенных выше примера должны давать 29. Работает только второй (с меньшими числами). - person ndgibson; 19.10.2012
comment
Я думаю, вы упираетесь в предел точности для двойников в VBA (около 15 цифр?) - person Tim Williams; 19.10.2012
comment
@TimWilliams Ты прав. Я как раз писал свой ответ по этому поводу. :] - person danielpiestrak; 19.10.2012
comment
Вы можете делать такие вещи в VB(A), но это требует обработки необходимых больших целых чисел в виде строк: di-mgt.com.au/crypto.html#dhvb - person Tim Williams; 19.10.2012