Наибольшее целое число, которое может быть сохранено в двойном
Какое наибольшее целое число без плавающих может быть сохранено в двойном типе IEEE 754 без потери точности?
12 ответов
Наибольшее / наибольшее целое число, которое может храниться в двойном значении без потери точности, совпадает с наибольшим возможным значением двойного числа. То есть, DBL_MAX
или примерно 1,8 × 10 308 (если ваш двойник является 64-битным двойником IEEE 754). Это целое число. Это представлено точно. Что вы еще хотите?
Продолжайте, спросите меня, какое наибольшее целое число такое, чтобы оно и все меньшие целые числа могли быть сохранены в 64-битных двойных числах IEEE без потери точности. IEEE 64-битный дубль имеет 52 бита мантиссы, поэтому я думаю, что это 2 53:
- 2 53 + 1 не может быть сохранено, потому что 1 в начале и 1 в конце имеют слишком много нулей между ними.
- Все, что меньше 2 53, может быть сохранено, с 52 битами, которые явно хранятся в мантиссе, а затем экспонента дает вам еще один.
- 2 53, очевидно, могут быть сохранены, так как это небольшая степень 2.
Или другой способ взглянуть на это: как только смещение было снято с показателя степени, и игнорируя знаковый бит как не относящийся к вопросу, значение, хранимое в double, является степенью 2 плюс 52-битное целое число, умноженное на 2 показатель степени - 52. Таким образом, с показателем 52 вы можете сохранить все значения от 2 52 до 2 53 - 1. Затем с показателем 53 следующее число, которое вы можете сохранить после 2 53, равно 2 53 + 1 × 2 53 - 52. Таким образом, потеря точности сначала происходит с 2 53 + 1.
9007199254740992 (это 9 007 199 254 740 992) без каких-либо гарантий:)
программа
#include <math.h>
#include <stdio.h>
int main(void) {
double dbl = 0; /* I started with 9007199254000000, a little less than 2^53 */
while (dbl + 1 != dbl) dbl++;
printf("%.0f\n", dbl - 1);
printf("%.0f\n", dbl);
printf("%.0f\n", dbl + 1);
return 0;
}
Результат
9007199254740991 9007199254740992 9007199254740992
Наибольшее целое число, которое может быть представлено в двойном (64-разрядном) IEEE 754, совпадает с наибольшим значением, которое может представлять тип, поскольку само это целое число.
Это представляется как 0x7FEFFFFFFFFFFFFF
, который состоит из:
- Знаковый бит 0 (положительный), а не 1 (отрицательный)
- Максимальный показатель
0x7FE
(2046, который представляет 1023 после смещения вычитается), а не0x7FF
(2047, который указывает наNaN
или бесконечность). - Максимальная мантисса
0xFFFFFFFFFFFFF
что составляет 52 бита все 1.
В двоичном виде значение представляет собой неявную 1, за которой следуют еще 52 единицы из мантиссы, затем 971 ноль (1023 - 52 = 971) от показателя степени.
Точное десятичное значение:
179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368
Это примерно 1,8 х 10308.
Википедия говорит об этом в том же контексте со ссылкой на IEEE 754:
В типичной компьютерной системе двоичное число с плавающей запятой с двойной точностью (64-разрядное) имеет коэффициент 53 бита (один из которых подразумевается), показатель степени 11 бит и один знаковый бит.
2 ^ 53 составляет чуть более 9 * 10^15.
Вам нужно посмотреть на размер мантиссы. 64-разрядное число IEEE 754 с плавающей запятой (которое имеет 52 бита плюс 1 подразумевается) может точно представлять целые числа с абсолютным значением, меньшим или равным 2^53.
Это правда, что для 64-битного IEEE754 double все целые числа до 9007199254740992 == 2^53 могут быть точно представлены.
Однако стоит также отметить, что все представимые числа за пределами 4503599627370496 == 2^ 52 являются целыми числами. За пределами 2 ^ 52 становится бессмысленным проверять, являются ли они целыми числами, потому что все они неявно округляются до ближайшего представимого значения.
В диапазоне от 2 ^51 до 2 ^ 52 единственными нецелыми значениями являются средние точки, оканчивающиеся на ".5", что означает, что любой целочисленный тест после вычисления должен дать как минимум 50% ложных ответов.
Ниже 2 ^51 у нас также есть «0,25» и «.75», поэтому сравнение числа с его округленным эквивалентом, чтобы определить, может ли оно быть целым или нет, начинает иметь некоторый смысл.
TL; DR: если вы хотите проверить, может ли вычисленный результат быть целым числом, избегайте чисел больше 2251799813685248 == 2 ^51
1.7976931348623157 × 10 ^ 308
http://en.wikipedia.org/wiki/Double_precision_floating-point_format
DECIMAL_DIG
от <float.h>
должен дать хотя бы разумное приближение к этому. Так как это имеет дело с десятичными цифрами, и оно действительно хранится в двоичном формате, вы, вероятно, можете хранить что-то немного большее, не теряя точности, но сколько именно трудно сказать. Я полагаю, вы должны быть в состоянии понять это из FLT_RADIX
а также DBL_MANT_DIG
, но я не уверен, что полностью доверю результату.
Двойники, «простое» объяснение
Наибольшее «двойное» число (число двойной точности с плавающей запятой) обычно представляет собой 64-битное или 8-байтовое число, выражаемое как:
1.79E308
or
1.79 x 10 (to the power of) 308
Как вы можете догадаться, 10 в степени 308 — это ГИГАНТСКОЕ ЧИСЛО, например 17000000000000000000000000000000000000000000000 и даже больше!
На другом конце шкалы 64-битные числа с плавающей запятой двойной точности поддерживают крошечные крошечные десятичные числа дробей с использованием «точечной» нотации, наименьшее из которых:
4.94E-324
or
4.94 x 10 (to the power of) -324
Все, что умножается на 10 в отрицательной степени, представляет собой крохотное десятичное число, например 0,00000000000000000000000000000000000494 и даже меньше.
Но что смущает людей, так это то, что они слышат, как компьютерщики и математики говорят: «но это число имеет диапазон только из 15 значений чисел». Получается, что описанные выше значения — это МАКСИМАЛЬНЫЕ и МИНИМАЛЬНЫЕ значения за все время, которые компьютер может хранить и представлять из памяти. Но они теряют точность и способность создавать числа НАДОЛГО ДО того, как станут такими большими. Таким образом, большинство программистов ИЗБЕГАЮТ максимально возможного двойного числа и пытаются придерживаться известного, гораздо меньшего диапазона.
Но почему? И какое максимальное двойное число лучше всего использовать? Я не мог найти ответ, читая десятки плохих объяснений на математических сайтах в Интернете. Так что это ПРОСТОЕ объяснение может помочь вам ниже. Мне помогло!!
ДВОЙНОЕ ЧИСЛО ФАКТОВ и НЕДОСТАТКОВ
JavaScript (который также использует 64-битную систему хранения чисел с двойной точностью в компьютерах) использует числа с плавающей запятой двойной точности для хранения всех известных числовых значений. Таким образом, он использует те же МАКС. и МИН. диапазоны, что и выше. Но большинство языков используют типизированную систему счисления с диапазонами, чтобы избежать проблем с точностью. Однако системы хранения двойных и плавающих чисел, по-видимому, имеют один и тот же недостаток, заключающийся в потере числовой точности по мере того, как они становятся больше и меньше. Я объясню почему, так как это влияет на идею «максимальных» значений...
Чтобы решить эту проблему, в JavaScript есть так называемое значение Number.MAX_SAFE_INTEGER , которое равно . Это наиболее точное число, которое оно может представлять для целых чисел, но НЕ самое большое число, которое можно сохранить. Он точен, потому что гарантирует, что любое число, равное или меньшее, может быть просмотрено, вычислено, сохранено и т. д. За пределами этого диапазона есть «отсутствующие» числа. Причина в том, что числа с двойной точностью ПОСЛЕ используют дополнительное число, чтобы умножить их на все большие и большие значения, включая истинное максимальное число . Это новое число называется показателем степени.
ЗЛОЙ ВЫРАЗИТЕЛЬ
Дело в том, что это максимальное значение также является максимальным числом, которое вы можете хранить в 53 битах компьютерной памяти, используемой в 64-битной системе хранения. Это число, хранящееся в 53-битной области памяти, представляет собой максимально возможное значение, которое может быть сохранено непосредственно в мантиссе памяти типичного числа двойной точности с плавающей запятой, используемого в JavaScript.
, между прочим, находится в формате, который мы называем Base10 или десятичным числом, используемым людьми. Но оно также хранится в памяти компьютера как 53-битное, как это значение...
11111111111111111111111111111111111111111111111111111
Это максимальное количество битов, которое компьютеры могут фактически хранить целой частью чисел с двойной точностью, используя 64-битную систему памяти чисел.
Чтобы получить даже БОЛЬШОЕ максимально возможное число (), JavaScript должен использовать дополнительный трюк, называемый показателем степени , чтобы умножить его на все большие и большие значения. Итак, есть
После того, как компьютер достигает этого предела максимального целочисленного значения (около ~9 квадриллионов) и заполняет секцию мантиссы памяти 53 битами, JavaScript использует новую 11-битную область хранения для экспоненты , которая позволяет увеличивать гораздо большие целые числа (до 10 в степени 308!) и гораздо меньшие десятичные числа, чтобы получить меньше (10 в степени -324!). Таким образом, этот показатель степени позволяет создавать полный диапазон больших и малых десятичных знаков с плавающей системой счисления или десятичной точкой для перемещения вверх и вниз по числу, создавая сложные дробные или десятичные значения, которые вы ожидаете увидеть. Опять же, эта экспонента является еще одним хранилищем больших чисел в 11 битах и сама имеет максимальное значение .
Вы заметите, что это максимальное целое число, но не объясняет большее МАКСИМАЛЬНОЕ значение, возможное в хранилище, или МИНИМАЛЬНОЕ десятичное число, или даже то, как создаются и сохраняются десятичные дроби. Как это компьютерное битовое значение создает все это?
Ответ снова через экспоненту!
Оказывается, 11-битное значение экспоненты делится на положительное и отрицательное значение, так что оно может создавать большие целые числа, но также и маленькие десятичные числа.
Для этого у него есть свой положительный и отрицательный диапазон, созданный вычитанием
Однако число -+1023, хранящееся в экспоненте , не умножается на мантиссу для получения двойного числа, а используется для повышения числа.
Это сгенерированное значение затем умножается на мантиссу , чтобы получить число MAX и MIN, разрешенное для хранения в JavaScript, а также все большие и меньшие значения в пределах диапазона. Он использует «2», а не 10 для целей точности, поэтому с каждым увеличением значения экспоненты он только удваивает значение мантиссы. Это снижает потери номеров. Но этот экспоненциальный множитель также означает, что он будет терять увеличивающийся диапазон чисел в удвоениях по мере его роста, до точки, где, когда вы достигаете МАКСИМАЛЬНОГО хранимого экспоненты и возможной мантиссы, очень большие ряды чисел исчезают из окончательного вычисленного числа, и, таким образом, определенные числа теперь невозможны в математических вычислениях!
Вот почему большинство использует БЕЗОПАСНЫЕ максимальные целочисленные диапазоны (
Обратите внимание, что
ИСТИННЫЙ МАКСИМАЛЬНЫЙ МАКСИМАЛЬНЫЙ МАКСИМАЛЬНЫЙ БЕСКОНЕЧНОСТЬ
Наконец, что происходит, когда целые числа достигают МАКСИМАЛЬНОГО возможного числа или наименьшей возможной десятичной дроби?
Оказывается, числа с плавающей запятой двойной точности зарезервировали набор битовых значений для 64-битных значений экспоненты и мантиссы для хранения четырех других возможных чисел:
- +Бесконечность
- -Бесконечность
- +0
- -0
Например, +0 в двойных числах, хранящихся в 64-битной памяти, представляет собой большую строку пустых битов в памяти компьютера. Ниже показано, что происходит после того, как вы выходите за пределы наименьшего возможного десятичного числа () при использовании числа с плавающей запятой двойной точности. Это становится после того, как у него заканчивается память! Компьютер вернет , но сохранит в памяти 0 бит. Ниже приведен ПОЛНЫЙ 64-битный дизайн хранилища в битах для двойника в памяти компьютера. Первый бит управляет
0 00000000000 0000000000000000000000000000000000000000000000000000
Если двойное число достигает своего положительного максимума или минимума или отрицательного максимума или минимума, многие языки всегда будут возвращать одно из этих значений в той или иной форме. Однако некоторые возвращают NaN или переполнение, исключения и т. д. Как это обрабатывается, это отдельная тема. Но часто эти четыре значения являются вашими ИСТИННЫМИ минимальными и максимальными значениями для double. Возвращая иррациональные значения, вы, по крайней мере, имеете представление max и min в двойных числах, которые объясняют последние формы двойного типа, которые не могут быть сохранены или объяснены рационально.
КРАТКОЕ СОДЕРЖАНИЕ
Таким образом, МАКСИМАЛЬНЫЙ и МИНИМАЛЬНЫЙ диапазоны для положительных и отрицательных удвоений следующие:
MAXIMUM TO MINIMUM POSITIVE VALUE RANGE
1.79E308 to 4.94E-324 (+Infinity to +0 for out of range)
MAXIMUM TO MINIMUM NEGATIVE VALUE RANGE
-4.94E-324 to -1.79E308 (-0 to -Infinity for out of range)
But the SAFE and ACCURATE MAX and MIN range is really:
9007199254740991 (max) to -9007199254740991 (min)
Таким образом, вы можете видеть, что с добавлением +-Infinity и +-0 у двойников есть дополнительные максимальные и минимальные диапазоны, которые помогут вам, когда вы превысите максимальные и минимальные значения.
Как упоминалось выше, когда вы переходите от наибольшего положительного значения к наименьшему десятичному положительному значению или дроби, биты обнуляются, и вы получаете 0 Past.
Противоположное происходит с большими значениями... в прошлом
Обратите внимание, что МИНИМАЛЬНЫЙ БЕЗОПАСНЫЙ ДИАПАЗОН для десятичных знаков/дробей не показан выше, поскольку он зависит от точности, необходимой для дроби. Когда вы комбинируете целое число с дробной частью, точность десятичного разряда быстро снижается по мере уменьшения. Об этом в сети много дискуссий и дискуссий. Ни у кого никогда нет ответа. Список ниже может помочь. Возможно, вам придется изменить эти диапазоны, перечисленные на гораздо меньшие значения, если вы хотите гарантировать точность. Как видите, если вы хотите поддерживать точность до 9 знаков после запятой в числах с плавающей запятой, вам нужно будет ограничить МАКСИМАЛЬНЫЕ значения в мантиссе этими значениями. Точность означает, сколько знаков после запятой вам нужно с точностью. Небезопасно означает, что после этих значений число потеряет точность и будет иметь пропущенные числа:
Precision Unsafe
1 5,629,499,534,21,312
2 703,687,441,770,664
3 87,960,930,220,208
4 5,497,558,130,888
5 68,719,476,736
6 8,589,934,592
7 536,870,912
8 67,108,864
9 8,388,608
Мне потребовалось некоторое время, чтобы понять ИСТИННЫЕ пределы чисел с плавающей запятой двойной точности и компьютеров. Я создал это простое объяснение, приведенное выше, после того, как прочитал в Интернете так много МАССОВОЙ ЗАБЛУЖДЕННОСТИ от математических экспертов, которые отлично умеют вычислять числа, но ужасно умеют что-либо объяснять! Надеюсь, я помог вам в вашем путешествии по программированию - Мир :)
ОБНОВЛЕНИЕ 1 :
только что понял5 ^ 1074
НЕ является истинным верхним пределом того, что вы можете получить бесплатно из IEEE 754 с плавающей запятой двойной точности, потому что я считал только денормализованные показатели степени и забыл тот факт, что сама мантисса может соответствовать еще 22 степеням 5, так что в меру своих возможностей Понимая, что наибольшая степень числа 5, которую можно получить бесплатно из формата двойной точности, равна ::
наибольшая степень числа 5:
- 5 ^ 1096
наибольшее нечетное число:
5 ^ 1074 х 9007199254740991
5 ^ 1074 х ( 2 ^ 53 - 1 )
mawk 'BEGIN { OFS = "\f\r\t"; CONVFMT = "IEEE754 :: 4-byte word :: %.16lX"; print "", sprintf("%.*g", __=(_+=_+=_^=_<_)^++_+_*(_+_), ___=_=((_+_)/_)^-__), (_ ""), \ sprintf("%.*g",__,_=_*((_+=(_^=!_)+(_+=_))*_\ )^(_+=_++)), (_ ""), \ sprintf("%.*g",__,_=___*= \ (_+=_+=_^=_<_)^--_^_/--_-+--_), (_ "") }'
4.940656458412465441765687928682213723650598026143247644255856825006755072702087518652998363616359923797965646954457177309266567103559397963987747960107818781263007131903114045278458171678489821036887186360569987307230500063874091535649843873124733972731696151400317153853980741262385655911710266585566867681870395603106249319452715914924553293054565444011274801297099995419319894090804165633245247571478690147267801593552386115501348035264934720193790268107107491703332226844753335720832431936092382893458368060106011506169809753078342277318329247904982524730776375927247874656084778203734469699533647017972677717585125660551199131504891101451037862738167250955837389733598993664809941164205702637090279242767544565229087538682506419718265533447265625e-324
— IEEE754 :: 4-byte word :: 0000000000000001 494065645841246544176568792......682506419718265533447265625 } 751 dgts : 5^1,074
1.1779442926436580280698985883431944188238616052015418158187524855152976686244219586021896275559329804892458073984282439492384355315111632261247033977765604928166883306272301781841416768261169960586755720044541328685833215865788678015827760393916926318959465387821953663477851727634395732669139543975751084522891987808004020022041120326339133484493650064495265010111570347355174765803347028811562651566216206901711944564705815590623254860079132843479610128658074120767908637153514231969910697784644086106916351461663273587631725676246505444808791274797874748064938487833137213363849587926231550453981511635715193075144590522172925785791614297511667878003519179715722536405560955202126362715257889359212587458533154881546706053453699158950485070818103849887847900390625e-308
— IEEE754 :: 4-byte word :: 000878678326EAC9 117794429264365802806989858......070818103849887847900390625 } 767 dgts : 5^1,096
4.4501477170144022721148195934182639518696390927032912960468522194496444440421538910330590478162701758282983178260792422137401728773891892910553144148156412434867599762821265346585071045737627442980259622449029037796981144446145705102663115100318287949527959668236039986479250965780342141637013812613333119898765515451440315261253813266652951306000184917766328660755595837392240989947807556594098101021612198814605258742579179000071675999344145086087205681577915435923018910334964869420614052182892431445797605163650903606514140377217442262561590244668525767372446430075513332450079650686719491377688478005309963967709758965844137894433796621993967316936280457084866613206797017728916080020698679408551343728867675409720757232455434770912461317493580281734466552734375e-308
— IEEE754 :: 4-byte word :: 001FFFFFFFFFFFFF 445014771701440227211481959......317493580281734466552734375 } 767 dgts : 5^1,074 6361 69431 20394401
и вот быстроawk
фрагмент кода, чтобы распечатать каждую положительную степень от 2 до 1023 , каждую положительную степень от 5 до 1096 и их общую степень нуля, оптимизированную как для с, так и безbigint
библиотека:
{m,g,n}awk' BEGIN {
CONVFMT = "%." ((_+=_+=_^=_<_)*_+--_*_++)(!++_) "g"
OFMT = "%." (_*_) "g"
if (((_+=_+_)^_%(_+_))==(_)) {
print __=_=\
int((___=_+=_+=_*=++_)^!_)
OFS = ORS
while (--___) {
print int(__+=__), int(_+=_+(_+=_))
}
__=((_+=_+=_^=!(__=_))^--_+_*_) substr("",_=__)
do {
print _+=_+(_+=_) } while (--__)
exit
} else { _=_<_ }
__=((___=_+=_+=++_)^++_+_*(_+_--))
_=_^(-(_^_--))*--_^(_++^_^--_-__)
_____=-log(_<_)
__^=_<_
___=-___+--___^___
while (--___) {
print ____(_*(__+=__+(__+=__))) }
do {
print ____(_) } while ((_+=_)<_____)
}
function ____(__,_) {
return (_^=_<_)<=+__ \
? sprintf( "%.f", __) \
: substr("", _=sprintf("%.*g", (_+=++_)^_*(_+_),__),
gsub("^[+-]*[0][.][0]*|[.]|[Ee][+-]?[[:digit:]]+$","",_))_
}'
==============================
зависит от того, насколько вы гибки с определением "представленный" и "представимый" -
Несмотря на то, что говорится в типичной литературе, целое число, которое на самом деле является «самым большим» вIEEE 754 double precision
, без какой-либо библиотеки bigint или внешнего вызова функции, с полностью полной мантиссой , которая вычисляется, сохраняется и печатается, на самом деле:
9,007,199,254,740,991 * 5 ^ 1074
(~2546.750773909... bits)
4450147717014402272114819593418263951869639092703291
2960468522194496444440421538910330590478162701758282
9831782607924221374017287738918929105531441481564124
3486759976282126534658507104573762744298025962244902
9037796981144446145705102663115100318287949527959668
2360399864792509657803421416370138126133331198987655
1545144031526125381326665295130600018491776632866075
5595837392240989947807556594098101021612198814605258
7425791790000716759993441450860872056815779154359230
1891033496486942061405218289243144579760516365090360
6514140377217442262561590244668525767372446430075513
3324500796506867194913776884780053099639677097589658
4413789443379662199396731693628045708486661320679701
7728916080020698679408551343728867675409720757232455
434770912461317493580281734466552734375
я использовалxxhash
сравнить это сgnu-bc
и подтвердил, что он действительно идентичен и точность не потеряна. В этом числе вообще нет ничего «денормализованного», несмотря на то, что диапазон показателей помечен как таковой.
Попробуйте на своей системе, если не верите мне. (Я получил эту распечатку через готовуюmawk
) - и вы также можете легко добраться до него:
- один(1) возведение в степень/мощность (
^
он же**
) оп, - одно(1) умножение (
*
) оп, - один (1)
sprintf()
звонок, и - либо один (1) из -
substr()
или регулярное выражение-gsub()
произвести необходимую очистку
Как и часто упоминаемый номер 1.79…E309,
- оба имеют ограничение по мантиссе
- оба имеют экспоненциальное ограничение
- у обоих смехотворно большие
ULPs (unit in last place)
- и оба находятся ровно в 1 шаге от «переполнения» блока с плавающей запятой либо переполнением, либо недостаточным переполнением, чтобы дать вам полезный ответ
Отмените двоичные показатели рабочего процесса, и вы можете полностью выполнять операции в этом пространстве, а затем просто инвертировать его еще раз в конце рабочего процесса, чтобы вернуться к той стороне, которую мы обычно считаем «большей».
but keep in mind that in the inverted exponent realm, there's no "gradual overflow"
— Кассир 4Chan
Как отмечали другие, я предполагаю, что OP запросил наибольшее значение с плавающей запятой, чтобы все целые числа, меньшие, чем он сам, были точно представлены.
Ты можешь использовать
FLT_MANT_DIG
а также
DBL_MANT_DIG
определено в
float.h
не полагаться на явные значения (например, 53):
#include <stdio.h>
#include <float.h>
int main(void)
{
printf("%d, %.1f\n", FLT_MANT_DIG, (float)(1L << FLT_MANT_DIG));
printf("%d, %.1lf\n", DBL_MANT_DIG, (double)(1L << DBL_MANT_DIG));
}
выходы:
24, 16777216.0
53, 9007199254740992.0
Рассмотрим ваш компилятор, который может не соответствовать текущей спецификации IEEE 754 Double Type. Вот исправленный фрагмент, который можно попробовать в VB6 или Excel VBA. Он выходит из цикла по адресу 999 999 999 999 999, что составляет всего 1/9 ожидаемого значения. При этом не проверяются все числа, поэтому может быть меньшее число, приращение которого на 1 не увеличивает сумму. Вы также можете попробовать следующую строку в окне отладки: Print Format(1E15# + 1#,"#,###")
Microsoft VB6, Microsoft Excel 2013 VBA (Both obsolete)
Sub TestDbl()
Dim dSum As Double 'Double Precision Sum
Dim vSum As Variant 'Decimal Precision Sum
Dim vSumL As Variant 'Last valid comparison
Dim dStep As Double
Dim vStep As Variant
dStep = 2# ^ 49# 'Starting step
vStep = CDec(dStep)
dSum = dStep 'Starting Sums
vSum = vStep
vSumL = vSum
Debug.Print Format(dSum, "###,###,###,###,###,###,###"); " "; _
Format(vSum, "###,###,###,###,###,###,###"); " "; _
vStep; " "; Now()
Do
dSum = dSum + dStep 'Increment Sums
vSum = CDec(vSum + vStep)
If dSum <> vSum Then
'Print bad steps
Debug.Print Format(dSum, "###,###,###,###,###,###,###"); " "; _
Format(vSum, "###,###,###,###,###,###,###"); " "; _
vStep; " "; Now()
'Go back 2 steps
vSum = CDec(vSumL - vStep)
dSum = CDbl(vSum)
'Exit if Step is 1
If dStep < 2 Then Exit Do
'Adjust Step, if <1 make 1
vStep = CDec(Int(vStep / 4))
If vStep < 2 Then vStep = CDec(1)
dStep = CDbl(vStep)
End If 'End check for matching sums
vSumL = vSum 'Last Valid reading
DoEvents
Loop 'Take another step
'Last Valid step
Debug.Print Format(dSum, "###,###,###,###,###,###,###"); " "; _
Format(vSum, "###,###,###,###,###,###,###"); " "; _
vStep; " "; Now()
End Sub