谈谈JAVA关键字—strictfp

Java语言中的其中一个设计目标是可移植性。无论在哪个虚拟机上运行,同一个计算应该得到同样的结果。对于浮点数的算术运算,实现这样的可移植性是相当困难的。double 类型使用 64 位存储一个 double 数值,而有些处理器使用 80 位浮点寄存器。这些寄存器增加了中间过程的计算精度。例如,下列运算:

double w = x * y / z ;

很多Intel处理器计算x*y,并且将结果存储在80位的寄存器中,再除以z将结果截断为64位。这样可以得到一个更为精确的计算结果,并且还能够避免产生指数溢出。但是,这个结果可能与始终在64位机器上计算的结果不一样。

因此,Java虚拟机最初规范规定所有的中间计算都必须进行截断。这种行为遭到了数值计算团体的反对。截断计算不仅可能导致溢出,而且由于截断操作需要消耗时间,所以在计算机速度上要比精确计算慢。

为此,Java程序设计语言承认了最优性能与最理想结果之间的冲突,并予以了改进。在默认情况下,虚拟机设计者允许将中间计算机结果采用扩展的精度。但是,对于使用 strictfp 关键字标记的方法来说,必须使用严格的浮点计算,以产生理想的结果。

strictfp 关键字可应用于类、接口或方法。使用 strictfp 关键字声明一个方法时,该方法中所有的float和double表达式都严格遵守FP-strict的限制,符合IEEE-754规范。 当对一个类或接口使用 strictfp 关键字时,该类中的所有代码,包括嵌套类型中的初始设定值和代码,都将严格地进行计算。严格约束意味着所有表达式的结果都必须是 IEEE 754 算法对操作数预期的结果,以单精度和双精度格式表示。

例如可以把 main 方法标记为

public static strictfp void main(String[] args){}

于是,在 main 方法中的所有指令都将使用严格的浮点计算。如将一个类标记为 strictfp ,这个类的所有方法都必须使用严格的浮点计算。
 
实际的计算方式取决于Intel处理器。在默认情况下,中间结果允许使用扩展的指数,但不允许使用扩展的尾数。(Intel芯片在截断尾数时并不损失性能)

因此,这两种方式的区别仅仅在于采用默认的方式不会产生溢出,而采用严格的计算有可能产生溢出。

如果你想让你的浮点运算更加精确,而且不会因为不同的硬件平台所执行的结果不一致的话,可以用关键字strictfp.

对大多数程序来说,浮点溢出不属于大问题。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值