Java BigDecimal 区别

发布于 2024-11-07 10:06:58 字数 1081 浏览 0 评论 0原文

我想看看是否有人可以解释为什么以下代码适用于 valueOf 而不适用于其他代码。

import java.math.BigDecimal; 
public class Change {
   public static void main(String args[]) {
     double a = 4.00d;
     double b = 3.10d;
     BigDecimal a1 = new BigDecimal(a);
     BigDecimal b1 = new BigDecimal(b);
     BigDecimal diff = a1.subtract(b1);
     System.out.println("Double difference");
     System.out.println(diff);

     float c = 4.00f;
     float d = 3.10f;
     BigDecimal a2 = new BigDecimal(c);
     BigDecimal b2 = new BigDecimal(d);
     BigDecimal diff2 = a2.subtract(b2);
     System.out.println("Float difference");
     System.out.println(diff2);

     System.out.println("Valueof Difference");
     System.out.println(BigDecimal.valueOf(4.00).subtract(BigDecimal.valueOf(3.10)));

   }
 }

输出如下:

>java Change
 Double difference
  0.899999999999999911182158029987476766109466552734375
 Float difference
  0.900000095367431640625
 Valueof Difference
 0.9

我的问题是: valueOf() 做什么来获得精度? 有没有其他方法可以获得正确的结果,而无需手动四舍五入到 2 位数字?

谢谢,

I wanted to see if anyone can explain why the following code works with valueOf but not others.

import java.math.BigDecimal; 
public class Change {
   public static void main(String args[]) {
     double a = 4.00d;
     double b = 3.10d;
     BigDecimal a1 = new BigDecimal(a);
     BigDecimal b1 = new BigDecimal(b);
     BigDecimal diff = a1.subtract(b1);
     System.out.println("Double difference");
     System.out.println(diff);

     float c = 4.00f;
     float d = 3.10f;
     BigDecimal a2 = new BigDecimal(c);
     BigDecimal b2 = new BigDecimal(d);
     BigDecimal diff2 = a2.subtract(b2);
     System.out.println("Float difference");
     System.out.println(diff2);

     System.out.println("Valueof Difference");
     System.out.println(BigDecimal.valueOf(4.00).subtract(BigDecimal.valueOf(3.10)));

   }
 }

The output looks like:

>java Change
 Double difference
  0.899999999999999911182158029987476766109466552734375
 Float difference
  0.900000095367431640625
 Valueof Difference
 0.9

My question is: What does valueOf() do to get the precision?
Is there any other way of getting the correct result without rounding off to the 2 digits manually?

thanks,

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

夜声 2024-11-14 10:06:58

查看 BigDecimal 的源代码,它确实如此:

public static BigDecimal valueOf(double val) {
    // Reminder: a zero double returns '0.0', so we cannot fastpath
    // to use the constant ZERO.  This might be important enough to
    // justify a factory approach, a cache, or a few private
    // constants, later.
    return new BigDecimal(Double.toString(val));
}

从其 JavaDoc 来看:

将双精度数转换为 BigDecimal,
使用 double 的规范字符串
提供的代表
Double.toString(double) 方法。

注意:这通常是首选方式
将双精度型(或浮点型)转换为
BigDecimal,因为返回的值为
等于结果
从构造一个 BigDecimal
使用结果
Double.toString(double)。

由于浮点表示形式,双精度值并不完全是您设置的值。但是,在字符串表示期间,它会四舍五入显示的内容。 (所有规则都在其上 JavaDoc)。

此外,由于这种舍入,如果您执行以下操作:

BigDecimal d = BigDecimal.valueOf(4.00000000000000000000000000000000001));

您将得到错误的值。 (d == 4.0)

因此,用字符串初始化它们总是更好。

Looking at the source code for BigDecimal, it does:

public static BigDecimal valueOf(double val) {
    // Reminder: a zero double returns '0.0', so we cannot fastpath
    // to use the constant ZERO.  This might be important enough to
    // justify a factory approach, a cache, or a few private
    // constants, later.
    return new BigDecimal(Double.toString(val));
}

From its JavaDoc:

Translates a double into a BigDecimal,
using the double's canonical string
representation provided by the
Double.toString(double) method.

Note: This is generally the preferred way to
convert a double (or float) into a
BigDecimal, as the value returned is
equal to that resulting from
constructing a BigDecimal from the
result of using
Double.toString(double).

Because of floating-point representation, a double value is not exactly what you set it as. However, during String representation, it rounds off what it displays. (All of the rules are on it's JavaDoc).

Furthermore, because of this rounding, if you did:

BigDecimal d = BigDecimal.valueOf(4.00000000000000000000000000000000001));

you would get the wrong value. (d == 4.0)

So, it's pretty much always better to initialize these with strings.

叫嚣ゝ 2024-11-14 10:06:58

BigDecimal.valueOf(double) 首先执行从 double 到 String 的转换,然后从 String 到 BigDecimal。

在第一种情况下,您从 double 或 float 开始,转换为 BigDecimal,计算差异。在第二种情况下,您从 double 或 float 开始,转换为 String,然后转换为 BigDecimal,然后计算差异。

BigDecimal.valueOf(double) first does a conversion from double to String, then String to BigDecimal.

In the first case, you're starting with a double or float, converting to BigDecimal, calculating the difference. In the second case, you're starting with double or float, converting to a String, then converting to BigDecimal, then calculating the difference.

你好,陌生人 2024-11-14 10:06:58

来自 Javadocs

公共静态BigDecimal valueOf(double val)

将双精度数转换为 BigDecimal,
使用 double 的规范字符串
提供的代表
Double.toString(double) 方法。笔记:
这通常是首选方式
将双精度型(或浮点型)转换为
BigDecimal,因为返回的值为
等于结果
从构造一个 BigDecimal
使用结果
Double.toString(double)。

我想这回答了你的两个问题。

干杯,

From the Javadocs:

public static BigDecimal valueOf(double val)

Translates a double into a BigDecimal,
using the double's canonical string
representation provided by the
Double.toString(double) method. Note:
This is generally the preferred way to
convert a double (or float) into a
BigDecimal, as the value returned is
equal to that resulting from
constructing a BigDecimal from the
result of using
Double.toString(double).

I think this answers both of your questions.

Cheers,

不离久伴 2024-11-14 10:06:58

valueOf 起作用是因为它调用 Double.toString。来自 Javadoc:

public static BigDecimal valueOf(double val)

    使用双精度数将双精度数转换为 BigDecimal

规范的字符串表示
由提供
Double.toString(double) 方法。

当您将 double 传递到 BigDecimal 构造函数时,构造函数会获取浮点值并准确地再现它。 toString 代码查找浮点值的近似值。

如果您没有注意到,使用 System.out.println() 显示浮点数不会显示与首先将浮点数包装在 BigDecimal 中相同的结果(使用采用 double 的 BigDecimal 构造函数) )。

The valueOf works because it calls Double.toString. from the Javadoc:

public static BigDecimal valueOf(double val)

    Translates a double into a BigDecimal, using the double's

canonical string representation
provided by the
Double.toString(double) method.

When you pass a double into the BigDecimal constructor, the constructor takes the floating-point value and reproduces it exactly. The toString code finds an approximation for the floating point value.

In case you didn't notice, using System.out.println() to show a floating point number doesn't show the same results as if you wrap the floating point number in a BigDecimal first (using the BigDecimal constructor that takes a double).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文