strictfp - does it actually make a difference?

T

tzvika.barenholz

Hi all

I've been puzzled by the strictfp modifier. according to JLS , unless
it is specified, the JVM *may* use more precision for intermediate
calculations. For example running the following:

public class StrictFpExample {
public static void main(String[] args) {
double x =3.e-300;
double y= x*x/x;
System.out.println(x);
System.out.println(y);
}

}


should resyult in y being 3e-300, not 0.
unfortunately, testing this both with and without strictfp, you get y=0
anyway.
I imagine if they put it in, there should be a difference.

any idea? can anyone come up with en example that shows a difference?

p.s. this is on 1.5.02

thx
Tzvika
 
R

Roland

Hi all

I've been puzzled by the strictfp modifier. according to JLS , unless
it is specified, the JVM *may* use more precision for intermediate
calculations. For example running the following:

public class StrictFpExample {
public static void main(String[] args) {
double x =3.e-300;
double y= x*x/x;
System.out.println(x);
System.out.println(y);
}

}


should resyult in y being 3e-300, not 0.
unfortunately, testing this both with and without strictfp, you get y=0
anyway.
I imagine if they put it in, there should be a difference.

any idea? can anyone come up with en example that shows a difference?

p.s. this is on 1.5.02

thx
Tzvika

It can make a difference, for example when --without strictfp-- the
hotspot compiler decides to optimize floating point expressions.

Here's an example, modified example from
<http://java.sun.com/developer/JDCTechTips/2001/tt0410.html#using>

Without strictfp modifier, the hotspot compiler may optimize the expression
4.0 * d * 0.5
of the method calc(double).

So after calling the calc method a few dozen times, the value printed is
the same as 2.0 * d.

Using strictfp however, calc(d) always returns Infinity (because 4.0 * d
causes 'overflow').


public
//strictfp
class FpDemo3 {

private static double calc(double d) {
return 4.0 * d * 0.5;
}

public static void main(String[] args) {
final int MAX_ITERS = 100000000;
double d = 8e+307;
System.out.println(4.0 * d * 0.5);
System.out.println(2.0 * d);

System.out.println("Before loop");
System.out.println("Calling calc(d): " + calc(d));

System.out.println("Repeating call to calc(d) "
+ MAX_ITERS + " times");
double value = 0.0;
for (int i = 0; i < MAX_ITERS; i++) {
value = calc(d);
}
System.out.println("After loop");
System.out.println("Last value in loop: " + value);
System.out.println("Calling calc(d): " + calc(d));

}
}

--
Regards,

Roland de Ruiter
___ ___
/__/ w_/ /__/
/ \ /_/ / \
 
J

John McGrath

public class StrictFpExample {
public static void main(String[] args) {
double x =3.e-300;
double y= x*x/x;
System.out.println(x);
System.out.println(y);
}

}

should resyult in y being 3e-300, not 0.

Java evaluates expressions left to right, so you have:

y = ( 3e-300 * 3e-300 ) / 3e-300;
y = ( 9e-600 ) / 3e-300;

Since 9e-600 is too small to be represented in a double, it is equivalent
to 0.

y = ( 0 ) / 3e-300;
y = 0;
I imagine if they put it in, there should be a difference.

any idea?

There may be a difference, but it is not required. If the code is
not marked as strictfp, then the JVM is not *required* to round off
intermediate values to IEEE floating point values. That is not the
same thing as being required not to do so.
can anyone come up with en example that shows a difference?

An example that is found to show a difference on one machine would not
necessarily show a difference on another machine.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top