Post by David P. CaldwellWell, I'm not an expert on floating-point standards and all of that.
It may be that no other decision is possible, but I think I can predict this will confuse people.
That is often unavoidable when floating-point is involved ;-)
Post by David P. CaldwellI think I'd argue for the edge case -- where the actual number being processed is the closest value to the half-way point -- to be processed as though the value actually *were* at the half-way point. (Maybe that's the way it worked before?)
Thanks so much for pointing me to the issue report so that I understand what's happening.
A short explanation: floating-point numbers are fundamentally discrete
values. Since Java uses IEEE 754 double values, the representable
floating-point numbers are sums of powers of two. Consequently, many
interesting decimal fractions cannot be exactly represented.
A finite floating-point number represents some particular point on the
real number line, say x. Under the round to nearest even rounding mode,
a range of the real number line, some values less than x and some values
greater than x, get rounded to x. Once you have x, you don't have any
history about where x came from, maybe it was exactly computed, maybe
the exact result before roundoff was greater than x, maybe it was less than.
The most reasonable thing to do is to assume the value you have now is
exact for the purposes of future computation and carry on. Therefore,
once "85.55" is converted to a double value, the fact that is came from
"85.55" is lost. Now it is some numerical value slightly less than 85.55
and should be treated accordingly.
For exact computation on decimal quantities, BigDecimal should be used
instead of double.
For some more general information about floating-point see:
"What Every Computer Programmer Should Know about Floating-Point
Arithmetic"
https://blogs.oracle.com/darcy/resource/Wecpskafpa-ACCU.pdf
Cheers,
-Joe
Post by David P. Caldwell-- David.
Post by Joe DarcyHello,
JDK-7131459 [Fmt-De] DecimalFormat produces wrong format() results when close to a tie
https://bugs.openjdk.java.net/browse/JDK-7131459
The new result is actually numerically correct since the text string "85.55" does not get converted to a double value actually equal to 85.55 it is converted to a value slightly less than 85.55.
HTH,
-Joe
Post by David P. CaldwellHere's a bug report for b129. Mac OS X 10.8.5, although I doubt this is platform-dependent.
DecimalFormatTest.java
public class DecimalFormatTest {
public static void main(String[] args) {
System.out.println("java.version: " + System.getProperty("java.version"));
System.out.println("85.55 rounded to one digit: " + new java.text.DecimalFormat("##.#").format(85.55));
}
}
DecimalFormatTest.sh
#!/bin/bash
javac -source 1.6 -target 1.6 $(dirname $0)/DecimalFormatTest.java
/System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home/bin/java DecimalFormatTest
/Library/Java/JavaVirtualMachines/jdk1.7.0_25.jdk/Contents/Home/bin/java DecimalFormatTest
/Library/Java/JavaVirtualMachines/jdk1.7.0_45.jdk/Contents/Home/bin/java DecimalFormatTest
/Library/Java/JavaVirtualMachines/jdk1.8.0.jdk/Contents/Home/bin/java DecimalFormatTest
/Library/Java/JavaVirtualMachines/jdk1.8.0.jdk/Contents/Home/bin/java -version
uname -a
$ ./DecimalFormatTest.sh
warning: [options] bootstrap class path not set in conjunction with -source 1.6
1 warning
java.version: 1.6.0_65
85.55 rounded to one digit: 85.6
java.version: 1.7.0_25
85.55 rounded to one digit: 85.6
java.version: 1.7.0_45
85.55 rounded to one digit: 85.6
java.version: 1.8.0
85.55 rounded to one digit: 85.5
java version "1.8.0"
Java(TM) SE Runtime Environment (build 1.8.0-b129)
Java HotSpot(TM) 64-Bit Server VM (build 25.0-b69, mixed mode)
Darwin mabosdcaldwell-m1.corp.local 12.5.0 Darwin Kernel Version 12.5.0: Sun Sep 29 13:33:47 PDT 2013; root:xnu-2050.48.12~1/RELEASE_X86_64 x86_64
The DecimalFormat specification says it should use HALF_EVEN as the rounding mode. The getRoundingMode() method for the DecimalFormat (examined in debugger) does in fact return HALF_EVEN, but the output is incorrect.
-- David P. Caldwell
http://www.davidpcaldwell.com/
Post by Mathias AxelssonHi,
I'd like to give you an update on the below. We've promoted b128 and this
is the first release candidate build of JDK 8. b128 is available on
java.net [1] so you can download it and try it out.
I'll continue to monitor incoming bugs. If a showstopper bug shows up that
is deemed critical for the JDK 8 release then we'll have to create a new
build to include it.
Kind regards,
Mathias Axelsson, Oracle JDK Release Manager
[1] https://jdk8.java.net/download.html
Post by Mathias AxelssonHi,
It's been a while since my last update so I wanted to give you an update on
where we are.
Focus has been on getting the final RI (Reference Implementation) build for
the Java SE 8 specification completed and ready. The current RI build is
b126 [1] and unless any TCK blockers shows up, this build will be the RI
for Java SE 8.
With the RI build in place focus has now shifted to get the remaining
showstopper fixes for JDK 8 into the master. We had a number of fixes lined
up and got them integrated earlier this week so that we could do a new
promoted build (b127). This build will be posted on java.net [2] shortly.
b127 is not a release candidate build as there are still a few critical
issues that must be fixed and integrated. I'm following up on the bugs on a
daily basis and hope we can cut the first release candidate of JDK 8
shortly.
I will send out an update once we have a release candidate build of JDK 8.
Kind regards,
Mathias Axelsson, Oracle JDK 8 Release Manager
[1] https://jdk8.java.net/java-se-8-ri/
[2] https://jdk8.java.net/download.html