Deprecated: imwpcache\f884414bce24ee67f\f73723ec7b1919fa5::__construct(): Implicitly marking parameter $YECBGYFECGEAFWHA as nullable is deprecated, the explicit nullable type must be used instead in /www/wwwroot/www.chuangxiangniao.com/wp-content/plugins/imwpcache-dist/build/f884414bce24ee67ff73723ec7b1919fa5.php on line 2

Deprecated: imwpcache\f884414bce24ee67f\f73723ec7b1919fa5::__construct(): Implicitly marking parameter $BBWFDDBHHYHDXXAB as nullable is deprecated, the explicit nullable type must be used instead in /www/wwwroot/www.chuangxiangniao.com/wp-content/plugins/imwpcache-dist/build/f884414bce24ee67ff73723ec7b1919fa5.php on line 2
深入理解Java中HALF_EVEN舍入模式与浮点数精度陷阱_创想鸟

深入理解Java中HALF_EVEN舍入模式与浮点数精度陷阱

深入理解Java中HALF_EVEN舍入模式与浮点数精度陷阱

本文深入探讨了java中`roundingmode.half_even`模式在处理特定小数(如6.325)时,为何会产生与预期不符的舍入结果。核心原因在于浮点数(`double`类型)无法精确表示某些十进制小数,导致其内部存储值略有偏差,从而影响了“最近邻”和“等距”的判断。文章将通过示例代码解析此现象,并提供使用`bigdecimal`等解决方案,以确保数值计算的精确性。

Java HALF_EVEN 舍入模式解析

在Java中,java.text.DecimalFormat和java.math.BigDecimal都支持多种舍入模式,其中RoundingMode.HALF_EVEN(也称为银行家舍入法)是一种常用的规则。其定义如下:

RoundingMode.HALF_EVEN: 向“最近的邻居”方向舍入,除非两个邻居距离相等,在这种情况下,向“偶数邻居”方向舍入。

这意味着,如果一个数字恰好位于两个可能舍入结果的中间(即等距),它将舍入到末位是偶数的那个结果。例如:

2.5 舍入到整数位,会变成 2 (因为 2 是偶数)。3.5 舍入到整数位,会变成 4 (因为 4 是偶数)。2.25 舍入到一位小数,会变成 2.2 (因为 2.2 更近)。2.35 舍入到一位小数,会变成 2.4 (因为 2.4 更近)。

浮点数精度问题:6.325的特殊案例

根据HALF_EVEN的定义,当我们将6.325舍入到两位小数时,6.32和6.33都是其“邻居”,且6.325恰好位于它们之间。在这种等距情况下,我们期望它会舍入到末位为偶数的6.32。然而,在Java中使用DecimalFormat进行格式化时,实际结果却可能出乎意料:

import java.text.DecimalFormat;import java.math.RoundingMode;public class HalfEvenRoundingExample {    public static void main(String[] args) {        DecimalFormat df = new DecimalFormat("0.00");        df.setRoundingMode(RoundingMode.HALF_EVEN);        double value = 6.325;        String formattedValue = df.format(value);        System.out.println("使用DecimalFormat格式化 6.325 (HALF_EVEN): " + formattedValue);        // 预期输出: 6.32        // 实际输出: 6.33    }}

运行上述代码,会发现输出结果是6.33,而非预期的6.32。这与HALF_EVEN的定义似乎相悖。

立即学习“Java免费学习笔记(深入)”;

揭示真相:double类型的内部表示

这种看似矛盾的现象并非HALF_EVEN模式本身的问题,而是源于Java(以及大多数编程语言)中浮点数(float和double)的底层实现机制——IEEE 754浮点数标准。

浮点数在计算机内部是以二进制形式存储的。这意味着,并非所有的十进制小数都能被精确地表示。例如,0.1在二进制中是一个无限循环小数,就像1/3在十进制中是0.333…一样。6.325也属于这类无法精确表示的十进制小数。

当我们在Java代码中写入double value = 6.325;时,6.325实际上被存储为其最接近的double类型表示。这个最接近的double值并非精确的6.325,而是略大于6.325:

6.325的实际double表示近似为 6.32500000000000017763568394002504646778106689453125。

STORYD STORYD

帮你写出让领导满意的精美文稿

STORYD 164 查看详情 STORYD

正是这个微小的偏差改变了舍入时的“等距”条件。由于内部存储的值略大于6.325,它不再是精确地位于6.32和6.33的中间。相反,它现在更靠近6.33。因此,根据HALF_EVEN规则的第一部分(向“最近的邻居”方向舍入),它被舍入到了6.33。

我们可以通过打印更高精度的double值来验证这一点,或者使用在线浮点数转换器来查看其二进制表示。

确保精确计算:BigDecimal的应用

为了避免浮点数精度问题对数值计算和舍入结果造成的影响,尤其是在金融计算或任何需要高精度的场景中,Java提供了java.math.BigDecimal类。BigDecimal能够精确表示任意精度的十进制数,从而避免了double和float的精度限制。

当使用BigDecimal时,我们可以确保6.325被精确地表示,并且HALF_EVEN舍入模式将按照预期工作:

import java.math.BigDecimal;import java.math.RoundingMode;public class BigDecimalRoundingExample {    public static void main(String[] args) {        // 推荐使用字符串构造BigDecimal,避免double的精度问题        BigDecimal bdValue = new BigDecimal("6.325");         // 设置舍入模式和精度        BigDecimal roundedValue = bdValue.setScale(2, RoundingMode.HALF_EVEN);        System.out.println("使用BigDecimal处理 6.325 (HALF_EVEN): " + roundedValue);        // 预期输出: 6.32        // 实际输出: 6.32 (正确)        // 另一个HALF_EVEN的例子        BigDecimal bdValue2 = new BigDecimal("6.335");        BigDecimal roundedValue2 = bdValue2.setScale(2, RoundingMode.HALF_EVEN);        System.out.println("使用BigDecimal处理 6.335 (HALF_EVEN): " + roundedValue2);        // 预期输出: 6.34 (因为34是偶数)        // 实际输出: 6.34 (正确)    }}

在上述BigDecimal的示例中,”6.325″作为字符串传入构造器,确保了BigDecimal对象内部精确地表示6.325。此时,setScale(2, RoundingMode.HALF_EVEN)方法会正确地将6.325舍入到6.32,因为它严格位于6.32和6.33之间,并且6.32是偶数邻居。

总结与最佳实践

RoundingMode.HALF_EVEN模式在Java中是按照其定义工作的。然而,当与double或float等浮点类型结合使用时,由于这些类型固有的精度限制,它们可能无法精确表示某些十进制小数,从而导致在舍入时出现与直觉不符的结果。

关键点:

浮点数不精确性: double类型的6.325实际上存储的是一个略大于6.325的值,这使得它不再是等距的,而是更接近6.33。HALF_EVEN原则: 当数字不再是等距时,HALF_EVEN会优先舍入到最近的邻居。解决方案: 对于需要精确十进制计算的场景(如货、科学计算),务必使用java.math.BigDecimal类。在创建BigDecimal对象时,建议使用字符串构造器(new BigDecimal(“6.325”))来避免double类型转换带来的精度损失。

理解浮点数的这些底层特性对于编写健壮和精确的数值处理代码至关重要。

以上就是深入理解Java中HALF_EVEN舍入模式与浮点数精度陷阱的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/866275.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
希沃白板5如何使用擦除功能_希沃白板5擦除工具的精确操作
上一篇 2025年11月28日 02:31:50
卡普空暂无推出《生化危机9》试玩版计划:先把游戏做完
下一篇 2025年11月28日 02:31:58

相关推荐

  • 卢伟冰:功能手机、智能手机之后 手机行业正进入新周期

    9月4日,小米集团总裁卢伟冰表示,继功能机时代与智能机时代之后,全球手机产业正迈入一个全新时代。 卢伟冰今日在社交平台发文提到:“我从2002年进入手机行业,有幸完整见证了功能手机和智能手机两大发展阶段。如今,AI时代已经到来,整个行业正在酝酿深刻变革,步入全新的发展周期。” 回望过去,功能手机时期…

    2026年9月21日
    200
  • Java 正则表达式:查找双引号内所有指定字符串的出现次数

    本文旨在解决在 Java 中使用正则表达式查找双引号内特定字符串(例如 “variant”)的所有出现次数的问题。我们将提供一个完整的解决方案,包括正则表达式的构建、代码示例以及详细的解释,帮助开发者准确高效地完成此类任务。 在 Java 中,使用正则表达式查找字符串中特定模…

    2026年9月21日
    000
  • MySQL 大型历史数据表结构设计与优化指南

    本文旨在为处理大量客户历史交易数据的MySQL数据库设计提供专业指导。我们将探讨如何构建高效、可扩展的表结构,重点关注主键设计、数据分区、实时数据摄入以及性能优化策略,以确保系统能够稳定支持百万级乃至亿级数据量的查询需求。 MySQL大型历史数据表结构设计与优化 在处理大量历史数据,特别是涉及到多用…

    2026年9月21日
    000
  • MySQL重复数据检测与清理逻辑_Sublime脚本批量处理历史冗余记录

    MySQL重复数据检测与清理逻辑_Sublime脚本批量处理历史冗余记录MySQL重复数据检测与清理逻辑_Sublime脚本批量处理历史冗余记录MySQL重复数据检测与清理逻辑_Sublime脚本批量处理历史冗余记录MySQL重复数据检测与清理逻辑_Sublime脚本批量处理历史冗余记录

    处理mysql重复数据的核心步骤是识别并清理,可使用group by或窗口函数定位重复项,再通过分批删除或倒腾法安全清理;sublime text可用于高效生成和编辑sql语句。1. 识别重复数据常用group by+having或row_number()窗口函数;2. 清理策略包括分批删除、使用临…

    2026年9月21日 用户投稿
    100
  • 如何用PyTorch训练AI大模型?构建高效神经网络的完整教程

    如何用PyTorch训练AI大模型?构建高效神经网络的完整教程如何用PyTorch训练AI大模型?构建高效神经网络的完整教程如何用PyTorch训练AI大模型?构建高效神经网络的完整教程如何用PyTorch训练AI大模型?构建高效神经网络的完整教程

    PyTorch大模型训练需综合运用分布式训练、内存优化与高效计算策略。首先采用DistributedDataParallel实现多GPU并行,配合DistributedSampler确保数据均衡;通过混合精度训练、梯度累积和激活检查点缓解显存压力;使用torch.compile优化模型计算效率;选择…

    2026年9月21日 用户投稿
    100
  • 丛林宝藏猎人必备指南:解锁稀有皮肤与服饰的黄金法则

    谁说稀有皮肤遥不可及?揭开丛林宝箱的秘密,成为雨林猎人的梦想触手可及!这些散发着原始气息与神秘魅力的箱子,蕴藏着极具收藏价值的丛林主题服饰和炫酷夺目的武器皮肤,是每一位冒险者心中的至宝。究竟如何才能将它们收入囊中?三大核心途径为你点亮寻宝之路! 一、零花玩家的宝藏地图:野外探索(免费但拼实力)经典模…

    2026年9月21日
    100
  • win10打开图片提示“没有注册类”怎么办_win10图片打开注册类错误解决方案

    首先重置照片应用并修复系统文件,再通过PowerShell重新注册应用包,最后调整默认应用关联以解决“没有注册类”错误。 如果您尝试在Windows 10中打开图片文件,但系统弹出“没有注册类”的错误提示,则可能是由于默认图片查看应用的注册信息丢失或损坏。以下是解决此问题的步骤: 本文运行环境:De…

    2026年9月21日
    200
  • MySQL自动化性能测试方案_MySQL持续监控调优数据库效率

    MySQL自动化性能测试方案_MySQL持续监控调优数据库效率MySQL自动化性能测试方案_MySQL持续监控调优数据库效率MySQL自动化性能测试方案_MySQL持续监控调优数据库效率MySQL自动化性能测试方案_MySQL持续监控调优数据库效率

    mysql自动化性能测试和持续监控的核心在于构建闭环反馈系统,包含模拟真实负载、全面数据采集、自动化执行与分析、数据驱动的持续调优四大环节。①测试环境需与生产一致并隔离,使用docker、虚拟机或云沙盒,解决数据同步与脱敏问题;②负载生成工具如sysbench、jmeter、locust或自定义脚本…

    2026年9月21日 用户投稿
    200
  • CyberLinkMediaSuite如何制作AI视频?多功能工具快速剪辑的方法

    CyberLinkMediaSuite如何制作AI视频?多功能工具快速剪辑的方法CyberLinkMediaSuite如何制作AI视频?多功能工具快速剪辑的方法CyberLinkMediaSuite如何制作AI视频?多功能工具快速剪辑的方法CyberLinkMediaSuite如何制作AI视频?多功能工具快速剪辑的方法

    答案:CyberLink MediaSuite(核心为PowerDirector)通过AI艺术风格转换、智能对象选取、AI天空替换、音频降噪与运动追踪等功能,显著提升视频制作效率与创意表现。结合模板应用、快捷键操作、媒体库管理及代理编辑等实战技巧,可实现快速剪辑与专业输出,适用于Vlog创作、教育视…

    2026年9月21日 用户投稿
    300
  • Win10与Ubuntu 18.04双系统安装。(Win10引导Linux)[通俗易懂]

    Win10与Ubuntu 18.04双系统安装。(Win10引导Linux)[通俗易懂]Win10与Ubuntu 18.04双系统安装。(Win10引导Linux)[通俗易懂]Win10与Ubuntu 18.04双系统安装。(Win10引导Linux)[通俗易懂]Win10与Ubuntu 18.04双系统安装。(Win10引导Linux)[通俗易懂]

    大家好,很高兴再次与大家见面,我是你们的老朋友全栈君。 作为一个初学者,为了满足自己的求知欲,我按照几位大神写的教程尝试了一遍安装过程,现在来和大家分享一下。 1、Win10安装(如果已经安装,请跳过) 1)制作系统U盘(参考微信公众号“软件安装管家”): https://www.php.cn/li…

    2026年9月21日 用户投稿
    400
  • 百家号视频怎么隐藏?百家号怎么设置仅自己可见

    随着短视频平台的快速发展,其已成为人们获取资讯和休闲娱乐的重要方式。作为国内知名的自媒体平台之一,百家号吸引了大量用户。然而,在享受便捷的同时,隐私安全问题也日益突出。本文将介绍百家号视频隐藏的方法,帮助用户更好地保护个人内容,维护隐私安全。 一、百家号视频隐藏方法 设置隐私权限 在百家号后台,用户…

    2026年9月21日
    200
  • MySQL数据库如何设计适合大数据量的表结构_案例分析?

    MySQL数据库如何设计适合大数据量的表结构_案例分析?MySQL数据库如何设计适合大数据量的表结构_案例分析?MySQL数据库如何设计适合大数据量的表结构_案例分析?MySQL数据库如何设计适合大数据量的表结构_案例分析?

    设计适合大数据量的mysql表结构,核心在于数据类型选对、索引用好、适当拆分。1. 合理选择字段类型,如根据数据范围选用tinyint/smallint代替bigint,固定值字段用enum类型,大文本字段单独拆表;2. 精准建立索引,高频查询字段建联合索引并遵循最左前缀原则,避免低区分度字段建索引…

    2026年9月21日 用户投稿
    100
  • Java Random类如何生成随机数

    Random类位于java.util包,通过实例化生成伪随机数;无参构造以系统时间作种子,带参构造用固定种子可复现序列;提供nextInt()、nextDouble()等方法生成不同类型随机值;指定范围整数可用rand.nextInt(max-min)+min实现;多线程推荐ThreadLocalR…

    2026年9月21日
    200
  • windows10如何查看S.M.A.R.T.硬盘状态_windows10硬盘S.M.A.R.T.状态查看方法

    电脑运行慢、蓝屏或文件损坏可能是硬盘故障前兆,可通过S.M.A.R.T.技术检测健康状况。1、使用WMIC命令行工具输入“wmic diskdrive get model,status”查看状态,显示Pred Fail需立即备份数据;2、CrystalDiskInfo可深度分析S.M.A.R.T.参…

    2026年9月21日
    200
  • Photopea的AI功能怎么裁剪图片?快速实现高效图片裁剪技巧

    Photopea的AI功能怎么裁剪图片?快速实现高效图片裁剪技巧Photopea的AI功能怎么裁剪图片?快速实现高效图片裁剪技巧Photopea的AI功能怎么裁剪图片?快速实现高效图片裁剪技巧Photopea的AI功能怎么裁剪图片?快速实现高效图片裁剪技巧

    Photopea的AI功能通过智能选择工具与内容感知技术结合,实现高效图片裁剪。首先使用对象选择、快速选择或魔棒工具智能识别主体或背景,再通过“选择并遮住”精细调整边缘,尤其适用于复杂轮廓如发丝。随后可应用图层蒙版透明化背景,并用裁剪工具调整画布范围。结合内容感知填充可移除干扰元素并自动补全画面,内…

    2026年9月21日 用户投稿
    300
  • PHP框架中间件有什么用处_PHP框架中间件设计与实现

    PHP框架中间件是处理请求和响应的过滤器,用于实现身份验证、日志记录、CORS等通用逻辑,核心价值在于解耦和提升可维护性。通过定义中间件接口、具体中间件类及管道调度器可实现自定义中间件,如身份验证或CORS处理。在Laravel中可通过Kernel.php配置全局、分组或路由级中间件,执行顺序按注册…

    2026年9月21日
    100
  • Java中字符到数字转换:解决for循环提前返回的常见陷阱

    本文探讨java中`for`循环在字符到数字转换时,因`return`语句放置不当导致程序提前终止、无法完整处理字符串的问题。我们将分析这种常见陷阱,并提供修正方案,演示如何正确利用循环填充数组,并在循环结束后统一返回最终结果,确保每个字符都能被准确映射和组合。 引言:字符到数字的映射需求 在编程实…

    2026年9月21日
    100
  • win10登录界面不显示用户头像或名称怎么办_恢复登录界面完整显示的操作方法

    登录界面缺少头像或账户名时,先检查账户名一致性,修复头像缓存,重设头像,扫描系统文件,必要时创建新管理员账户验证问题。 如果您在启动Windows 10后,登录界面仅显示密码输入框而缺少用户头像或账户名称,则可能是由于系统设置、缓存异常或账户配置问题导致。以下是恢复登录界面完整显示的详细操作方法。 …

    2026年9月21日
    100
  • 梦幻号虚拟主播电商运营宝典(附新手教程+配套工具清单)

    虚拟主播电商的核心在于“内容驱动销售,人设凝聚用户”,要让“梦幻号”真正动起来并实现带货,必须先赋予其鲜明的人设,包括清晰的定位标签(如美食家、科技宅)、独特的人格魅力(性格、口头禅、小缺点)和与产品的强关联性,使其具备辨识度和故事感,从而建立用户信任;接着通过obs studio、vtube st…

    2026年9月21日
    100
  • win10平板模式下屏幕键盘不自动弹出怎么办_恢复屏幕键盘自动弹出的技巧

    1、检查平板电脑模式设置,确保登录和使用时均启用平板模式并重启;2、在设备→输入中开启“不处于平板模式且未连接键盘时显示触摸键盘”;3、通过注册表编辑器创建InitialKeyboardIndicators值为2(十六进制)以强制启用键盘指示器;4、手动显示触摸键盘按钮并测试各应用兼容性,排查特定软…

    2026年9月21日
    100

发表回复

登录后才能评论
关注微信