我知道无论OS,编程语言如何,都存在浮点不准确性。但是,我发现这个例子没有不准确之处。怎么可能这样呢?我认为计算需要将stirng转换为double,因此应该存在浮点不准确!
import java.math.*;
class NoErrorBigDecimal {
public static void main(String[] args)
{
BigDecimal e1=new BigDecimal("1.6");
BigDecimal e2=new BigDecimal("0.1");
System.out.println("result of add : "+e1.add(e2));
System.out.println("result of multiplication : "+e1.multiply(e2));
}
}
答案 0 :(得分:3)
BigDecimal如何不会出现浮点不准确?
答案是它不能。
浮点不准确(正如您所说)是计算机中使用的实际数字表示的基础。
BigDecimal
命题的反例是,使用单个BigDecimal
(或float
或double
无法精确表示1/3的值那件事)。
使用base-3浮点表示法可以表示,但这是不切实际的。
它可以通过(假设的)任意精度有理数表示来表示,但是没有标准的Java SE类可以实现它。
另一个反例是Pi(3.14159 ......)。由于它是不合理的,它没有有限的数字表示(除了涉及循环逻辑的不切实际的意义......)
另一方面,如果您将自己局限于可以精确表示为有限十进制浮点字符串(例如"1.6"
和"0.1"
)的数字,那么BigDecimal
可以代表所有这些数字......确切地说。
我认为计算需要将stirng转换为double,因此应该存在浮点不准确!
实际上,并不是说不准确。它取决于具体的计算,具体的表示,以及(通常)实际值。例如:
我可以(平凡地)实施计算1 / 2
并且(如果硬件有效)保证结果将准确地表示为float
或double
。
将String
形式的十进制数转换为BigDecimal
不会涉及任何可能导致准确性降低的计算。 (由标准库实现,并假设有O(N)
个可用内存...其中N
是输入字符串长度。)
答案 1 :(得分:-2)
好的,所以这里的推论是Double提供比BigDecimal更高的精度,或者提供"没有浮点不准确。"你说每个编程语言都必须为舍入做出让步是正确的。 Java也不例外。
相对于其他数字类型,BigDecimal为程序员提供了更大程度的控制,并通过诸如“BigDecimal(long val,MathContext mc)”之类的众多构造函数进行舍入。和舍入模式(例如,' ROUND_UP')[参见Java 7 API- http://docs.oracle.com/javase/7/docs/api/java/math/BigDecimal.html]。这就是BigDecimal在处理货币时首选的类型。