在双精度数中移动小数位 [英] Moving decimal places over in a double

查看:44
本文介绍了在双精度数中移动小数位的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以我有一个双精度设置为 1234,我想移动一个小数位使其成为 12.34

So I have a double set to equal 1234, I want to move a decimal place over to make it 12.34

为此,我将 .1 乘以 1234 两次,就像这样

So to do this I multiply .1 to 1234 two times, kinda like this

double x = 1234;
for(int i=1;i<=2;i++)
{
  x = x*.1;
}
System.out.println(x);

这将打印结果,12.340000000000002"

This will print the result, "12.340000000000002"

有没有一种方法,而不是简单地将其格式化为两位小数,就能正确地存储双存储 12.34?

Is there a way, without simply formatting it to two decimal places, to have the double store 12.34 correctly?

推荐答案

如果您使用 doublefloat,您应该使用舍入或期望看到一些舍入错误.如果您不能这样做,请使用 BigDecimal.

If you use double or float, you should use rounding or expect to see some rounding errors. If you can't do this, use BigDecimal.

您遇到的问题是 0.1 不是一个精确的表示,并且通过执行两次计算,您正在加剧该错误.

The problem you have is that 0.1 is not an exact representation, and by performing the calculation twice, you are compounding that error.

但是,100 可以准确表示,因此请尝试:

However, 100 can be represented accurately, so try:

double x = 1234;
x /= 100;
System.out.println(x);

打印:

12.34

这是有效的,因为 Double.toString(d) 代表您执行了少量的舍入,但并不多.如果您想知道没有四舍五入会是什么样子:

This works because Double.toString(d) performs a small amount of rounding on your behalf, but it is not much. If you are wondering what it might look like without rounding:

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

印刷品:

0.100000000000000005551115123125782702118158340454101562
12.339999999999999857891452847979962825775146484375

简而言之,无论您是否明确这样做,四舍五入对于浮点数的合理答案都是不可避免的.

In short, rounding is unavoidable for sensible answers in floating point whether you are doing this explicitly or not.

注意:x/100x * 0.01 在四舍五入误差方面并不完全相同.这是因为第一个表达式的舍入误差取决于 x 的值,而第二个表达式中的 0.01 具有固定的舍入误差.

Note: x / 100 and x * 0.01 are not exactly the same when it comes to rounding error. This is because the round error for the first expression depends on the values of x, whereas the 0.01 in the second has a fixed round error.

for(int i=0;i<200;i++) {
    double d1 = (double) i / 100;
    double d2 = i * 0.01;
    if (d1 != d2)
        System.out.println(d1 + " != "+d2);
}

印刷品

0.35 != 0.35000000000000003
0.41 != 0.41000000000000003
0.47 != 0.47000000000000003
0.57 != 0.5700000000000001
0.69 != 0.6900000000000001
0.7 != 0.7000000000000001
0.82 != 0.8200000000000001
0.83 != 0.8300000000000001
0.94 != 0.9400000000000001
0.95 != 0.9500000000000001
1.13 != 1.1300000000000001
1.14 != 1.1400000000000001
1.15 != 1.1500000000000001
1.38 != 1.3800000000000001
1.39 != 1.3900000000000001
1.4 != 1.4000000000000001
1.63 != 1.6300000000000001
1.64 != 1.6400000000000001
1.65 != 1.6500000000000001
1.66 != 1.6600000000000001
1.88 != 1.8800000000000001
1.89 != 1.8900000000000001
1.9 != 1.9000000000000001
1.91 != 1.9100000000000001

注意:这与系统(或电源)的随机性无关.这是由于表示错误,每次都会产生相同的结果.double 的精度是有限的,并且以 2 为基数而不是以 10 为基数,所以可以用十进制精确表示的数字往往不能用基数 2 精确表示.

NOTE: This has nothing to do with randomness in your system (or your power supply). This is due to a representation error, which will produce the same outcome every time. The precision of double is limited and in base 2 rather than base 10, so numbers which can be precisely represented in decimal often cann't be precisely represented in base 2.

这篇关于在双精度数中移动小数位的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆