The result of (0).toExponential(1)
On H.24/03/08, at 12:39, DX Jin <dox.jin at gmail.com> wrote:
(0).toExponential(1) should, according to the algorithm in 15.7.4.6, return "0e+0".
But all browser implementations return "0.0e+0" instead.
Which is wrong? The specification or the implementations?
Neither, the result is correct. The number is the same, just different representations as strings.
I don't think so.
ES5 specified the algorithm of toExponential. ¡°The number is the same¡± is not the only requirement.
See the algorithm below: ( please pay attention to 8.a )
Let x be this Number value es5.github.com/#this-Number-value. 2.
Let f be ToInteger es5.github.com/#x9.4(fractionDigits). 3.
If x is NaN, return the String "NaN". 4.
Let s be the empty String. 5.
If x < 0, then 1.
Let *s* be *"-"*.
2.
Let *x* = ¨C*x*.
6.
If x = +¡Þ, then 1.
Return the concatenation of the Strings *s* and *"Infinity"*.
7.
If fractionDigits is not undefined and (f < 0 or f > 20), throw a RangeError es5.github.com/#x15.11.6.2 exception. 8.
If x = 0, then 1.
*Let f = 0.*
2.
Let *m* be the String consisting of *f*+1 occurrences of the
character ¡®0¡¯.
3.
Let *e* = 0.
9.
Else, x ¡Ù 0 1.
If fractionDigits is not *undefined*, then
1.
Let *e* and *n* be integers such that 10*f* ¡Ü *n* < 10*f*+1 and
for which the exact mathematical value of *n* ¡Á 10*e*¨C*f* ¨C *x* is
as close to zero as possible. If there are two such sets of *e*
and *n*, pick the *e* and *n* for which *n* ¡Á 10*e*¨C*f* is larger.
2.
Else, *fractionDigits* is *undefined*
1.
Let *e*, *n*, and *f* be integers such that *f* ¡Ý 0, 10*f* ¡Ü *n* <
10*f*+1, the number value for n¡Á 10*e*¨C*f* is *x*, and *f* is as
small as possible. Note that the decimal representation of*n* has *
f*+1 digits, *n* is not divisible by 10, and the least significant
digit of *n* is not necessarily uniquely determined by these
criteria.
3.
Let *m* be the String consisting of the digits of the decimal
representation of *n* (in order, with no leading zeroes).
10.
If f ¡Ù 0, then 1.
Let *a* be the first character of *m*, and let *b* be the remaining *f
* characters of *m*.
2.
Let *m* be the concatenation of the three Strings *a*, *"."*, and *b*.
11.
If e = 0, then 1.
Let *c* = *"+".*
2.
Let *d* = *"0".*
12.
Else 1.
If *e* > 0, then let *c* = *"+".*
2.
Else, *e* ¡Ü 0
1.
Let *c* = *"-"*.
2.
Let *e* = ¨C*e*.
3.
Let *d* be the String consisting of the digits of the decimal
representation of *e* (in order, with no leading zeroes).
13.
Let m be the concatenation of the four Strings m, "e", c, and d . 14.
Return the concatenation of the Strings s and m.
According to this algorithm, (0).toExponential(1) should return "0e+0".(f is set to 0)
But it looks none of V8, spidermonkey and JScript did that thing. Their result is "0.0e+0".
So is there anyone could give some message about why does ES5 define this behavior like this? Or is it simply a spec bug?
2012/3/8 Jens Nockert <jens at nockert.se>
Later, I saw the ES5 draft history[1], Step 15 in the previous version of the "Sunnyvale"( 23 Feb 2009 ) and step 8.a in the "Sunnyvale"( 02 March 2009 ) are the same intention. Step 15 in the previous version of the "Sunnyvale" is only execute if this number value is 0 and fractionDigits is undefined, But step 8.a in "Sunnyvale" is also execute if fractionDigits is not undefined.
so step 8.a should be "a. if fractionDigits is undefined, then let f = 0.".
[1] es3.1:es3.1_proposal_working_draft
在 2012年3月8日 下午10:34,程劭非 <csf178 at gmail.com>写道:
(12/03/10 17:33), DX Jin wrote:
Later, I saw the ES5 draft history[1], Step 15 in the previous version of the "Sunnyvale"( 23 Feb 2009 ) and step 8.a in the "Sunnyvale"( 02 March 2009 ) are the same intention. Step 15 in the previous version of the "Sunnyvale" is only execute if this number value is 0 and fractionDigits is undefined,
Namely, Step 15 was skipped as Step 11 says
# If x = 0, go to step16.
But step 8.a in "Sunnyvale" is also execute if fractionDigits is not undefined.
so step 8.a should be "a. if fractionDigits is undefined, then let f = 0.".
This is probably an error introduced by the refactoring of this section which happended in between these versions (23 Feb 2009 - 02 March 2009)
(0).toExponential(1) should, according to the algorithm in 15.7.4.6, return "0e+0".
But all browser implementations return "0.0e+0" instead.
Which is wrong? The specification or the implementations?