BigDecimal 在与浮点数转换时不保留舍入值[重复]

2023-12-03

我有一个使用 BigDecimal.setScale 将浮点数四舍五入到 n 位数字的函数

private float roundPrice(float price, int numDigits) {
    BigDecimal bd = BigDecimal.valueOf(price);
    bd = bd.setScale(numDigits, RoundingMode.HALF_UP);
    float roundedFloat = bd.floatValue();
    return roundedFloat;
}

public void testRoundPrice() {
    float numberToRound = 0.2658f;
    System.out.println(numberToRound);
    float roundedNumber = roundPrice(numberToRound, 5);
    System.out.println(roundedNumber);
    BigDecimal bd = BigDecimal.valueOf(roundedNumber);
    System.out.println(bd);
}

Output:

0.2658
0.2658
0.26579999923706055

如何防止 BigDecimal 在舍入值末尾添加所有这些额外数字?

注意:我无法执行以下操作,因为我无权访问 api 调用函数中的位数。

System.out.println(bd.setScale(5, RoundingMode.CEILING));

事实恰恰相反。BigDecimal正在告诉你真相。 0.26579999923706055 更接近您的值float在四舍五入之前和之后都有所有时间。 Afloat作为二进制数而不是十进制数不能精确地保存 0.2658。实际上 0.265799999237060546875 是我们能得到的最接近的值。

当您打印浮点数时,您不会获得完整的值。会发生一些舍入,因此尽管float具有上述值,您只会看到0.2658.

当您创建一个BigDecimal来自float,你实际上首先转换为double(因为这就是BigDecimal.valueOf()接受)。这double具有相同的值float,但会打印为 0.26579999923706055,这也是您的值BigDecimal gets.

如果你想要一个BigDecimal拥有printed的值float而不是其中的确切值或接近的值,以下可能有效:

    BigDecimal bd = new BigDecimal(String.valueOf(roundedNumber));
    System.out.println(bd);

Output:

0.2658

不过,您可能会对其他值感到惊讶,因为float还没有那么高的精度。

编辑:你正在有效地转换float -> double -> String -> BigDecimal.

Dawood ibn Kareem 的这些富有洞察力的评论让我进行了一些研究:

实际上是0.265799999237060546875。

Well, 0.26579999923706055是调用返回的值toString on the double价值。这和号码不一样 实际上代表的是double。这就是为什么BigDecimal.valueOf(double)通常不会返回相同的值 作为new BigDecimal(double)。了解这一点非常重要 如果您要使用浮点值,则会有所不同 与BigDecimal.

那么到底发生了什么:

  1. Your float在舍入之前和之后,内部的值为 0.265799999237060546875。
  2. When you are passing your float to BigDecimal.valueOf(double), you are effectively converting float -> double -> String -> BigDecimal.
    • The double具有相同的值float,0.265799999237060546875。
    • 转换为String稍微舍入到"0.26579999923706055".
    • So your BigDecimal获取值 0.26579999923706055,即您看到并询问的值。

从文档BigDecimal.valueOf(double):

翻译一个double into a BigDecimal, 使用double的 提供的规范字符串表示Double.toString(double) method.

Links

  • 堆栈溢出问题:浮点数学有问题吗?
  • 文档:BigDecimal.valueOf(double)
  • 堆栈溢出问题:BigDecimal - 使用 new 或 valueOf
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

BigDecimal 在与浮点数转换时不保留舍入值[重复] 的相关文章

  • 获取 UndeclaredThrowableException 而不是我自己的异常

    我有以下代码 public Object handlePermission ProceedingJoinPoint joinPoint RequirePermission permission throws AccessException
  • 如何将log4j日志文件更改为utf8

    我收到了一个使用 log4j 作为记录器应用程序的代码 如何为其生成 UTF8 日志文件 log4j 创建的日志文件目前为 ASCII 格式 我已经尝试过以下操作 按照以下说明设置日志文件的文件编码 vi current set bomb
  • Maven UTF-8编码问题

    当我使用两个不同的项目运行下面的代码时 我得到不同的输出 String myString T rk e Karakter Testi i String value new String myString getBytes UTF 8 Sys
  • 如果我在 JSP 中有 html 元素,那么执行顺序是什么?

    什么将执行第一个 body 元素或 head 元素 Head Body scriplet 如果我明白您的要求 JSP 文件中的每个元素都会按照代码从上到下出现的顺序进行处理
  • Tomcat 7 停止接收 HTTP 请求

    我有一个Tomcat 7接收大量数据的服务器GET 要求 这种方法在一段时间内效果很好 然后突然停止工作 7 8 小时后 当它停止工作时 我收到此错误 五月 06 2015 12 47 58 AM org apache coyote htt
  • 协助持续进行 Java 到 C# 转换的工具

    如今 许多项目都是用 Java 编写的 其中一些最终转换为 C 以合并到 NET 中 我想到的例子有 log4net nhibernate 和 db4o 包括 Sharpen db4o 的工具 在内 您是否见过和 或使用过任何使连续转换变得
  • 如何从内容处置中读取编码的文件名

    我得到的内容处置标头值如下 附件 文件名 UTF 8 album jpeg 如何从中提取文件名 album jpeg 在查看该值时 它具有编码格式值 使用Spring的内容配置 https docs spring io spring doc
  • Powermockito 可以在非最终具体类中模拟最终方法吗?

    假设我有一个非最终具体类 具有如下所示的最终方法 public class ABC public final String myMethod return test test 可以嘲笑吗myMethod 调用时返回其他内容junit usi
  • 从 HashMap 条目列表中删除重复项

    我有一个List
  • Hazelcast Jet 变更数据捕获

    我在我的应用程序中使用 Hazelcast 更改数据捕获 CDC 我使用 CDC 的原因是 如果使用 jdbc 或其他替代功能将数据加载到缓存中 会花费大量时间 所以CDC将在数据库和 Hazelcast Jet 之间进行数据同步 Stre
  • Java GUI,根据actionListener更改面板

    我在两个不同的面板中添加了两个按钮 如果单击第一个按钮 则需要转到下一个面板 其中包含第二个按钮 但是当我单击第一个按钮时 该按钮没有被替换 Java GUI import java awt event ActionEvent import
  • 椭圆与椭圆如何相交?

    我用的是JAVA Ellipse2D s1 new Ellipse2D Float 0 0 100 100 System out println s1 intersects 99 30 100 100 应该返回 false 但它返回 tru
  • IntelliJ 对于 Java 项目使用的默认构建过程是什么?

    直接从 IntelliJ 中的 IDE 构建 Java 项目非常好 它速度很快 而且很有效 我无法找到任何有关 IntelliJ 如何进行这些默认构建的文档 我猜它使用Ant 我想做的是为下载我的项目的任何人自动化这个快速 轻松的构建过程
  • 如何更改使用 Google ReCaptcha 版本 2 时的错误消息?

    当为 Google ReCaptcha 版本 2 选择多张照片时 会显示以下错误消息 需要多个正确的解决方案 请解决更多 如何将错误消息更改为我网站上的自定义消息 这是图像 我认为不可能在服务器端 在谷歌 进行 这可以在客户端通过利用 js
  • 为什么我用Java计算的结果是错误的?

    我使用这段代码来计算一些东西 但几乎在所有情况下结果都是 0 0 为什么 编译器中没有警告或错误 private void jButton1ActionPerformed java awt event ActionEvent evt try
  • 将带有 md5 消息摘要和 DESede/CBC/PKCS5Padding 的 3DES 加密的 java 代码转换为 python

    我有这个工作java代码 它使用3DES加密对密码进行加密 import java security MessageDigest import java util Arrays import java util Base64 import
  • Maven 依赖冲突:org.w3c.dom.ElementTraversal

    我有一个 Java 代码库 它使用 Maven 进行依赖项解析并在 CI 上运行测试 经过最近的一批开发 大到足以很难识别重大更改 我的一些测试现在在通过 Maven 运行时失败了NoClassDefFoundError for org w
  • 如何删除 Spring 的 RestTemplate 添加的某些 HTTP 标头?

    我在远程服务方面遇到问题 我无法控制对使用 Spring 的 RestTemplate 发送的请求进行 HTTP 400 响应 使用发送的请求curl但被接受了 所以我将它们与通过 RestTemplate 发送的内容进行了比较 特别是 S
  • Selenium 查看鼠标/指针

    有什么方法可以在运行测试时真正看到硒鼠标吗 要么是 Windows 光标图像 要么是某种点或十字线或任何东西 我正在尝试使用拖放功能selenium and java in an HTML5Web 应用程序 并且能够看到光标以了解它实际在做
  • SQL准备语句如何通过多个可能的菜单选择进行选择?

    所以我有 4 个菜单选择 产品 位置 课程类型和类别 所有这些都可以为空 使用 JSF 编程 但这应该与这个问题无关 因为它是一个 SQL 问题 菜单选择将向托管 bean 发送用户选择的变量 并使用准备好的语句使用用户选择的菜单中的信息

随机推荐