【问题标题】:Exception in thread "main" java.lang.ArithmeticException: Rounding necessary [closed]线程“主”java.lang.ArithmeticException 中的异常:需要舍入 [关闭]
【发布时间】:2021-01-11 14:05:46
【问题描述】:

当我尝试获取 longValueExact() 时:

BigDecimal bigDecimal = new BigDecimal(432.900).divide(new BigDecimal(1), 2, RoundingMode.FLOOR);
System.out.println(bigDecimal.longValueExact());

Exception in thread "main" java.lang.ArithmeticException: Rounding necessary
    at java.math.BigDecimal.commonNeedIncrement(BigDecimal.java:4151)
    at java.math.BigDecimal.needIncrement(BigDecimal.java:4207)
    at java.math.BigDecimal.divideAndRound(BigDecimal.java:4115)
    at java.math.BigDecimal.setScale(BigDecimal.java:2455)
    at java.math.BigDecimal.longValueExact(BigDecimal.java:3093)
    at com.tessi.bmd.specific.actil.utils.ActilUtils.main(ActilUtils.java:1281)

【问题讨论】:

  • 是的,如果值不能用long 精确表示,那就是intended and documented behaviour。不确定您的问题是什么;如果您对舍入没问题,只需使用longValue 而不是longValueExact

标签: java bigdecimal


【解决方案1】:

new BigDecimal(432.900)

这是个坏主意。 432.900 是一个双重文字,因此极不可能实际代表 432.900。您正在使用 BigDecimal,因此您大概知道最多只有 2^64 个数字可以由 double 精确表示。 432.900 不是其中之一。不要使用这个构造函数——它到处都是警告。使用new BigDecimal("432.9")

.divide(new BigDecimal(1),

好的,除以 1,什么也不做。另外,请为此使用BigDecimal.ONE

该值仍然是 432.899999999999434 之类的。

System.out.println(bigDecimal.longValueExact());

这当然行不通 - long 值只能保存整数值,而 432.9(或接近的值)则不行。

您是否认为432.900 只是一种编写432900 的方式,在. 用作千位分隔符的某些语言环境中对人类来说更具可读性?

. 是小数分隔符。 432.900 是一个双精度字面量,表示最接近数字 432 + 9/10ths 的可表示双精度数。如果这是您的意图,请删除. - 如果您想为“是”创建一些水平空间,请使用_,这在数字文字中是合法的并且没有意义。

如果这不是您的问题,并且您真的希望 432.9 精确长 - 我想,回到第一方并开始学习 java。很快(毫无疑问,在一两天内),您将了解本教程中解释原始数据类型的部分。请特别注意本节。

【讨论】:

  • @l4mpi 具体不清楚的方面(432.900 尝试使用千位分隔符,或尝试写入 432 加 9/10)非常具体。如果这是关闭问题的理由,那么关于 SO 的 100 个问题中有 99 个应该因不清楚而关闭。
  • 不,这只是您对 OP 问题的慈善解释;目前尚不清楚这是否是问题所在,或者 OP 是否不理解错误消息,或者需要阅读 java 数据类型(您在自己的答案中提到过),或者是否完全是其他问题。另外,我完全同意应该关闭关于 SO 的大多数问题。
  • 另外,我完全同意关于 SO 的大多数问题都应该关闭。 不是我所说的,而且我不认为通过评论答案来表达这种异国情调是一个很好的使用SO。 不,这只是您对 OP 问题的慈善解释 谁让您成为确定解释是“慈善”还是“公平”的老板? 关于 SO 的每个答案都会做出假设。
  • 好的,让我重申一下。您的答案包括一段询问 OP 是否知道 Java 语言的基础知识(有些人甚至可能将其解释为违反“友善”政策)。诸如“回到第一方并开始学习 java”之类的句子是 IMO 对 OP 问题质量极差的反映。如果这个问题让你觉得 OP 甚至可能不了解编程的基础知识,例如基本数据类型,最好的办法是不回答它,而是投票关闭它,并可选择发表评论要求澄清。
  • @l4mpi 这是一个公平的观点。我假设(希望?)这是前一个问题,OP 将 . 混淆为 _
【解决方案2】:

这是正常行为,因为您要显示为 long 的值具有小数部分(432.89,而不是 432.90,因为从 double 中设置 BigDecimal)所以不是整数。来自javadoc

将此 BigDecimal 转换为 long,检查丢失的信息。如果 此 BigDecimal 具有非零小数部分或超出 长结果的可能范围,然后 ArithmeticException 是 扔了。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-06-04
    • 1970-01-01
    • 2011-10-26
    • 1970-01-01
    • 2014-03-20
    • 2016-06-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多