JDK-8135000 : Number.prototype.toFixed returns wrong string for 0.5 and -0.5
  • Type: Bug
  • Component: core-libs
  • Sub-Component: jdk.nashorn
  • Affected Version: 9
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • OS: generic
  • CPU: generic
  • Submitted: 2015-09-03
  • Updated: 2016-01-14
  • Resolved: 2015-09-10
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 8 JDK 9
8u72Fixed 9 b82Fixed
Description
This bug was reported via nashorn-dev http://mail.openjdk.java.net/pipermail/nashorn-dev/2015-September/005142.html

Email content below for reference:

The implementation of Number.prototype.toFixed seems to be wrong in
two cases. Can you confirm this, and/or report it on an issue tracker?

Observed behaviour:

> $ jjs -version
> nashorn 1.8.0_60
> jjs> 0.5.toFixed()
> 0
> jjs> -0.5.toFixed()
> 0

Expected behaviour:

The two results should be 1 and -1 respectively.

I expect this behaviour because that is how I interpret ES5 and ES6
specifications for Number.prototype.toFixed, and because that is the
behaviour that I can observe in Chrome and Firefox.



Extra comments on possible cause of bug:

The interesting part of the ES6 specification is

20.1.3.3 - 10. - a.:

> Let n be an integer for which the exact mathematical value of n /
  10^f ��� x is as close to zero as possible. If there are two such n,
  pick the larger n.

In the case of `0.5.toFixed()` the expression above becomes:

> n / 10^0 - 0.5 = n / 1 - 0.5 = n - 0.5

which solves to `n = 0` or `n = 1`.  It seems that Nashorn picks the
`n = 0` case instead of the `n = 1` case.



---
Esben Andreasen

-------------------

His interpretation seems right.

See spec. section:

https://es5.github.io/#x15.7.4.5

Step 8 Else, x < 1021

    Let n be an integer for which the exact mathematical value of n �� 10f ��� x is as close to zero as possible. If there are two such n, pick the larger n. 

Comments
Quick check: This diff seems to take care of the reported issue and pass tests. $ hg diff diff -r 352a446e3a13 src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeNumber.java --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeNumber.java Wed Sep 02 22:28:31 2015 +0530 +++ b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeNumber.java Thu Sep 03 09:44:00 2015 +0530 @@ -33,6 +33,7 @@ import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodType; +import java.math.RoundingMode; import java.text.NumberFormat; import java.util.Locale; import jdk.internal.dynalink.linker.GuardedInvocation; @@ -186,6 +187,7 @@ final NumberFormat format = NumberFormat.getNumberInstance(Locale.US); format.setMinimumFractionDigits(fractionDigits); format.setMaximumFractionDigits(fractionDigits); + format.setRoundingMode(RoundingMode.HALF_UP); format.setGroupingUsed(false); return format.format(x);
03-09-2015