Есть сервер приложений, одна из функций возвращает сумму в копейках в виде целого числа (int). Однажды выяснилось, что одна копейка "потерялась", в БД одна сумма, на клиенте она пришла на копейку меньше.
Сумму в результирующем классе устанавливает такой код:
Выяснилось, что при sum = 38.87 в result.Sum получается 3886!
Интересно, что если в Visual Studio в окне QuickWatch набрать 38.87*100, получается 3886.99999999995. Причем если умножать на 10 или 1000, то все ОК, получается соответственно 388.7 и 38870.0.
Что бы это значило? Теперь перевод в копейки через округление что ли делать?!
Здравствуйте, Stone78, Вы писали:
S>Выяснилось, что при sum = 38.87 в result.Sum получается 3886!
О сколько нам открытий чудных готовит просвященья дух...
S>Что бы это значило? Теперь перевод в копейки через округление что ли делать?!
Это значит что теперь уже пора:
1. прочитать как работает float и double и хотя бы почему они называются числами с плавающей точкой.
2. хранить деньги в decimal
3. Посмотреть заодно код на наличие точного равенства с числами с плавающей точкой (типа sum == 0). Не удивлюсь если такие в коде тоже найдутся. А ты удивишься, когда увидишь, как они регулярно не срабатывают
S>Выяснилось, что при sum = 38.87 в result.Sum получается 3886! S>Интересно, что если в Visual Studio в окне QuickWatch набрать 38.87*100, получается 3886.99999999995. Причем если умножать на 10 или 1000, то все ОК, получается соответственно 388.7 и 38870.0.
S>Что бы это значило? Теперь перевод в копейки через округление что ли делать?!
В тысячный раз уже...
А что поиском воспользоваться не судьба?
RTFM!!!
Здравствуйте, Aen Sidhe, Вы писали: AS>2. Что будет, если у вас будет сумма больше 250 миллионов рублей?
Какой вопрос! Какой вопрос...
Вот лично я считаю, что если у меня будет сумма больше 250 миллионов рублей, то вопросы округления копеек будут беспокоить меня меньше всего...
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Sinclair, Вы писали:
AS>>2. Что будет, если у вас будет сумма больше 250 миллионов рублей? S>Какой вопрос! Какой вопрос... S>Вот лично я считаю, что если у меня будет сумма больше 250 миллионов рублей, то вопросы округления копеек будут беспокоить меня меньше всего...
До тех пор, пока на указанную копейку ты не ошибёшься в налоговой декларации
Help will always be given at Hogwarts to those who ask for it.
Здравствуйте, _FRED_, Вы писали: _FR>До тех пор, пока на указанную копейку ты не ошибёшься в налоговой декларации
Да ну. Ну насчитают мне пеней на эту копейку — там за десять лет и рубля не набежит.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, Aen Sidhe, Вы писали: AS>>2. Что будет, если у вас будет сумма больше 250 миллионов рублей? S>Какой вопрос! Какой вопрос... S>Вот лично я считаю, что если у меня будет сумма больше 250 миллионов рублей, то вопросы округления копеек будут беспокоить меня меньше всего...
Бюджет, у которого дебит с кредитом не сходятся, не вызывает доверия.
S>Выяснилось, что при sum = 38.87 в result.Sum получается 3886! S>Интересно, что если в Visual Studio в окне QuickWatch набрать 38.87*100, получается 3886.99999999995. Причем если умножать на 10 или 1000, то все ОК, получается соответственно 388.7 и 38870.0.
S>Что бы это значило? Теперь перевод в копейки через округление что ли делать?!
Кратко — double\float и прочие типы с плавающей точкой не предназначены для точных вычислений.
Используй, хотя бы, int.
Идея следующая
int sum = 0;//в копейках
// ...
// Здесь расчет суммы
// Все числа умножаются на 100.
// ...
result.Sum = (Int32)(sum);
Плюс посмотри тип Decimal и для чего он предназначен.
Здравствуйте, fmiracle, Вы писали:
F>1. прочитать как работает float и double и хотя бы почему они называются числами с плавающей точкой. F>2. хранить деньги в decimal
A decimal number is a floating-point value that consists of a sign, a numeric value where each digit in the value ranges from 0 to 9, and a scaling factor
Дело в том, что матисса у float и double умножается на степень двойки, а не десятки.