Как округлить значения валюты в Java? - PullRequest
9 голосов
/ 07 февраля 2009

Хорошо, вот моя проблема. В основном у меня есть эта проблема.

У меня есть номер как .53999999. Как округлить его до 54 без использования математических функций?

Я предполагаю, что мне нужно умножить на 100, чтобы масштабировать, а затем разделить? Что-то в этом роде?


Проблема в деньгах. скажем, у меня есть 50,5399999 долларов. Я знаю, как получить 50 долларов, но у меня нет, как получить центы. Я могу получить часть .539999, но я не знаю, как получить ее до 54 центов.

Ответы [ 10 ]

20 голосов
/ 07 февраля 2009

Я бы использовал что-то вроде:

BigDecimal result = new BigDecimal("50.5399999").setScale(2, BigDecimal.ROUND_HALF_UP);

Есть замечательная статья под названием Создание центов с BigDecimal на JavaWorld , на которую стоит взглянуть.

15 голосов
/ 07 февраля 2009

Вы должны использовать десятичный или валютный тип для представления денег, а не с плавающей запятой.

7 голосов
/ 07 февраля 2009

Математика с деньгами сложнее, чем думает большинство инженеров (более обобщенно)

Если вы делаете расчеты в валюте, я думаю, вы можете углубиться в проблемы, которые кажутся простыми на первый взгляд, но на самом деле довольно сложными. Например, методы округления, которые являются результатом решений бизнес-логики, которые часто повторяются, могут существенно повлиять на итоги вычислений.

Если это домашнее задание, показ учителю, что вы продумали реальную проблему, а не просто слили кучу кода, который «работает», - несомненно, будет более впечатляющим.

Кстати, я изначально собирался предложить посмотреть на реализацию математических методов Java в исходном коде, поэтому я взглянул. Я заметил, что Java использует нативные методы для своих методов округления - как и положено.

Однако взгляд на BigDecimal показывает, что для округления в Java доступен исходный код Java. Поэтому вместо того, чтобы просто дать вам код для домашней работы, я предлагаю вам взглянуть на закрытый метод BigDecimal doRound (MathContext mc) в исходном коде Java.

7 голосов
/ 07 февраля 2009

Если 50,54 нельзя представить с двойной точностью, то округление не поможет.

Если вы пытаетесь конвертировать 50,53999999 в целое число долларов и целое число центов , выполните следующие действия:

double d = 50.539999; // or however many 9's, it doesn't matter
int dollars = (int)d;
double frac = d - dollars;
int cents = (int)((frac * 100) + 0.5);

Обратите внимание, что прибавление 0,5 на последнем шаге означает округление до ближайшего целого числа центов. Если вы всегда хотите округлить до , измените это значение на 0,9999999 вместо 0,5.

6 голосов
/ 07 февраля 2009

Почему бы вам не использовать математические функции?

static long round(double a) 

- Возвращает ближайший к аргументу аргумент.

http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Math.html

Чтобы представить деньги, я бы взял следующий совет вместо того, чтобы заново изобретать колесо:

http://www.javapractices.com/topic/TopicAction.do?Id=13

3 голосов
/ 20 февраля 2009

Попробуйте сохранить вашу валюту в виде количества центов (вы можете абстрагироваться от количества единиц базовой валюты) с длинной.

Редактировать: так как это домашняя работа, вы не можете контролировать типы. Считайте, что это урок для будущих проектов

long money = 5054;

long cents = money % 100;
long dollars = money / 100; // this works due to integer/long truncation

System.out.printf("$%d.%02.d", dollars, cents);
1 голос
/ 07 февраля 2009

Вам нужно сделать число .535 и сравнить его с вашим исходным числом, чтобы увидеть, округлите ли вы вверх или вниз. Вот как вы получаете .535 от .53999999 (должно работать для любого числа):

num = .53999999;
int_num = (int)(num * 100); // cast to integer, however you do it in Java
compare_num = (int_num + 0.5) / 100;

compare_num будет 0,535 в этом случае. Если num больше или равно compare_num, округлите до int_num + 1. В противном случае просто округлите до int_num.

0 голосов
/ 07 февраля 2009

Я предлагаю вам использовать long для округления двойного значения. Для небольших чисел это не имеет значения, но может иметь значение.

double d = 50.539999;
long cents = (long)(d * 100 + 0.5);
double rounded = cents/100;
0 голосов
/ 07 февраля 2009

Кажется, что у Шона это есть, за исключением того, что если вы хотите навязать правильные правила, вы можете добавить выражение if, например:

double value = .539999;
int result = (int) (value*100);
if(((value*100)%result)>.5)
    result++;
0 голосов
/ 07 февраля 2009

Что именно вы пытаетесь сделать? Вы всегда пытаетесь перейти к двум цифрам? Или вы всегда пытаетесь исправить такие вещи, как 99999 в конце концов, несмотря ни на что?

Согласно комментариям, это фактически первое: округление до долларов и центов. Так что действительно round(100*a)/100 - это то, что вы хотите. (Последнее будет намного сложнее ...)

Наконец, если вы просто хотите извлечь часть центов, сработает следующее:

dollars_and_cents = round(100*a)/100
cents = (dollars_and_cents-(int)dollars_and_cents)*100

(или java просто имеет frac? В этом случае последняя строка будет просто frac(dollars_and_cents)*100.

...