我想将值从0.00到10.00以双倍存储。我只需要两位数的精度。如果不对双变量进行操作,我是否可以保证始终得到我存储在变量中的内容?
我查看了这个答案,并测试了以下代码:
double a = 1.2;
double b = 1.1;
System.out.println(a - b);
System.out.println(a);
System.out.println(b);第一个打印输出一个不精确的值,据我理解,解释是机器如何不精确地表示数字。但是,为什么其他两个打印输出精确的值呢?就因为我没做手术?我能假设这一切都是真的吗?
发布于 2020-05-27 16:37:02
Java的double类型使用IEEE-754 double格式。这种类型的属性是,对于指数范围内的数字,如果15或更少的十进制数字被转换为double (使用圆整到最近,领带到偶数),结果double被转换回15位十进制数字,结果等于原始数字。
对于浮点数字的默认格式,Java生成的数字刚好足以唯一区别浮点格式中的数字。
这两个属性的一个结果是,将具有15或更少有效数字的十进制数字转换为double,然后使用默认格式将其转换回十进制,将生成与原始数字相等的内容。这在某些方面可能有所不同。例如,原始数字可能具有产生的数字没有的尾随零,例如“3.00”到“3”或“123.4500”到“123.45”。
发布于 2020-05-27 13:24:00
不精确的原因是将数字表示为double ( 浮点数)。
尽管它确实对浮点值使用算术,正如我前面所说的,问题在于值的存储,尽管打印方法常常试图对我们隐藏这一点。这个答案应该包含足够的细节:https://stackoverflow.com/a/588014/1406083
如果您想要存储(并操作)小数点到两个小数点的精度,那么您不应该使用doubles (或floats)。相反,您应该使用精确的数字(例如ints或longs)。对于两个小数点,您可以只使用100 == 1.0,或者使用BigDecimal类。
发布于 2020-05-27 13:35:39
以下是打印双值内容的一些不同尝试:
import java.math.*;
public class FloatShow {
public static void main(String ... args) {
System.out.println(1.2);
System.out.println(new Double(1.2).toString());
System.out.println(new BigDecimal(1.2).toString());
}
}这个打印出来
1.2
1.2
1.1999999999999999555910790149937383830547332763671875println方法给出了一个双框,并调用了toString,类似地,double使用了toString,它为您做了一些舍入。BigDecimal使用原始值构造一个实例,并在不进行清理的情况下显示它。所以你关于精确性的假设是无效的。
浮点和固定小数是两个不同的概念。这是维基百科中浮点算法的定义。
在计算中,浮点算法(FP)使用实数的公式化表示作为近似,支持范围和精度之间的权衡。因此,浮点计算经常出现在包含非常小和非常大的实数的系统中,这些系统需要快速的处理时间。
但是固定小数(如BigDecimal)是不同的,它存储单个数字。BigDecimal的使用速度较慢,但它并没有像浮点那样进行距离精度的权衡。
浮点对于图形和工程应用是很好的,因为计算是瓶颈,输入不是完全精确的(但在已知的误差范围内),而且可以计算出速度是值得权衡的。对于许多业务应用程序来说,性能差异并不是一个问题,因为其他的东西总是瓶颈,值是确切的,准确性是不可商量的。
https://stackoverflow.com/questions/62043959
复制相似问题