Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/355.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何显示BigDecimal实例化的精确值_Java - Fatal编程技术网

Java 如何显示BigDecimal实例化的精确值

Java 如何显示BigDecimal实例化的精确值,java,Java,我想检索bigDecimal的值,其精确值与这里实例化的值相同 BigDecimal balance = new BigDecimal(2300000870000000000067.7797); 我现在使用balance检索的值是23000008699999975424。 您能告诉我如何将其检索为23000000870000000000067.7797本身吗?您使用了java.math.BigDecimal.BigDecimal(double val)构造函数 从JavaDoc: java.m

我想检索bigDecimal的值,其精确值与这里实例化的值相同

BigDecimal balance = new BigDecimal(2300000870000000000067.7797);
我现在使用balance检索的值是23000008699999975424。
您能告诉我如何将其检索为23000000870000000000067.7797本身吗?

您使用了
java.math.BigDecimal.BigDecimal(double val)
构造函数

JavaDoc

java.math.BigDecimal.BigDecimal(double val)


Translates a double into a BigDecimal which is the exact decimal representation of the double's binary floating-point value. The scale of the returned BigDecimal is the smallest value such that (10scale × val) is an integer. 

Notes: 
1. The results of this constructor can be somewhat unpredictable. One might assume that writing new BigDecimal(0.1) in Java creates a BigDecimal which is exactly equal to 0.1 (an unscaled value of 1, with a scale of 1), but it is actually equal to 0.1000000000000000055511151231257827021181583404541015625. This is because 0.1 cannot be represented exactly as a double (or, for that matter, as a binary fraction of any finite length). Thus, the value that is being passed in to the constructor is not exactly equal to 0.1, appearances notwithstanding. 
2. The String constructor, on the other hand, is perfectly predictable: writing new BigDecimal("0.1") creates a BigDecimal which is exactly equal to 0.1, as one would expect. Therefore, it is generally recommended that the String constructor be used in preference to this one. 
3. When a double must be used as a source for a BigDecimal, note that this constructor provides an exact conversion; it does not give the same result as converting the double to a String using the Double.toString(double) method and then using the BigDecimal(String) constructor. To get that result, use the static valueOf(double) method. 
此处第一点表明:

此构造函数的结果可能有些不可预测。可以假设,在Java中编写新的BigDecimal(0.1)创建的BigDecimal正好等于0.1(未标度值1,标度为1),但实际上等于0.1000000000000005555115123125782702118158340454015625。这是因为0.1不能精确地表示为双精度(或者,就此而言,表示为任何有限长度的二进制分数)。因此,传递给构造函数的值并不完全等于0.1,尽管如此

第二点建议使用带字符串参数的构造函数获得精确值


这就是值差异的原因。

java文档本身建议使用
BigDecimal(Double val)

此构造函数的结果可能有些不可预测

您应该使用以下选项:

BigDecimal balance = new BigDecimal("2300000870000000000067.7797");

您正试图使用一个无法放入精度最高为15位小数的双精度中的文字数字,这可能是您首先要使用BigDecimal的原因。因此,在初始化BigDecimal之前,您的数字将转换为double中最精确的表示形式。然后,BigDecimal构造函数通过弄乱已经弄乱的double来增加错误

您必须将数字表示为字符串才能获得该精度

    double x = 2300000870000000000067.7797d;
    System.out.println("double:"+x);        
    BigDecimal balance = new BigDecimal(2300000870000000000067.7797);
    System.out.println("balance:"+balance);
    BigDecimal stringbased = new BigDecimal("2300000870000000000067.7797");
    System.out.println("stringbased:"+stringbased);
印刷品

double:2.30000087E21
balance:2300000869999999975424
stringbased:2300000870000000000067.7797

您可以尝试使用
toString()
来获得精确的值,然后如果愿意,可以将其转换为数字;尝试使用字符串而不是BigDecimal@Maxouille完全错误和误导。当你不知道主题时,给出建议有什么意义?要点是:当你不使用基于字符串的构造函数时,你无论如何都会放弃精度。正如答案和DUP问题所表明的那样:您绝对不希望使用双精度构造函数。主要效果似乎是从字面上转换为双精度,而不是BigDecimal构造函数。@JanLarsen您的意思是正确使用此构造函数的主要效果?“这似乎是”最后一句应该删除或更改为“这是”[:-)@CarlosHeuberger完成。谢谢。@Raj不,我不是指“使用此构造函数的主要效果”。我是指问题代码的主要效果。我试图在回答中解释它。