`

java精度思考(1)

 
阅读更多

问题:

得到的结果如下:
f=2.0015E7
d=2.0015E7
d2=2.0014999E7

从输出结果可以看出double 可以正确的表示20014999 ,而float 没有办法表示20014999 ,得到的只是一个近似值。这样的结果很让人讶异。20014999 这么小的数字在float下没办法表示。于是带着这个问题,做了一次关于float和double学习,做个简单分享,希望有助于大家对java 浮点数的理解。

关于 java float double

Java 语言支持两种基本的浮点类型: float double java 的浮点类型都依据 IEEE 754 标准。IEEE 754 定义了32 位和 64 位双精度两种浮点二进制小数标准。

IEEE 754 用科学记数法以底数为 2 的小数来表示浮点数。32 位浮点数用 1 位表示数字的符号,用 8 位来表示指数,用 23 位来表示尾数,即小数部分。作为有符号整数的指数可以有正负之分。小数部分用二进制(底数 2 )小数来表示。对于64 位双精度浮点数,用 1 位表示数字的符号,用 11 位表示指数,52 位表示尾数。如下两个图来表示:

float(32位):


double(64位):


都是分为三个部分:

(1) 一个单独的符号位s 直接编码符号s

(2)k 位的幂指数E移码表示

(3)n 位的小数,原码表示

那么 20014999 为什么用 float 没有办法正确表示?

结合float和double的表示方法,通过分析 20014999 的二进制表示就可以知道答案了。

以下程序可以得出 20014999 double float 下的二进制表示方式。


输出结果如下:

Double:100000101110011000101100111100101110000000000000000000000000000

Float: 1001011100110001011001111001100

对于输出结果分析如下。对于 double 的二进制左边补上符号位 0 刚好可以得到 64 位的二进制数。根据double的表示法,分为符号数、幂指数和尾数三个部分如下:

0 10000010111 0011000101100111100101110000000000000000000000000000

对于 float 左边补上符号位 0 刚好可以得到 32 位的二进制数。 根据float的表示法, 也分为 符号数、幂指数和尾数三个部分如下

0 10010111 00110001011001111001100

绿色部分是符号位,红色部分是幂指数,蓝色部分是尾数。

对比可以得出:符号位都是 0 ,幂指数为移码表示,两者刚好也相等。唯一不同的是尾数。

double 的尾数为: 001100010110011110010111 0000000000000000000000000000 省略后面的零,至少需要24位才能正确表示

而在 float 下面尾数为: 00110001011001111001100 ,共 23 位。

为什么会这样?原因很明显,因为 float尾数 最多只能表示 23 位,所以 24 位的 001100010110011110010111 float 下面经过四舍五入变成了 23 位的 00110001011001111001100 。所以 20014999 float 下面变成了 20015000
也就是说
20014999 虽然是在float的表示范围之内,但 IEEE 754 float 表示法精度长度没有办法表示出 20014999 ,而只能通过四舍五入得到一个近似值。

总结:

浮点运算很少是精确的,只要是超过精度能表示的范围就会产生误差。往往产生误差不是因为数的大小,而是因为数的精度。因此,产生的结果接近但不等于想要的结果。尤其在使用 float double 作精确运算的时候要特别小心。
可以考虑采用一些替代方案来实现。如通过
String 结合 BigDecimal 或者通过使用 long 类型来转换。




分享到:
评论

相关推荐

    java中的1到20的阶乘

    ### Java中的1到20的阶乘 在Java编程语言中,实现1到20的阶乘是一个典型的编程练习,可以帮助初学者理解循环结构、变量声明以及简单的数学运算。本篇文章将详细介绍如何在Java中计算1到20的阶乘,并深入探讨其中...

    Java实验指导书_21

    1. 思考最佳的猜数方案,理论上,最高效的策略是每次猜测中间值,这样最多需要7次就能确定答案。 2. `System.out.println("猜对了!");`放在while循环外面是因为只有在猜对的情况下才结束循环,如果放在循环体内,...

    Java大作业

    1. **黄金分割数**:使用分层计算法求解高精度黄金分割数,可以练习数值计算和精度控制。 2. **连续数**:这道题涉及数组处理和子序列查找,可以锻炼算法设计和遍历技巧。 3. **幸运数**:幸运数的计算涉及到数学...

    java4android学习笔记(2-54全)(mars)

    - **精度区别:** `float`类型的精度较低,而`double`类型具有更高的精度。 - **表示形式:** 通常以十进制小数的形式表示。 #### 第6课 练习课(一) - **主要内容:** 实践前面章节所学的基础知识。 - **练习示例:*...

    java单元自测.pdf

    1. **Java源程序和字节码**:Java源程序文件的扩展名是`.java`,编译后生成的字节码文件扩展名为`.class`。Java源代码通过Java编译器(javac)转化为字节码,字节码可以在不同平台上运行,这是Java的跨平台特性。 2. ...

    Java实现简易计算器培训课件.pdf

    - **提升综合能力:** 培养学生的逻辑思维能力、问题解决能力和编程实践能力,同时增强其独立思考与团队合作的能力。 #### 二、实验要求 - **目标功能:** 实现一个具有基本数学运算功能的简易计算器,包括但不限于...

    Java基础总结(必看).doc

    1. Java 语言的三种技术架构: J2EE:企业版,是为开发企业环境下的应用程序提供的一套解决方案。该技术体系中包含的技术如 Servlet、Jsp 等,主要针对 Web 应用程序开发。 J2SE:标准版,是为开发普通桌面和商务...

    圣思园Java视频全套链接

    - **使用陷阱详解**:探讨在使用原始数据类型时可能遇到的问题,比如溢出错误、精度损失等,并提供相应的解决方案。 #### 五、运算符与表达式 - **运算符分类**:介绍算术运算符、关系运算符、逻辑运算符等不同...

    java程序设计之网络编程第二版课后习题答案

    1. **编写源代码**:使用文本编辑器(如Notepad、Eclipse、IntelliJ IDEA等)编写Java源代码。每个源文件应该只包含一个`public`类(如果有),并且文件名需与该`public`类的名称相同。 2. **编译源代码**:使用...

    Java基础day03(ppt文档).pptx

    (1)容量大的数据类型转换为容量小的数据类型时,要加上强制转换符,但可能造成精度降低或溢出;使用时要格外注意。 (2)有多种类型的数据混合运算时,系统首先自动的将所有数据转换成容量最大的那一种数据类型,...

    上海地区(杭州一带)面试java程序员必考的题目。

    - 对于浮点数的比较,由于浮点数存在精度误差,因此不能直接使用 `==` 或 `!=` 进行比较。 - 正确的方法是定义一个足够小的误差范围 `EPSILON`,然后使用 `(x >= -EPSILON) && (x )` 来检查浮点数是否接近于零。 - ...

    Java学习笔记(必看经典)

    - **符合人类认知习惯**:面向对象编程的方式与人们思考问题的方式一致。 - **代码复用性**:通过继承和多态等机制提高代码的复用性。 - **模块化**:降低模块间的耦合度,提高系统的可维护性和可扩展性。 #### 类...

    javaSE总结

    - 符合人们的思考习惯。 - 将复杂问题简化。 - 让程序员从具体的实现细节中抽离出来,专注于设计解决问题的策略。 - **特征**:待续。 以上是对 Java SE 基础知识的一些总结,涵盖了从 Java 的基本概念到面向...

    Java 80年代电子游戏

    - 这个时期的电子游戏往往强调玩家的反应速度和策略思考,而非复杂的故事线或高精度的视觉效果。 4. **Java重制80年代游戏的优势**: - 稳定性:Java的强类型和垃圾回收机制可以提高游戏的稳定性和内存管理。 - ...

    Project-Euler-C-Java:使用CJava编程语言实现Euler项目的源代码-java project source code

    4. **数值计算与精度控制**:对于涉及大量计算的问题,需要关注浮点数的精度问题,C语言中可以使用高精度库,Java则有BigDecimal类提供支持。 5. **代码组织与设计模式**:良好的代码结构和设计模式可以使代码更易于...

    Java_ORIPA是一款专门设计折纸折痕图案的绘图软件。ORIPA的独特之处在于从图案中计算折叠形状.zip

    它不仅仅是设计工具,更是艺术家思考和创作的延伸。在这个平台上,无论是绘制简单的几何形状,还是复杂的艺术品,都可以轻松实现。 ORIPA的自动计算功能,是基于先进的数学模型,能够自动计算出最佳的折叠路径。这...

Global site tag (gtag.js) - Google Analytics