Java Math 类中的新功能,第 2 部分: 浮点数

Java 语言规范第 5 版向 java.lang.Math 和 java.lang.StrictMath 添加了 10 种新方法,Java 6 又添加了 10 种。这个共两部分的系列文章的 第 1 部分 介绍了很有意 义的新的数学方法。它提供了在还未出现计算机的时代中数学家比较熟悉的函数。在第 2 部 分中,我主要关注这样一些函数,它们的目的是操作浮点数,而不是抽象实数。

就像 我在 第 1 部分中 提到的一样,实数(比如 e 或 0.2)和它的 计算机表示(比如 Java double)之间的区别是非常重要的。最理想的数字应该是无限精确 的,然而 Java 表示的位数是固定的(float 为 32 位,double 为 64 位)。float 的最大 值约为 3.4*1038。这个值还不足以表示某些东西,比如宇宙中的电子数目。

double 的最大值为 1.8*10308,几乎能够表示任何物理量。不过涉及到 抽象数学量的计算时,可能超出这些值的范围。例如,光是 171! (171 * 170 * 169 * 168 * ... * 1) 就超出了 double 最大值。float 只能表示 35! 以内的数字。非常小的数(值 接近于 0 的数字)也会带来麻烦,同时涉及到非常大的数和非常小的数的计算是非常危险的 。

为了处理这个问题,浮点数学 IEEE 754 标准(参见 参考资料)添加了特殊值 Inf 和 NaN,它们分别表示无穷大(Infinity)和非数字(Not a Number)。IEEE 754 还定 义了正 0 和负 0(在一般的数学中,0 是不分正负的,但在计算机数学中,它们可以是正的 ,也可以是负的)。这些值给传统的原理带来了混乱。例如,当使用 NaN 时,排中律就不成 立了。x == y 或 x != y 都有可能是不正确的。当 x 或 y 为 NaN 时,这两个式子都不成 立。

除了数字大小问题外,精度是一个更加实际的问题。看看这个常见的循环,将 1.0 相加 10 次之后等到的结果不是 10,而是 9.99999999999998:

for (double x = 0.0; x <= 10.0; x += 0.1) {
   System.err.println(x);
}

对于简单的应用程序,您通常让 java.text.DecimalFormat 将最终的输出格式化为与其 值最接近的整数,这样就可以了。不过,在科学和工程应用方面(您不能确定计算的结果是 否为整数),则需要加倍小心。如果需要在特别大的数字之间执行减法以得到较小的数字, 则需要万分 小心。如果以特别小的数字作为除数,也需要加以注意。这些操作能够将很小的 错误变成大错误,并给现实应用带来巨大的影响。由有限精度浮点数字引起的很小的舍入错 误就会严重歪曲数学精度计算。

浮点数和双精度数字的二进制表示

由 Java 实现的 IEEE 754 浮点数有 32 位。第一位是符号位,0 表示正,1 表示负。接 下来的 8 位表示指数,其值的范围是 -125 到 +127。最后的 23 位表示尾数(有时称为有 效数字),其值的范围是 0 到 33,554,431。综合起来,浮点数是这样表示的: sign * mantissa * 2exponent

敏锐的读者可能已经注意到这些数字有些不对劲。首先,表示指数的 8 位应该是从 -128 到 127,就像带符号的字节一样。但是这些指数的偏差是 126,即用不带符号的值(0 到 255)减去 126 获得真正的指数(现在是从 -126 到 128)。但是 128 和 -126 是特殊值。 当指数都是 1 位(128)时,则表明这个数字是 Inf、-Inf 或 NaN。要确定具体情况,必须 查看它的尾数。当指数都是 0 位(-126)时,则表明这个数字是不正常的(稍后将详细介绍 ),但是指数仍然是 -125。

尾数一般是一个 23 位的不带符号的整数 — 它非常简单。23 位可以容纳 0 到 224-1,即 16,777,215。等一下,我刚才是不是说尾数的范围是从 0 到 33,554,431?即 225-1。多出的一位是从哪里来的?

因此,可以通过指数表示第 1 位是什么。如果指数都是 0 位,则第 1 位为 0。否则第 1 位为 1。因为我们通常知道第 1 位是什么,所以没有必要包含在数字中。您 “免费” 得 到一个额外的位。是不是有些离奇?

尾数的第 1 位为 1 的浮点数是正常的。即尾数的值通常在 1 到 2 之间。尾数的第 1 位为 0 的浮点数是不正常的,尽管指数通常为 -125,但它通常能够表示更小的数字。

双精度数是以类似的方式编码的,但是它使用 52 位的尾数和 11 位的指数来获得更高的 精度。双精度数的指数的偏差是 1023。

时间: 2024-08-01 20:14:07

Java Math 类中的新功能,第 2 部分: 浮点数的相关文章

Java Math 类中的新功能,第 1 部分: 实数

有时候您会对一个类熟悉到忘记了它的存在.如果您能够写出 java.lang.Foo 的文档, 那么 Eclipse 将帮助您自动完成所需的函数,您无需阅读它的 Javadoc.例如,我使用 java.lang.Math(一个我自认为非常了解的类)时就是这样,但令我吃惊的是,我最近偶然 读到它的 Javadoc -- 这可能是我近五年来第一次读到,我发现这个类的大小 几乎翻了一倍,包含 20 种我从来没听说过的新方法.看来我要对它另眼相看了. Java 语言规范第 5 版向 java.lang.M

浅谈java中math类中三种取整函数的区别_java

math类中三大取整函数 1.ceil 2.floor 3.round 其实三种取整函数挺简单的.只要记住三个函数名翻译过来的汉语便能轻松理解三大函数,下面一一介绍 1.ceil,意思是天花板,java中叫做向上取整,大于等于该数字的最接近的整数 例:math.ceil(13.2)=14 math.ceil(-13.2)=-13 2.floor,意思是地板,java中叫做向下取整,小于等于该数字的最接近的整数 例:math.floor(13.2)=13 math.floor(-13.2)=-14

如何充分利用Windows 8.1中的新功能

  距微软推出Windows 8.1公众预览版已差不多一个月时间,但这并不意味着Windows 8应用开发者们可以等到最终的RTM版发布的时候才开始应用的调节工作.今天,微软给Windows 8应用的制作者们带来了一些有用的提示,希望能帮助他们充分利用到Windows 8.1中的新功能. 微软在其Windows App Builder博客上发布了这篇技术性很强的文章,其中有提到:Windows 8.1去掉了"过程生命周期管理"(Process Lifetime Management)导

《Adobe Premiere Pro CS4经典教程》——1.2 Adobe Premiere Pro CS4中的新功能

1.2 Adobe Premiere Pro CS4中的新功能 虽然这不是Premiere Pro CS4项功能的完整列表,但会列出您在学习这个应用程序时所期望的一些功能改进.我们将在本书中使用很多这些功能. 1.2.1 特效 - 把特效应用到多个剪辑:选择序列中的多段剪辑,把一个或多个特效从Effects面板拖放到所选择的剪辑,这样可以提高编辑效率. - 使用多种预设特效:现在把一个或多个特效保存为预设,您可以把它应用到序列或项目面板内的一个或多个剪辑. - 删除所有特效:从一个或多个剪辑中快

《Adobe Premiere Pro CS5经典教程》——第1课 Adobe Premiere Pro CS5概述 1.1 Adobe Premiere Pro CS5中的新功能

第1课 Adobe Premiere Pro CS5概述 本课介绍的内容包括: dobe Premiere Pro CS5的新功能. Adobe Premiere Pro CS5内的非线性编辑. 标准的数字视频工作流. 将Adobe Creative Suite 3 Production Premium集成到工作流. Premiere Pro工作区介绍. 定制工作区. 本课大约需要40分钟. 在第一次编辑或者应用第一个切换之前,需要简要了解一下视频编辑.Adobe Premiere Pro对视频

使用.net framework中常用类在2.0版中的新功能

在上一篇<浏览.NET Framework 2.0 类型库中新增的常用功能>一文中我主要列了几个新增的常用主件,本文作为小结主要针对一些常用类的扩展来讲最近在使用C# 2.0 的时候发现的几个新特征,讲得不当之处请网友指正. 1.Exception异常基类在2.0下,Exception基类增加了Data属性,原型如下,public virtual IDictionary Data {get;}可见其实现了IDictionary接口,用来存储异常的自定义信息,由此想到在ExceptionMana

Spring Framework 4.2 中的新功能和增强功能

至今为止,Spring Framework 的最新版本为 4.2.1.RELEASE. 那么 Spring Framework 4.2 中的又有哪些新功能和增强功能呢? 核心容器改进 如 @bean 注释,就如同得到发现和处理 Java 8 默认方法一样,可以允许组合配置类与默认@bean 接口方法. 配置类现在可以声明 @import 作为常规组件类,允许引入的配置类和组件类进行混合. 配置类可以声明一个 @Order 值,用来得到相应的处理顺序(例如重写 bean 的名字),即使通过类路径扫

Java定时任务:利用java Timer类实现定时执行任务的功能_java

一.概述 在java中实现定时执行任务的功能,主要用到两个类,Timer和TimerTask类.其中Timer是用来在一个后台线程按指定的计划来执行指定的任务. TimerTask一个抽象类,它的子类代表一个可以被Timer计划的任务,具体要执行的代码写在TimerTask需要被实现的run方法中. 二.先看一个最简单的例子 我们通过代码来说明 import java.text.SimpleDateFormat; import java.util.Date; import java.util.T

IBM Rational Rhapsody 8.0和Rhapsody Design Manager 4.0中的新功能

重要的新功能 IBM Rational Rhapsody 开发环境支持广泛的技术,可用于许多用途,例如: 需求分析 基于模型的系统工程 交易学习分析 嵌入式和实时软件开发 注重安全性的软件开发 基于模型的测试 AUTomotive Open System ARchitecture (AUTOSAR) 开发 捕获 DoDAF 或 MODAF 架构框架 Rational Rhapsody 8.0 和 Rational Rhapsody Design Manager 4.0 版本包含一些新功能和改进,