EVALUATION
Re-opening bug.
Changing the new Double("0.0") to a new Double("1.0") or anything else but
0.0 works fine. It appears we may have a hole for 0.0 case. See Workaround
from customer...
###@###.### 2002-06-13
Without running the attached test case, it sounds as if the C or Delphi dll is changing the floating-point unit's control word from traps disabled to (at least) trap on divide by zero. Java semantics require the former settings; other langauges require different settings, such as terminating on overflow or divide by zero. However, I would assume well-hehaved dll's *should* restore the floating-point settings of their callers.
Executing 1.0/zero in Java is perfectly legal and well defined; moreover is it explicitly forbidden from throwing any sort of floating-point exception. If the FPU's control word has been modified, changing the DecimalFormat code to test the sign bit by converting to integer and masking only hides the problem since any subsequent divide by zero would trigger a program-terminating trap.
Will investigate.
###@###.### 2002-06-13
Preliminary investigations reveal that Delphi does support changing the fpu's control word so the scenario outlined above is certainly possible. If the Delphi dll is alterning the control word and not changing it back, the bug to be fixed is in the Delphi dll.
###@###.### 2002-06-13
Confirmed previous suspicions: loading the Delphi dll changes the fpu's trapping status to trap on certain floating-point events (overflow, divide by zero, underflow) which are defined to not trap by Java. I modified the standalone test to perform some floating-point operations before and after the delphi call; the first set of operations caused a trap to occur, impliciating the loading process. (The call to DecimalFormat is not relevant or necessary to the trapping behavior.)
This behavior is not so surprising since Delphi by default runs with floating-point traps enabled (see O'Reily's "Delphi in a Nutshell" p. 9). Well-written programs and dll's should restore the floating-point trapping status of their caller on exit, not propagate local changes to other parties.
The customer has a few options:
1. Fix the Delphi code
A Delphi program can explicitly save and restore the floating-point fpu state; the customer's program could properly shield the Java code from the unwanted fpu changes. See the Delphi documentation for the Set8087CW method.
It is *not* resonable to place the onus of maintaining the proper fpu control state for cross-language calls on the jvm; the Delphi code is using non-default behavior.
2. Don't use Delphi for computations.
From the description section, it sound as if the functionality the customer needs is basically provided by java.lang.Math.floor.
intPortion(double x) {
if(x >= 0)
return(Math.floor(x);
else
return -Math.floor(-x);
}
The fractional portion of x is (x - intPortion(x)).
The floor function is also found in the C math library.
Closing as not a bug.
###@###.### 2002-06-14

2002-06-14

WORK AROUND
You can patch the DecimalFormat-Class by detecting the sign
bit without Division by zero.
boolean isNegative = (number < 0.0) ||
(number == 0.0 && (Double.doubleToLongBits(number)
& 0x8000000000000000L) != 0L);
if (isNegative) number = -number;
Btw: Isn't this version not better for detecting the sign-
bit ?
(Review ID: 143369)
No, dividing zero into one is the only floating-point operation that can easily distinguish the sign of zero; this is perfectly legal and well-defined in Java.
###@###.### 2002-06-13