1、 i == i + 1
一个数字永远不会等于它自己加 1 ? Java 强制要求使用 IEEE 754 浮点数算术运算 [IEEE 754] ,它可以让你用一个 double 或 float 来表示无穷大。正如我们在学校里面学到的,无穷大加 1 还是无穷大。
你可以用任何被计算为无 穷 大 的 浮点 算 术 表达式来初 始 化 i , 例 如:
double i = 1.0 / 0.0;
不 过 ,你最好是能够 利 用 标准类 库 为你 提供 的 常量 :
double i = Double. P O SI T I V E_I N F I N I T Y ;
事实 上,你不 必 将 i 初 始 化 为无 穷 大 以确 保 循 环 永远 执 行。任何足够 大 的 浮点 数都可以 实现 这一目的, 例 如:
double i = 1.0e 4 0;
这 样做 之所以可以起作用,是因为一个 浮点 数值 越 大 ,它和其后 继 数值之间的间 隔 就 越 大 。 浮点 数的这种分 布 是用 固 定数 量 的有 效 位来表 示 它 们 的 必 然结果。对一个足够 大 的 浮点 数加 1 不会 改 变 它的值,因为 1 是不足以 “ 填 补 它与其后 继 者 之间的 空 隙 ” 。
浮点 数操作返回的是 最 接近 其 精 确 的数 学 结果的 浮点 数值。一 旦毗邻 的 浮点 数值之间的 距离 大 于 2 ,那么对其中的一个 浮点 数值加 1 将不会产生任何 效 果,因为其结果 没 有达到两个数值之间的一半。对于 float 类 型,加 1 不会产生任何 效 果的最 小 级 数是 2的25次方 ,即 33,554,43 2 ;而对于 double 类 型,最 小 级 数是 2的54次方 , 大约 是 1. 8 × 10 16 。
毗邻 的 浮点 数值之间的 距离 被 称 为一个 ulp ,它是 “ 最 小单 位( unit in t h e lastplace ) ” 的 首 字 母 缩 写 词 。在 5 .0 版 中, 引 入 了 M at h .ulp 方法来计算 float 或 double 数值的 ulp 。
总之,用一个 double 或一个 float 数 值来表示无穷大是可以的。大多数人在第一次听到这句话时,多少都会有一点吃惊,可能是因为我们无法用任何整数类型来表示无穷大的原因。第二点,将一个很小 的浮点数加到一个很大的浮点数上时,将不会改变大的浮点数的值。这过于违背直觉了,因为对实际的数字来说这是不成立的。我们应该记住二进制浮点算术只是对 实际算术的一种近似。
2、 i != i
一个数 字 总是等于它 自 己 ? IEEE 754 浮点 算 术 保 留 了一个 特殊 的值用来表 示 一个不是数 字 的数 量 [IEEE 754] 。这个值就是 NaN ( “ 不是一个数 字 ( Not a Number ) ” 的 缩 写 ),对于所有 没 有 良 好的数 字 定义的 浮点 计算, 例 如 0.0/0.0 ,其值都是它。 规范 中描述 道 , NaN 不等于任何 浮点 数值,包 括 它 自 身 在 内 [ J LS 1 5 .21.1 ] 。
你可以用任何计算结果为 NaN 的 浮点 算 术 表达式来初 始 化 i , 例 如:
double i = 0.0 / 0.0;
同 样 ,为了表达 清 晰 ,你可以使用 标准类 库 提供 的 常量 :
double i = Double.NaN;
NaN 还有其他的 惊 人 之 处 。任何 浮点 操作,只要它的一个或 多 个操作数为 NaN ,那么其结果为 NaN 。这 条规则 是非 常 合 理 的,但是它 却 具有奇 怪 的结果。 例 如,下面的程序将 打印 false :
class Test {
public static void main( S trin g[] ar g s) {
double i = 0.0 / 0.0;
Sy stem.out.println(i - i == 0);
}
}
这 条 计算 NaN 的 规则 所 基 于的 原理 是:一 旦 一个计算产生了 NaN ,它就被 损 坏 了, 没 有任何更 进 一 步 的计算可以 修 复 这 样 的 损 坏 。 NaN 值意图使 受损 的计算 继 续执 行下 去 , 直 到方 便 处理 这种 情况 的地方为止。
总之,
float
和
double
类
型都有一个
特殊
的
NaN
值,用来表
示
不是数
字
的数
量
。
转载自:
无码团队blog-wuma.koubei.com