大十进制错误

发布于 2024-12-27 04:43:22 字数 1001 浏览 4 评论 0原文

在 Java 中,我将 k 定义为 double k=0.0;

我正在从数据库中获取数据并使用 while 循环添加相同的数据,

while(rst.next()) {
k = k + Double.parseDouble(rst.getString(5));
}

注意:在数据库中,我的值为 125.23、458.45、665.99 (全部两位小数)

当我显示 k 时,我得到的值为

k = 6034.299999999992

因此我介绍BigDecimal 并将代码更改为下面的代码

      BigDecimal bd = new BigDecimal(k);
      bd = bd.setScale(2,BigDecimal.ROUND_UP);

现在我得到的新总计为 bd=6034.30 这是正确的。

问题 1

那么问题是当我在其他地方使用相同的内容时,下面是我得到的内容

 k  = 157.3
 bd = 157.31

它应该显示 bd=157.30 因为手动添加后我得到 157.30

显示为 157.31 的任何原因。

问题 2

另外,k 显示这么多小数值的原因是什么? 下面是我得到的双变量 k 的不同值,

157.3
67.09
1014.6000000000003
229.06999999999996

我不明白有时它显示一位小数,有时它显示 2 位小数,大多数时候它显示 14 位小数。

任何建议将不胜感激。

In Java, I have defined k as
double k=0.0;

I am taking data from database and adding the same using while loop,

while(rst.next()) {
k = k + Double.parseDouble(rst.getString(5));
}

NOTE: In database, I have values as 125.23, 458.45, 665.99 (all two decimals)

When I display k, I get value as

k = 6034.299999999992

Hence I introduced BigDecimal and changed code to below

      BigDecimal bd = new BigDecimal(k);
      bd = bd.setScale(2,BigDecimal.ROUND_UP);

Now I get new total as bd=6034.30 which is correct.

Problem 1

Well the problem is when I am using same at other place, below is what I am getting

 k  = 157.3
 bd = 157.31

It should have shown bd=157.30 as after adding manually I get 157.30.

Any reason why it is showing as 157.31.

Problem 2

Also any reason why k is showing so many decimal values?
Below are different values I am getting for double variable k

157.3
67.09
1014.6000000000003
229.06999999999996

I don't understand sometime it displays one decimal, sometime it display 2 decimal and most of the time it show 14 decimal value.

Any suggestion would be appreciated.

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

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

发布评论

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

评论(5

半枫 2025-01-03 04:43:22

您仍然要通过double。坚持BigDecimal 任何地方

BigDecimal k = BigDecimal.ZERO;
while (rst.next()) {
    k = k.add(new BigDecimal(rst.getString(5));
}

或者 - 并且最好是,如果数据库中的字段实际上是十进制值:

BigDecimal k = BigDecimal.ZERO;
while (rst.next()) {
    k = k.add(rst.getBigDecimal(5));
}

You're still going via double. Stick to BigDecimal everywhere:

BigDecimal k = BigDecimal.ZERO;
while (rst.next()) {
    k = k.add(new BigDecimal(rst.getString(5));
}

Alternatively - and preferrably, if the field in the database is actually a decimal value:

BigDecimal k = BigDecimal.ZERO;
while (rst.next()) {
    k = k.add(rst.getBigDecimal(5));
}
孤独患者 2025-01-03 04:43:22

至于你的第二个问题,double是一个二进制浮点数。这意味着它被表示为二的幂之和。 永远不要使用它们来计算货币价值。(如果这就是您总结的内容)。 BigDecimal 使用十进制算术,因此这更符合我们的使用。

0.1 之类的数字是二进制的无限分数,在本例中:0.000110011... 因此,您无法通过使用 double 获得可靠且准确的结果>。

As to your second question, double is a binary floating point number. This means that it is expressed as a sum of powers of two. Don't ever use those for calculating monetary values. (if that's what you're summing up there). BigDecimal uses decimal arithmetic, so this is more in line to what we use.

Numbers such as 0.1 are infinite fractions in binary, in this case: 0.000110011... thus you cannot get a reliable and exact result from using double.

不必你懂 2025-01-03 04:43:22

我假设 rst 是 <代码>结果集。确保您使用的是 getBigDecimal 而不是 Double.parseDouble(rst.getString(5))

BigDecimal k = BigDecimal.ZERO;
while(rst.next()) {
  k = k.add(rst.getBigDecimal(5));
}

首先:为什么你不将这些数字添加到直接使用适当的 SQL SUM 查询数据库?

I assume rst is a ResultSet. Make sure you are using getBigDecimal rather than Double.parseDouble(rst.getString(5)):

BigDecimal k = BigDecimal.ZERO;
while(rst.next()) {
  k = k.add(rst.getBigDecimal(5));
}

And first of all: why aren't you adding these numbers in the database directly using appropriate SQL SUM query?

乖乖 2025-01-03 04:43:22

使用 BigDecimal.ROUND_HALF_UP(或 .._DOWN 或 .._EVEN)。

浮点计算本质上是不准确的,并且小错误会累积。这就是为什么你的最终结果略有偏差。如果总是向上舍入,像 1.0000000001 这样的小正误差就会变成 1.01。

或者,您也可以使用 BigDecimal 进行计算。这样一来,最终结果就不会有错误。只需记住使用 BigDecimal(String) 构造函数,或直接从结果集中获取 BigDecimal。

Use BigDecimal.ROUND_HALF_UP (or .._DOWN or .._EVEN).

Floating point calculations are inherently inaccurate and the small errors accumulate. That's why your end result is off by a small amount. If you always round up, a small positive error like 1.0000000001 becomes 1.01.

Alternatively you can use BigDecimal also for the calculations. That way you won't have an error in the end result in the first place. Just remember to use the BigDecimal(String) constructor, or obtain the BigDecimal directly from the result set.

蛮可爱 2025-01-03 04:43:22

您还需要将 k 设置为 BigDecimal,而不是 double

You need to have k as BigDecimal too, instead of double.

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