繁体   English   中英

JAVA浮点运算

[英]JAVA floating point operations

我在我的应用程序中做了很多浮点运算,我知道浮点运算不是100%准确,这很好但是在打印结果时我还没有找到一种方法来正确地格式化它。

例如

0.1 + 0.1 = 0.19999999999999999999999

Math.sin(Math.PI)= 1.2246E16而不是0

和1.000000000000000001之类的东西

我正在寻找一种通用的方法来获取这些结果并获得正确的舍入值(以String形式)

所以0.1 + 0.1 = 0.19999999999999999999999 - > 0.2这个需要四舍五入

Math.sin(Math.PI)= 1.2246E16 - > 0

和1.000000000000000001 - > 1之类的东西; 而这个需要四舍五入

我还想避免在结果为1.1234567891234567或1.33333333333333的情况下丢失数据,在这些情况下结果应该保持不变。

使用例如System.out.printf("%.6f", myFloat)

如果要避免使用格式化,可以在打印之前将结果舍入为固定精度,并使用Java将执行少量舍入以隐藏表示错误的事实。

例如到小数点后6位

public static double round6(double d) {
    return Math.round(d * 1e6) / 1e6;
}

round()1e6的结果可以准确表示。 另外“ IEEE 754需要正确的舍入:也就是说,舍入结果就好像使用无限精确的算术来计算值然后舍入”剩下的唯一错误是表示错误,因为它取最近的可表示值。 Java的toString()假设当你有一个具有最近可表示的较小十进制值的double时,就是你想要看到的。

例如,0.1的实际值是

System.out.println(new BigDecimal(0.1));

版画

0.1000000000000000055511151231257827021181583404541015625

但是当Double.toString()传递给这个值时,它确定0.1将被转换为这个double,所以这就是它应该显示的内容。

BTW在Java 6中,存在一个不使用最小位数的错误。

for (int i = 1; i <= 9; i++)
    System.out.print(i / 1000.0 + " ");

在Java 6打印

0.0010 0.0020 0.0030 0.0040 0.0050 0.0060 0.0070 0.0080 0.0090

并在Java 7打印

0.001 0.002 0.003 0.004 0.005 0.006 0.007 0.008 0.009

如果性能不是很关键,我经常使用printf,如果是,我使用自定义例程将double写入直接ByteBuffer到固定精度(有效地舍入它)这样会更快,因为它不会创建任何对象。

我还想避免在结果为1.1234567891234567或1.33333333333333的情况下丢失数据,在这些情况下结果应该保持不变。

在这种情况下,在您需要显示结果之前,请不要对结果进行舍入。

如果要避免丢失小数,请使用BigDecimal而不是float。 更慢但更准确。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM