Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Общие вопросы по .NET и C# > Потеря точности при записи числа в БД


Автор: mrHunter 21.7.2008, 18:25
Есть расчет очень сложного, циклического алгоритма. После каждой итерации данные (типа double) записываю в БД Access. Использую Visual Studio 2005 & C#. При отладке по шагам в Visual Studio числа имеют длину 20 знаков после запятой, а при записи в Access они укорачиваются до 18 знаков... В принципе такая точность мне и не нужна, я бы ограничился 15 знаками. Но нужно делать "расчет с продолжением", т.е. нужно открывать файл БД, ранее расчитанный, из него считываю 2 последние строчки и продолжаю вычисления, основываясь на этих данных... Так вот эти считанные данные (ранее сохраненные) отличаются на 2 последних знака после запятой, поэтому расчет например 100.000 без продолжения (за раз) отличается от расчета например сначала 50.000, потом еще 50.000. Сначала разница ничтожна, но потом сказывается "лавинный эффект" и при большом количестве итераций разница уже существенна...

Подскажите, пожалуйста, что мне лучше сделать? Обрезать числа после каждого вычисления? Какие еще варианты есть?

Заранее благодарен.

Автор: Idsa 21.7.2008, 18:36
mrHunter, к сведению: для вопросов по ADO.NET есть специальный раздел.

Какой тип поля используется в Access?

Добавлено через 11 минут и 27 секунд
И еще.
Вот выдержка из MSDN:
Цитата

By default, a Double value contains 15 decimal digits of precision

Так что в отладчике Вы обсчитались.

Автор: Idsa 21.7.2008, 18:52
Сейчас проверил. Отладчик показывается 17 знаков после запятой.
В MSDN и про это написано:
Цитата

By default, a Double value contains 15 decimal digits of precision, although a maximum of 17 digits is maintained internally

Автор: mrHunter 21.7.2008, 20:24
Но я точно проверял, в отладчике 20 цифр.... Это точно! В Access то все-равно числа обрезанные приходят. Тив в Accessе - двойное с плавающей точкой...

Автор: Lomir 21.7.2008, 22:43
Так ведь можно использовать строки для хранения чисел. А вопше если нужна такая большая точность и не совсем критична производителность, я тут лучше использовать длиную арифметику. Кстати есть еще такой тип как decimal (128 бит кажись), незнаю есть ли он в Access.

Автор: Idsa 22.7.2008, 05:54
Цитата(mrHunter @  22.7.2008,  00:24 Найти цитируемый пост)
Но я точно проверял, в отладчике 20 цифр

20 цифр после запятой? Не верю!
Скрины в студию.

Цитата(mrHunter @  22.7.2008,  00:24 Найти цитируемый пост)
Тив в Accessе - двойное с плавающей точкой... 

Тип double в Access соответствует типу double в .NET, и у него 15 цифр после запятой.

Автор: mrHunter 22.7.2008, 07:07
Вот скрин:

user posted image

Да реально, 20 цифр блин...

Автор: mrHunter 22.7.2008, 07:27
А в Accesse тоже 18 цифр после запятой, а никак не 15...

user posted image

Автор: Idsa 22.7.2008, 08:00
mrHunter, может, Вы все-таки используете не double, а decimal?

Автор: mrHunter 22.7.2008, 09:24
decimal никогда не использовал. Только double. Использование decimal удвоит количество занятой памяти и снизит скорость работы...

Вариант конвертации double в строку перед записью в БД -- наверное снизит скорость работы существенно... Должно же быть решение с double...

Не может быть, не может быть... Какая-то фигня...

Автор: mrHunter 22.7.2008, 12:21
Вот пример простенький, когда в отладчике можно увидеть 20 знаков после запятой:

Код

double[,] a = new double[1, 1];
double[] b = new double[1];
     
a[0, 0] = 0.05;
b[0] = 0.006;
      
a[0, 0] = a[0, 0] * b[0];

Автор: Wanderer2019 22.7.2008, 12:34
Попробуй округлять значения при помощи Math.Round. Тут можно указать количество цифр после запятой. Хотя это наверное не многим лучше работой со string.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)