double a = 0.05;
double b = 0.006;
double c = a * b;
Останавливаю в режиме отладки и вижу, что c = 0.00030000000000000003. 20 знаков после запятой!!! Почему??? Ведь должно получиться 0.0003.... В чем дело, кто-нибудь может объяснить? Хотя для типа double в msdne четко сказано, 15 значащих цифр...
Это не благой интерес. Очень нужно, чтобы все было по нормальному...
Есть расчет очень сложного, циклического алгоритма. После каждой итерации данные (типа double) записываю в БД Access. При отладке по шагам в Visual Studio числа имеют длину 20 знаков после запятой, а при записи в Access они укорачиваются до 18 знаков... В принципе такая точность мне и не нужна, я бы ограничился 15 знаками. Но нужно делать "расчет с продолжением", т.е. нужно открывать файл БД, ранее расчитанный, из него считываю 2 последние строчки и продолжаю вычисления, основываясь на этих данных... Так вот эти считанные данные (ранее сохраненные) отличаются на 2 последних знака после запятой, поэтому расчет например 100.000 без продолжения (за раз) отличается от расчета например сначала 50.000, потом еще 50.000. Сначала разница ничтожна, но потом сказывается "лавинный эффект" и при большом количестве итераций разница уже существенна...
И это всё из-за того, что получается в примере выше такая фигня.
Из-за того, что в памяти хранится не 0.0003 а 0.00030000000000000003 постепенно накапливается ошибка...
Спасибо за ссылки. Тип decimal удвоит объем данных... А при хранении 100.000 строк в БД это ой как существенно... Компилятор Borland Builder кстати этот пример посчитал абсолютно правильно...
Re[2]: Почему 0.05 * 0.006 = 0.00030000000000000003?
Здравствуйте, GarryIV, Вы писали:
GIV>Кто виноват: Ты прогулял лекцию на которой читали о числах с плавающей запятой... GIV>Что делать: Прочитай отсюда http://www.rsdn.ru/article/alg/float.xml
и до просветления
Что Вы на человека набросились?!
Вопрос в том, почему в MSDN говорится, что у double 15 знаков после запятой, а дебаггер показывает 20. Мне тоже непонятно.
... << RSDN@Home 1.2.0 alpha 4 rev. 1096>>
Re[3]: Почему 0.05 * 0.006 = 0.00030000000000000003?
N>>Поиском можно еще много по этой теме найти.
А>Спасибо за ссылки. Тип decimal удвоит объем данных... А при хранении 100.000 строк в БД это ой как существенно... Компилятор Borland Builder кстати этот пример посчитал абсолютно правильно...
Компилятор чего? СиППбилдеровский раньше проверял (в исполняемом коде) на отличие от нуля значения 1 в вечном цикле.
Re[3]: Почему 0.05 * 0.006 = 0.00030000000000000003?
Здравствуйте, Idsa, Вы писали:
I>Вопрос в том, почему в MSDN говорится, что у double 15 знаков после запятой, а дебаггер показывает 20. Мне тоже непонятно.
Где Вы нашли "15 знаков после запятой"? Можно ссылку?
Не "15 знаков после запятой", а "15 значащих цифр". Значащих десятичных цифр
Двоичных цифр в мантиссе 53, следовательно, десятичных log10(2^53) = 15.9546, то есть 15 — точно, а 16 — как повезёт.
Но незначащих цифр может быть хоть сто, так как двоичные дроби не всегда точно представимы в десятичном виде.
Поэтому, в Debug показывают с запасом.
Re[2]: Почему 0.05 * 0.006 = 0.00030000000000000003?
А>double a = 0.05;
А>double b = 0.006;
А>double c = a * b;
А>
А>Останавливаю в режиме отладки и вижу, что c = 0.00030000000000000003.
A> Хотя для типа double в msdne четко сказано, 15 значащих цифр...
А>Что делать?
Ну если чётко сказано, что 15, то отбрасывай после 15 цифр всё. Ну или мб нужно 16ую учесть.
Homo Guglens
Re[3]: Почему 0.05 * 0.006 = 0.00030000000000000003?