看不到的Java细节:浮点运算
来源:互联网 发布:淘宝回复买家评论话语 编辑:程序博客网 时间:2024/06/07 01:25
看不到的Java细节:浮点运算
1、 浮点运算是不精确度的
规则:在需要精确的地方不要使用浮点,应该使用一个一个整数类型或BigDecimal。要避免浮点类型的循环索引。要避免在浮点变量上使用++和—操作符,因为这些操作对多数的浮点数都不起任何作用。避免测试浮点值是否相等。宁愿用double,而不用float。
用double或float数值类来表示无穷大是可以的。这是因为一个浮点数值越大,它和其后继数值之间的间隔就越大。浮点数的这种分布式用固定数量的有效位来表示它们的必然结果。对一个足够大的浮点数加1不会改变它的值,因为1不足以“填补它与其后继者之间的空隙”。
浮点数操作数返回的是最接近其精确数学结果的浮点数值。一旦毗邻的浮点数值之间的距离大于2,那么对其中的一个浮点数值加1将不会产生任何效果,因为其结果没有达到两个数值之间的一半。对于float类型,加1不会产生任何效果的最小级数是2^25,即33554432;而对于double类型,最小级数是2^54,即1.8e16。
毗邻的浮点数值之间的距离被称为一个ulp,他是最下单位(unit in the last place)的缩写。
此外,将一个很小的浮点数加到一个很大的浮点数上,将不会改变大浮点数的值。所以我们应该记住二进制浮点算术只是对实际算术的一种近似。
2、 NaN不等于任何浮点数值,包括它自身
规则:要避免测试浮点数的相对性。这么做并不总能避免问题,但至少是一个良好的开端。
NaN不等于任何浮点数值,包括它自身在内。“==”不满足自反性。
任何浮点操作,只要它的一个或多个操作数为NaN,那么其结果为NaN。
一旦一个计算产生了NaN,它就损坏了,没有任何更进一步的计算可以修复这样的损坏。
3、 从int到float、从long到float以及从long到double的转换时有损精度的
规则:要避免整型和浮点型混合的计算。要优选整型算术而不是浮点型算术。“==”不满足“传递性”,这是由于可能出现类型转换。
4、 BigDecimal(double)构造器返回的是其浮点型参数的精确值
规则:应该总是使用BigDecimal(String)构造器,而永远不要使用BigDecimal(double)
5、 混合型计算容易令人迷茫
规则:要避免混合类型的计算。当把?:操作符作用于数字操作符时,第二个和第三个操作数要使用相同的数字类型。宁愿使用不变的变量,不愿使用内置的幻数。
不要使用异常控制循环;应该只位异常条件而使用异常。
要意识到逻辑AND和OR操作符的存在,并且不要因无意识的无用而受害。
6、 操作符的操作数是从左到右计算的
规则:要避免在同一个表达式中对相对的变量多次赋值。尤其是在同一个表达式中放入多重复合赋值操作符特别令人迷茫。
7、 操作符的优先级并不总是很明显
规则:要使用括号而不是空格来让优先级变得明显。要用具名的常量变量来替换内联的常量表达式。
8、 操作符==和!=在包装的的原生类型上执行引用比较
规则:要想强制进行值比较,需要在比较之前将一个操作数赋值或转型成恰当的原生类型。
在5.0版本中,自动包装和自动反包装被添加到了Java语言当中。<=操作符在原始数字类型集上是反对称的,但是现在它还应用在被包装的数字类型上(被包装类型的数字类型有:Byte,Character,Short,Integer,Long,Float和Double)。<=操作符在这些类型的操作数上不是反对称的,因为Java的判等操作符(==和!=)在作用于对象引用时,执行的是引用ID的比较,而不是值的比较。
9、 常量变量在所用的地方是内联的
规则:要避免导出常量域,除非它们表示的是永远都不会变化的真正的常量。可以使用一个恒等函数将一个表达式变成非常亮。
Java是在运行时对类进行装卸的,所以它总是访问最新版本的类。
对于常量域的引用会在编译期被转化为它们所表示的常量的值。这样的域从技术上讲,被称作常量变量(constant varicable),其定义就是,一个在编译期被常量表达式初始化的final的原生类型或String类型变量。
在这里还有要了解编译期常量表达式,所谓编译期常量表达式,就是其值在编译期间被确定,而在任何程序被执行之前。这里需要指出的是null不是一个编译期常量表达式。
在5.0版本中引入的枚举常量,虽然有这样一个名字,但是它们不是常量变量。你可以在枚举类型中加入枚举常量,对它们重新排序,甚至可以移除没有用的枚举常量,并且并不需要重新编译客户端。
10、 操作数&和I即使在作用于布尔类型的数值时,也要同时计算其两个操作数。
规则:要避免将&和I作用于布尔类型的操作数。对有意义的使用要加以注释。
注意,不要使用异常类控制循环;应该只为异常条件而使用异常。
&操作符除了位AND运算之外,还有的功能就是布尔操作符,功能和&&基本相同。差别就在于:&操作符总是计算它的两个操作数,而&&操作符在其左边的操作数被计算为false时,就不在计算右边的操作数。
- 看不到的Java细节:浮点运算
- java浮点运算的陷阱
- java中浮点数的高精度运算
- java对于浮点运算的bug
- Java 的浮点数运算问题
- JAVA中精确的浮点运算
- java中浮点数的运算
- 浮点数的相关运算Java实现
- <转>JAVA精确的浮点数运算
- java 浮点数运算
- Java浮点运算-BigDecimal
- Java浮点运算精度
- Java浮点数运算
- 一些Java运算符的细节
- 浮点数的运算
- 浮点数据的运算
- 丰富多彩的浮点运算
- 浮点运算的优化
- weblogic配置文件
- Java反射机制的作用是什么
- 一句话 之 AD -- AD中的计算机也是“人”
- 分解质因数
- 【JMLR'03】Latent Dirichlet Allocation (LDA) - David M.Blei
- 看不到的Java细节:浮点运算
- c基础
- 初学者使用Emacs的难点
- CrackMe破解【3】- 简单级别
- Ogre使用多线程
- scanf
- Struts2中为什么要使用拦截器?拦截器的使用原理以及如何配置拦截器。
- none
- ns学习笔记---AODV协议1