我什么时候应该在 Java 中使用“strictfp”关键字?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/517915/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
When should I use the "strictfp" keyword in java?
提问by GBa
I've looked up what this does, but does anyone actually have an example of when you would use the strictfp
keyword in Java? Has anyone actually found a use for this?
我已经查过这是做什么的,但是有人真的有什么时候会strictfp
在 Java 中使用关键字的例子吗?有没有人真的找到了这个用途?
Would there be any side-effects of just putting it on all my floating point operations?
将它放在我所有的浮点运算上会有任何副作用吗?
采纳答案by Dan Dyer
Strictfp ensures that you get exactly the same results from your floating point calculations on every platform. If you don't use strictfp, the JVM implementation is free to use extra precision where available.
Strictfp 确保您从每个平台上的浮点计算中获得完全相同的结果。如果您不使用 strictfp,则 JVM 实现可以在可用的情况下自由使用额外的精度。
Within an FP-strict expression, all intermediate values must be elements of the float value set or the double value set, implying that the results of all FP-strict expressions must be those predicted by IEEE 754 arithmetic on operands represented using single and double formats. Within an expression that is not FP-strict, some leeway is granted for an implementation to use an extended exponent range to represent intermediate results; the net effect, roughly speaking, is that a calculation might produce "the correct answer" in situations where exclusive use of the float value set or double value set might result in overflow or underflow.
在 FP-strict 表达式中,所有中间值必须是 float 值集或 double 值集的元素,这意味着所有 FP-strict 表达式的结果必须是 IEEE 754 算术对使用单双格式表示的操作数预测的结果. 在非 FP 严格的表达式中,为实现使用扩展的指数范围来表示中间结果提供了一些余地;粗略地说,净效果是在独占使用浮点值集或双值集可能导致上溢或下溢的情况下,计算可能会产生“正确答案”。
In other words, it's about making sure that Write-Once-Run-Anywhereactually means Write-Once-Get-Equally-Wrong-Results-Everywhere.
换句话说,它是关于确保Write-Once-Run-Anywhere实际上意味着Write-Once-Get-Equally-Wrong-Results-Everywhere。
With strictfp your results are portable, without it they are more likely to be accurate.
使用 strictfp,您的结果是可移植的,没有它,它们更有可能是准确的。
回答by MattK
Wikipedia actually has a good article about this topic here, with a link to the Java specification.
维基百科实际上有一篇关于这个主题的好文章here,带有指向 Java 规范的链接。
Reading between the lines, the implication is that if you don't specify strictfp
, then the JVM and JIT compiler have license to compute your floating-point calculations however they want. In the interest of speed, they will most likely delegate the computation to your processor. With strictfp
on, the computations have to conform to IEEE 754 arithmetic standards, which, in practice, probably means that the JVM will do the computation.
从字里行间看,这意味着如果您不指定strictfp
,则 JVM 和 JIT 编译器将获得许可,可以根据需要计算浮点计算。为了速度,他们很可能会将计算委托给您的处理器。随着strictfp
上的计算必须符合IEEE 754算法标准,在实践中,可能意味着JVM会做计算。
So why would you want to use strictfp
? One scenario I can see is in a distributed application (or multiplayer game) where all floating-point calculations need to be deterministic no matter what the underlying hardware or CPU is. What's the trade-off? Most likely execution time.
那么你为什么要使用strictfp
?我可以看到的一种情况是在分布式应用程序(或多人游戏)中,无论底层硬件或 CPU 是什么,所有浮点计算都需要确定性。什么是权衡?最有可能的执行时间。
回答by Michael Myers
Here are several references:
这里有几个参考:
- Using strictfp(JDC Tech Tip)
jGuru: What is the strictfp modifier for? When would I consider using it?
Basically, what it all boils down to is whether or not you care that the results of floating-point expressions in your code are fast or predictable. For example, if you need the answers that your code comes up with which uses floating-point values to be consistent across multiple platforms then use
strictfp
.Floating point hardware calculates with more precision, and with a greater range of values than the Java specification requires. It would be confusing if some platforms gave more precision than others. When you use the
strictfp
modifier on a method or class, the compiler generates code that adheres strictly to the Java spec for identical results on all platforms. Withoutstrictfp
, is it is slightly laxer, but not so lax as to use the guard bits in the Pentium to give 80 bits of precision.And finally the actual Java Language Specification, §15.4 FP-strict Expressions:
Within an FP-strict expression, all intermediate values must be elements of the float value set or the double value set, implying that the results of all FP-strict expressions must be those predicted by IEEE 754 arithmetic on operands represented using single and double formats. Within an expression that is not FP-strict, some leeway is granted for an implementation to use an extended exponent range to represent intermediate results; the net effect, roughly speaking, is that a calculation might produce "the correct answer" in situations where exclusive use of the float value set or double value set might result in overflow or underflow.
- 使用 strictfp(JDC 技术提示)
jGuru:strictfp 修饰符是做什么用的?我什么时候会考虑使用它?
基本上,归根结底是您是否关心代码中浮点表达式的结果是快速的还是可预测的。例如,如果您需要代码提出的使用浮点值在多个平台上保持一致的答案,请使用
strictfp
.浮点硬件的计算精度更高,并且值的范围比 Java 规范要求的范围更大。如果某些平台比其他平台提供的精度更高,那将会令人困惑。当您
strictfp
在方法或类上使用修饰符时,编译器会生成严格遵守 Java 规范的代码,以便在所有平台上获得相同的结果。如果没有strictfp
,它是否会稍微宽松一些,但不会宽松到使用 Pentium 中的保护位来提供 80 位精度。最后是实际的 Java 语言规范,§15.4 FP-strict Expressions:
在 FP-strict 表达式中,所有中间值必须是 float 值集或 double 值集的元素,这意味着所有 FP-strict 表达式的结果必须是 IEEE 754 算术对使用单双格式表示的操作数预测的结果. 在非 FP 严格的表达式中,为实现使用扩展的指数范围来表示中间结果提供了一些余地;粗略地说,净效果是在独占使用浮点值集或双值集可能导致上溢或下溢的情况下,计算可能会产生“正确答案”。
I've never personally had a use for it, though.
不过,我个人从未使用过它。
回答by Sean McCauliff
As the other answers mentioned it cause the intermediate floating point results to conform to the IEEE specification. In particular x86 processors can store intermediate results with different precision from the IEEE spec. The situation gets more complicated when the JIT optimizes a particular computation; the order the instructions could be different each time resulting in slightly different rounding.
正如其他答案所提到的,它导致中间浮点结果符合 IEEE 规范。特别是 x86 处理器可以存储与 IEEE 规范不同精度的中间结果。当 JIT 优化特定计算时,情况会变得更加复杂;每次指令的顺序可能不同,导致四舍五入略有不同。
The overhead incurred by strictfp likely to be very processor and JIT dependent. This wikipedia article on SSE2seems to have some insight into the problem. So if the JIT can generate SSE instructions to perform a calculation it seems that strictfp will not have any overhead.
strictfp 产生的开销可能非常依赖于处理器和 JIT。这篇关于SSE2 的维基百科文章似乎对这个问题有一些了解。因此,如果 JIT 可以生成 SSE 指令来执行计算,那么 strictfp 似乎不会有任何开销。
In my current project there are a few places where I use strictfp. There is a point where potential cosmic rays need to be removed from pixel values. If some outside researcher has the the same pixel value and cosmic ray in front them they should get the same resulting value as our software.
在我当前的项目中,有几个地方使用了 strictfp。有一点需要从像素值中去除潜在的宇宙射线。如果一些外部研究人员在他们面前有相同的像素值和宇宙射线,他们应该得到与我们的软件相同的结果值。
回答by Rahul Saxena
strictfp is a modifier which restricts floating point calculations as per IEEE 754.
This can be used on whole class like "public strictfp class StrictFpModifierExample{}" or on method "public strictfp void example()".If it is used on class than all methods will follow IEEE 754 and if used on method then particular method will follow IEEE 754.
Why it is used??::: As different platforms have different floating point hardware which calculates with more precision and greater range of values than the java specification requires which may produce diffrent output on diffrent plateforms.so it confirms the same output irrespective of diffrent plateforms
strictfp also ensures to take advantage of the speed and precision of the extended precision floating-point operations.
There is no disadvantage with this keyword we can use when we are doing floating point calculations
My last point is --What is IEEE754 in short IEEE 754 defines standard method for both floating point calculations and storage of floating point values in either single (32-bit, used in Java floats) or double (64-bit, used in Java doubles) precision.It also defines norms for intermediate calculations and for extended precision formats.
strictfp 是一个修饰符,它根据 IEEE 754 限制浮点计算。
这可以用于整个类,如“public strictfp class StrictFpModifierExample{}”或方法“public strictfp void example()”。如果在类上使用它,则所有方法都将遵循 IEEE 754,如果在方法上使用,则特定方法将遵循 IEEE 754。
为什么使用它??::: 因为不同的平台有不同的浮点硬件,它的计算精度和值范围比 java 规范要求的更高,这可能会在不同的平台上产生不同的输出。所以它确认相同的输出,而不管不同平板
strictfp 还确保利用扩展精度浮点运算的速度和精度。
我们在进行浮点计算时可以使用这个关键字没有任何缺点
我的最后一点是 - IEEE754 简称 IEEE 754 定义了浮点计算和浮点值存储的标准方法,无论是单(32 位,在 Java 浮点数中使用)还是双(64 位,在 Java 中使用) doubles) 精度。它还定义了中间计算和扩展精度格式的规范。
回答by Shanaka Jayalath
strictfp
is a keyword and can be used as a non Non-access modifier for classes or a methods (but never variables). Marking a class as strictfp
means that any method code in the class will conform to the IEEE 754 standard rules for floating points.
strictfp
是一个关键字,可以用作类或方法(但绝不是变量)的非非访问修饰符。将类标记为strictfp
意味着该类中的任何方法代码都将符合 IEEE 754 浮点标准规则。
Without that modifier, floating points used in the methods might behave in a platform-dependent way. With it you can predict how your floating points will behave regardless of the underlying platform the JVM is running on. The downside is that if the underlying platform is capable of supporting greater precision, a strictfp
method won't be able to take advantage of it.
如果没有该修饰符,方法中使用的浮点数可能会以平台相关的方式运行。有了它,您可以预测浮点的行为方式,而不管 JVM 运行的底层平台如何。缺点是如果底层平台能够支持更高的精度,则strictfp
方法将无法利用它。
If you don't declare a class as strictfp
, you can still get strictfp
behavior on a method-by-method basis, by declaring a method as strictfp
.
如果您不将类声明为strictfp
,您仍然可以strictfp
通过将方法声明为 来逐个方法地获取行为strictfp
。
~ SCJP Sun?Certified Programmer for Java? 6 - Kathy Sierra & Bert Bates ~
~ SCJP Sun?Java 认证程序员?6 - 凯西塞拉和伯特贝茨 ~
回答by AbhimanyuAryan
It all began with a story,
一切都始于一个故事,
When java was being developed by James Gosling, Herbert and rest of his team. They had this crazy thing in mind called platform independency. They wanted to make oak(Java)so much better that it would run exactly same on any machine having different instruction set, even running different operating systems. But, there was a problem with decimal point numbers also known as floating point and double in programming languages. Some machines were built targeting efficiency while rest were targeting accuracy. So, the later(more accurate) machines had size of floating point as 80 bits while the former(more efficient/faster) machines had 64 bit doubles. But, this was against there core idea of building a platform independent language. Also, this might lead to loss of precision/data when a code is built on some machine(having double of 64 bit size) and run on another kind of machine(having double of 80 bit size).
当 James Gosling、Herbert 和他的团队的其他成员正在开发 Java 时。他们想到了一种叫做平台独立性的疯狂事情。他们想制作橡木(爪哇)好多了,它可以在任何具有不同指令集的机器上完全相同地运行,甚至运行不同的操作系统。但是,小数点数在编程语言中也称为浮点数和双精度数存在问题。一些机器建立了瞄准效率,而其他机器则是瞄准精度。因此,较晚(更准确)的机器的浮点大小为 80 位,而前者(更高效/更快)的机器有 64 位双精度数。但是,这与构建平台独立语言的核心思想背道而驰。此外,当代码在某些机器上构建(具有 64 位大小的两倍)并在另一种机器(具有 80 位大小的两倍)上运行时,这可能会导致精度/数据丢失。
Up-Sizing can be tolerated but Down-Sizing can't be. So, they came across a concept of strictfp i.e. strict floating point. If you use this keyword with a class/function then its floating point and doubles have a consistent size over any machine. i.e. 32/64 -bit respectively.
可以容忍扩大规模,但不能容忍缩小规模。因此,他们遇到了 strictfp 的概念,即严格浮点数。如果将此关键字与类/函数一起使用,则其浮点数和双精度数在任何机器上都具有一致的大小。即分别为 32/64 位。
回答by Neeraj
May below example help in understanding this more clear : In java whenever we are using looking for precise information for any operation e.g. if we do double num1 = 10e+102; double num2 = 8e+10 ; result = num1+ num2;
下面的示例可能有助于更清楚地理解这一点:在 java 中,每当我们为任何操作寻找精确信息时,例如,如果我们执行 double num1 = 10e+102; 双 num2 = 8e+10 ; 结果 = num1+ num2;
The output will be so long and not precise, becasue it is precissed by the hardware e.g JVM and JIT has the license
as long as we dont have specify it Strictfp
Marking it Strictfp will make the result Uniform on every hardware and platform, because its precised value will be same
One scenario I can see is in a distributed application (or multiplayer game) where all floating-point calculations need to
be deterministic no matter what the underlying hardware or CPU is.
回答by Hari Krishna
'strictfp' keyword is used to force the precision of floating point calculations (float or double) in Java conform to IEEE's 754 standard, explicitly. If you do not use strictfp keyword, the floating point precision depends on target platform's hardware.
'strictfp' 关键字用于强制 Java 中浮点计算(float 或 double)的精度明确符合 IEEE 754 标准。如果不使用strictfp 关键字,浮点精度取决于目标平台的硬件。
If an interface or class is declared with strictfp, then all methods and nested types within that interface or class are implicitly strictfp.
如果接口或类是用 strictfp 声明的,那么该接口或类中的所有方法和嵌套类型都是隐式的 strictfp。
Reference link
参考链接