更新:
这篇文章提出了一个我认为从未得到回答的额外问题——为什么使用int
,或者更好,long
或者BigDecimal
用于货币计算。这是在这里回答的:
为什么不使用 double 或 float 来表示货币(或需要任何精确计算的地方)?
因为浮点数和双精度数不能准确地表示大多数以 10 为底的实数。
即使在使用时BigDecimal
,也必须使用String
构造函数而不是构造函数float
。
综上所述,您最好的选择是:
- 将所有值转换为美分并存储为
long
(将每个美元金额乘以 100)
- 以美分进行操作
- 最后除以 100 转换回美元
这将保持所需的精度。显然,这个解决方案考虑到了美元,任何外币兑换都需要适当考虑。
long
考虑四舍五入到最接近的值,而不是强制转换:
double d = 1234.56;
long x = Math.round(d);
我真的问你为什么要从 adouble
转到 a long
,因为这会让你失去十进制值的精度。
如果你想保持一些精度(比如最多 3 位),并且你绝对只能使用 long来做到这一点,你可以将两个双精度数乘以 1,000,然后将所有后续操作缩放相同的因子,然后缩放它们全部回到最后,就像这样:
double starting = 1234.5678;
double worker = starting * 1000;
long roundedWorker = Math.round(worker);
// do other computations here...
// due to earlier scaling, adding 1000 is equivalent to adding 1 to the original
long longResult = roundedWorker + 1000;
double threeDigitPreciseResult = longResult / 1000d;
System.out.println("Adding 1 to original number as a long: " + threeDigitPreciseResult);
更新
在对问题进行了更好的解释之后,听起来您正在寻找的是DecimalFormat
. 下面是一个roundToTwoDecimals()
使用它的方法,以及一个演示它的测试用例:
import java.text.DecimalFormat;
import org.junit.Test;
public class ExampleTest {
@Test
public void test() {
double num1 = 29334.32942032432;
double num2 = 438.95940;
double result = num1 / num2;
System.out.println("Before rounding: " + result);
double rounded = roundToTwoDecimals(result);
System.out.println("After rounding: " + rounded);
}
public double roundToTwoDecimals(double d) {
DecimalFormat twoDForm = new DecimalFormat("#.##");
return Double.valueOf(twoDForm.format(d));
}
}
打印出来:
Before rounding: 66.82697629968585
After rounding: 66.83