我已经查明了它的作用,但是有没有人真的有一个例子,你何时会strictfp
在Java中使用关键字?有没有人真的找到了这个用途?
将它放在我的所有浮点运算上是否会产生任何副作用?
Strictfp确保您在每个平台上获得与浮点计算完全相同的结果.如果不使用strictfp,则JVM实现可以在可用时自由使用额外的精度.
来自JLS:
在FP-strict表达式中,所有中间值必须是浮点值集或双值集的元素,这意味着所有FP严格表达式的结果必须是IEEE 754算法在使用单格式和双格式表示的操作数上预测的结果.在不是FP-strict的表达式中,为实现授予了一些余地,以使用扩展指数范围来表示中间结果; 粗略地说,净效应是在独占使用浮点值集或双值集可能导致上溢或下溢的情况下,计算可能会产生"正确答案".
换句话说,它是关于确保Write-Once-Run-Anywhere实际上意味着Write-Once-Get-Equally-Werong-Results-Everywhere.
使用strictfp,您的结果是可移植的,没有它,它们更可能是准确的.
维基百科实际上有关于这个话题的好文章在这里,并链接到Java规范.
读取行之间的含义是,如果您没有指定strictfp
,那么JVM和JIT编译器有许可计算您想要的浮点计算.为了速度,他们很可能会将计算委托给您的处理器.在strictfp
on,计算必须符合IEEE 754算术标准,实际上,这可能意味着JVM将进行计算.
那你为什么要用strictfp
呢?我可以看到的一个场景是在分布式应用程序(或多人游戏)中,无论底层硬件或CPU是什么,所有浮点计算都需要是确定性的.什么是权衡?最有可能是执行时间.
一切都始于一个故事,
当James由James Gosling,Herbert和他的团队的其他成员开发时.他们把这个疯狂的东西称为平台独立性.他们希望使橡木(Java)更好,以至于在具有不同指令集的任何机器上运行完全相同,甚至运行不同的操作系统.但是,小数点数也存在问题,在编程语言中也称为浮点数和双精度数.一些机器的目标是效率,而休息的目标是准确性.因此,后来的(更准确的)机器的浮点大小为80位,而前者(更有效/更快)的机器有64位双倍.但是,这是建立一种独立于平台的语言的核心理念.此外,当代码在某台机器上构建(具有64位大小的两倍)并在另一种机器(具有80位大小的两倍)上运行时,这可能会导致精度/数据丢失.
可以容忍Up-Sizing,但不能使用Down-Sizing.因此,他们遇到了strictfp即严格浮点的概念.如果将此关键字与类/函数一起使用,则其浮点和双精度在任何计算机上都具有一致的大小.即分别为32/64位.
以下是几个参考:
使用strictfp(JDC技术提示)
jGuru:strictfp修饰符是什么?我什么时候考虑使用它?
基本上,这一切归结为你是否关心你的代码中的浮点表达式的结果是快速的还是可预测的.例如,如果您需要您的代码提出的答案,使用浮点值在多个平台上保持一致,那么请使用
strictfp
.
strictfp - Java词汇表
浮点硬件的计算精度更高,并且具有比Java规范要求的更大范围的值.如果某些平台比其他平台更精确,那将会令人困惑.在
strictfp
方法或类上使用修饰符时,编译器会生成严格遵守Java规范的代码,以便在所有平台上获得相同的结果.没有strictfp
,它是否稍微宽松,但不是那么松懈,以至于使用Pentium中的保护位来提供80位精度.
最后是实际的Java语言规范,§15.4FP严格表达式:
在FP-strict表达式中,所有中间值必须是浮点值集或双值集的元素,这意味着所有FP严格表达式的结果必须是IEEE 754算法在使用单格式和双格式表示的操作数上预测的结果.在不是FP-strict的表达式中,为实现授予了一些余地,以使用扩展指数范围来表示中间结果; 粗略地说,净效应是在独占使用浮点值集或双值集可能导致上溢或下溢的情况下,计算可能会产生"正确答案".
不过,我从来没有亲自使用它.
正如其他答案所提到的那样,它会使中间浮点结果符合IEEE规范.特别是x86处理器可以存储IEEE规范中具有不同精度的中间结果.当JIT优化特定计算时,情况变得更加复杂; 每次指令可能不同的顺序导致略微不同的舍入.
由strictfp引起的开销可能非常依赖于处理器和JIT.这篇关于SSE2的维基百科文章似乎对这个问题有了一些了解.因此,如果JIT可以生成SSE指令来执行计算,那么strictfp似乎不会有任何开销.
在我目前的项目中有几个地方我使用strictfp.有一点需要从像素值中去除潜在的宇宙射线.如果一些外部研究人员在他们面前具有相同的像素值和宇宙射线,他们应该得到与我们的软件相同的结果值.
strictfp是一个修饰符,它根据IEEE 754限制浮点计算.
这可以在整个类上使用,如"public strictfp class StrictFpModifierExample {}"或方法"public strictfp void example()".如果它在类上使用,则所有方法都将遵循IEEE 754,如果在方法上使用,则特定方法将遵循IEEE 754.
为什么它被使用?:::由于不同的平台有不同的浮点硬件,它比java规范要求的更精确和更大的值范围计算,这可能会在不同的平板上产生不同的输出.因此它确认了相同的输出而不管不同plateforms
strictfp还确保利用扩展精度浮点运算的速度和精度.
我们在进行浮点计算时可以使用这个关键字没有缺点
我的最后一点是 - IEEE754简称IEEE 754定义了浮点计算和浮点值存储的标准方法,单个(32位,用于Java浮点数)或双(64位,用于Java)精度.它还定义了中间计算和扩展精度格式的规范.