Ви хочете зберігати свою валюту long
і обчислювати свою валюту в double
, принаймні, як резервну копію. Ви хочете, щоб усі транзакції проходили як long
.
Причина, в якій ви хочете зберігати свою валюту, long
полягає в тому, що ви не хочете втрачати жодну валюту.
Припустимо, ви використовуєте double
, а у вас немає грошей. Хтось дає вам три димери, а потім повертає їх назад.
You: 0.1+0.1+0.1-0.1-0.1-0.1 = 2.7755575615628914E-17
Ну, це не так круто. Можливо, хтось із 10 доларів хоче віддати своє статок, спочатку давши вам три десятки, а потім давши 9,70 долара комусь іншому.
Them: 10.0-0.1-0.1-0.1-9.7 = 1.7763568394002505E-15
А потім ти повертаєш їм копійки:
Them: ...+0.1+0.1+0.1 = 0.3000000000000018
Це просто зламано.
Тепер давайте скористаємося довгим, і ми будемо відслідковувати десяті частки копійок (так 1 = 0,001 долара). Дамо кожному на планеті один мільярд, сто дванадцять мільйонів, сімдесят п’ять тисяч, сто сорок три долари:
Us: 7000000000L*1112075143000L = 1 894 569 218 048
Гм, зачекайте, ми можемо дати кожному понад мільярд доларів, а витратити лише трохи більше двох? Переповнення тут - катастрофа.
Таким чином, всякий раз , коли ви розраховуєте суму грошей для передачі, використання double
і Math.round
його отримати long
. Потім виправте залишки (додайте та віднімайте обидва рахунки), використовуючи long
.
Ваша економіка не просочиться, і вона складе до чотирильйона доларів.
Є більш складні проблеми - наприклад, що ви робите, якщо зробите двадцять платежів? * - але це повинно розпочати роботу.
* Ви обчислюєте, що таке один платіж, круглий long
; потім помножте на 20.0
і перевірте, чи знаходиться в межах; якщо так, ви помножуєте платіж 20L
на отримання суми, що віднімається з балансу. Взагалі, всі транзакції повинні оброблятися як long
, тому вам справді потрібно підсумувати всі окремі транзакції; ви можете помножити на ярлик, але вам потрібно переконатися, що ви не додаєте помилок округлення та не переповнюєте, що означає, що вам потрібно перевірити, double
перш ніж робити реальний розрахунок long
.