|
|
|
Простой пример, а не работает.
|
|||
|---|---|---|---|
|
#18+
Добавил округление для случая с double на каждом шаге: Код: plaintext 1. 2. 3. Результат: double: Сумма: 1.1254950830000011E7 После округления: 11254950.83 BigDecimal: Сумма: 11254951.00 После округления: 11254951.00 Расхождение на 17 копеек. Вы все еще уверены, что тип double подходит для финансовых расчетов? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.10.2007, 07:58:42 |
|
||
|
Простой пример, а не работает.
|
|||
|---|---|---|---|
|
#18+
Самоловских Виталий aka Kefir Вы все еще уверены, что тип double подходит для финансовых расчетов? И вот опять... Как только я вижу попытки доказать, что double — говно, так тут же доказывальщик допускает ряд ошибок :) Я для вас подготовил занятный пример. Обратите внимание в район Step 25. Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. Там очень интересно будет: DB = 455851.1750 and round = 455851.18 d = 455851.175 and round = 455851.17 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.10.2007, 12:46:36 |
|
||
|
Простой пример, а не работает.
|
|||
|---|---|---|---|
|
#18+
Кстати, касательно скорости... Для интересно запускал в режиме -server -Xms32m -Xmx256m. Разница — 150-300 раз. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.10.2007, 12:50:34 |
|
||
|
Простой пример, а не работает.
|
|||
|---|---|---|---|
|
#18+
Как итог — если думать о том, что делаешь, не хочется (или хочется дополнительной уверенности в действиях) — лучше использовать BigDecimal. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.10.2007, 12:51:41 |
|
||
|
Простой пример, а не работает.
|
|||
|---|---|---|---|
|
#18+
Step 500 DB = 11227950.1000 and round = 11227950.10 d = 1.122795001E7 and round = 1.122795001E7 STEP1. DB sum = 11227950.10, d sum = 1.122795001E7 DB = 11254951.0000 and round = 11254951.00 d = 1.125495091E7 and round = 1.125495091E7 STEP2. DB sum = 11254951.00, d sum = 1.125495091E7 BigDecimal: Сумма: 11254951.00 После округления: 1125495 1.00 double: Сумма: 1.125495091E7 После округления: 1125495 0.91 Итоговая сумма расползлась на 9 копеек. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.10.2007, 23:43:31 |
|
||
|
Простой пример, а не работает.
|
|||
|---|---|---|---|
|
#18+
Софтверный проктологКак итог — если думать о том, что делаешь, не хочется (или хочется дополнительной уверенности в действиях) — лучше использовать BigDecimal. Я ф шоке: Код: plaintext Почему так, совершенно непонятно, т.к. 0.175 может быть представлено точно в типе double. Надо будет покопаться в исходниках. Может еще от версии JRE зависит... Исправил round: Код: plaintext 1. 2. 3. 4. 5. 6. Действительно все сошлось. Вот только такой вариант double приемлем ТОЛЬКО когда точно знаешь, что точность выше 4 знаков после запятой понадобиться не может. Общий случай, я, честно говоря, написать затрудняюсь. Такой вариант: Код: plaintext 1. 2. 3. Дал: double: Сумма: 1.1254950960000008E7 После округления: 11254950.96 BigDecimal: Сумма: 11254951.00 После округления: 11254951.00 Расхождение в 4 копейки. РЕЗЮМЕ: Чем трахаться с округлениями лучше я буду пользовать BigDecimal. Пусть синтетические тесты и работают в 150 (Vurn) - 400 (Мой) раз медленнее (единственное оправдание для использования double), эти расчеты еще ни разу не становились узким местом в системах, которые я разрабатываю. Если уж очень узкое место, можно попробовать создать собственный тип на основе long. Он должен работать значительно быстрее. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.10.2007, 06:57:57 |
|
||
|
Простой пример, а не работает.
|
|||
|---|---|---|---|
|
#18+
Вру: 0.175 не может быть представлена в виде double точно. Так что, все объяснимо. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.10.2007, 07:05:02 |
|
||
|
Простой пример, а не работает.
|
|||
|---|---|---|---|
|
#18+
А вот что я обнаружил, когда замерил время на выполнение варианта с двойным округлением при помощи BigDecimal (Единственным, который сошелся). double: Сумма: 1.1254951000000007E7 После округления: 11254951.00 Time in nanoseconds: 21724552 BigDecimal: Сумма: 11254951.00 После округления: 11254951.00 Time in nanoseconds: 2556651 Что мы имеем? В этом случае BigDecimal оказался в 8 раз эффективнее!!! Вот еще более удивительный результат. При использовании Math.round(value*100)/100 (Этот вариант дает некорректный ответ) я получил: double: Сумма: 1.1254950960000008E7 После округления: 11254950.96 Time in nanoseconds: 1301138 BigDecimal: Сумма: 11254951.00 После округления: 11254951.00 Time in nanoseconds: 2628739 Т.е. вариант с double оказался только в 2!!! раза эффективнее, чем с BigDecimal. Лично у меня сомнений не осталось. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.10.2007, 07:19:11 |
|
||
|
Простой пример, а не работает.
|
|||
|---|---|---|---|
|
#18+
Самоловских Виталий aka Kefir Я ф шоке: Код: plaintext Почему так, совершенно непонятно, т.к. 0.175 может быть представлено точно в типе double. Надо будет покопаться в исходниках. Осторожно!!! есть ещё и сташное число 0.25 - тоже компактно суммой степеней двоек не представляется. (копаться придётся в процессоре. Где твой туннельный микроскоп?) Самоловских Виталий aka KefirМожет еще от версии JRE зависит... нет. это ошибка в IEEE754 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.10.2007, 12:09:21 |
|
||
|
Простой пример, а не работает.
|
|||
|---|---|---|---|
|
#18+
Правда интересные вещи всплывают, как только начинаешь разбираться? Кстати, таки да. Если требуются точные округления в процессе вычисления — double использоваться не нужно. На одну копейку не сходится. Ну, раньше у меня таких задач никогда и не стояло, а теперь бубу знать ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.10.2007, 13:01:39 |
|
||
|
Простой пример, а не работает.
|
|||
|---|---|---|---|
|
#18+
P.S. Кстати, настоящие пацаны double'ы округляют так: Код: plaintext 1. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.10.2007, 13:03:32 |
|
||
|
Простой пример, а не работает.
|
|||
|---|---|---|---|
|
#18+
Софтверный проктологP.S. Кстати, настоящие пацаны double'ы округляют так: Код: plaintext 1. А вот с таким округлением все отработает просто идеально. Но это лишь частный случай. Код: plaintext 1. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.10.2007, 14:01:56 |
|
||
|
Простой пример, а не работает.
|
|||
|---|---|---|---|
|
#18+
Софтверный проктологP.S. Кстати, настоящие пацаны double'ы округляют так: Код: plaintext 1. Как я уже написал, дает ошибку, к тому же пример с таким способом округления работает всего в 2 раза быстрее чем пример полностью на BigDecimal. Кстати, из JDK java.lang.Math: Код: plaintext 1. 2. 3. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.10.2007, 15:29:46 |
|
||
|
Простой пример, а не работает.
|
|||
|---|---|---|---|
|
#18+
expp Самоловских Виталий aka Kefir Я ф шоке: Код: plaintext Почему так, совершенно непонятно, т.к. 0.175 может быть представлено точно в типе double. Надо будет покопаться в исходниках. Осторожно!!! есть ещё и сташное число 0.25 - тоже компактно суммой степеней двоек не представляется. (копаться придётся в процессоре. Где твой туннельный микроскоп?) Самоловских Виталий aka KefirМожет еще от версии JRE зависит... нет. это ошибка в IEEE754 В документации написано, что BigDecimal из float/double рекомендуется делать через String. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.10.2007, 08:02:38 |
|
||
|
|

start [/forum/topic.php?fid=59&msg=34876807&tid=2144297]: |
0ms |
get settings: |
21ms |
get forum list: |
31ms |
check forum access: |
8ms |
check topic access: |
8ms |
track hit: |
201ms |
get topic data: |
24ms |
get forum data: |
6ms |
get page messages: |
118ms |
get tp. blocked users: |
3ms |
| others: | 382ms |
| total: | 802ms |

| 0 / 0 |
