ActionScript:Number.toExponential返回某些值的错误结果

时间:2015-06-26 11:15:38

标签: actionscript-3 floating-point

我发现至少有两个数字,其中ActionScript的Number.toExponential(20)返回的结果不正确。

最明显的值是0。

trace(Number(0).toExponential(20)); // 0.00000000000000000000e-16
trace(Number(0).toExponential(2));  // 0.00e-16
trace(Number(0).toExponential(1));  // 0.0e-16
trace(Number(0).toExponential(0));  // 1e-15 - even worse!

我已经制作了一个Double类用于使用Numbers(IEEE 754双精度二进制浮点格式数字)。它需要一个数字并将所有位提取为符号,位和有效位数(后者打印包括隐式前导位),或者可以生成数字提供的符号,位和有效位数。有一些方法可以获得下一个和前一个最接近的可表示数字。 这是0在内部看起来像:

[Double number=0.00000000000000000000e-16 sign=1 exponent=-1023 isZero
significand=00000000000000000000000000000000000000000000000000000]

其他不正确的结果是最接近的可表示的数字大于Number.MAX_VALUE / 2和Number.MAX_VALUE / 4.

// Number.MAX_VALUE / 2.
trace(Number(8.98846567431157854072e+307).toExponential(20)); // 8.98846567431157854072e+307
// Nearest representable Number greater than Number.MAX_VALUE / 2. Printed incorrectly!
trace(Number(8.98846567431157953864e+307).toExponential(20)); // 0.e+327
// A Number two ULPs greater than Number.MAX_VALUE / 2.
trace(Number(8.98846567431158153448e+307).toExponential(20)); // 8.98846567431158153448e+307
// Nearest representable Number greater than Number.MAX_VALUE / 4. Printed incorrectly!
trace(Number(4.49423283715578976932e+307).toExponential(20)); // 0.e+327

以下是这四个数字在内部的样子:

[Double number=8.98846567431157854072e+307 sign=1 exponent=1022 
significand=11111111111111111111111111111111111111111111111111111]
[Double number=0.e+327 sign=1 exponent=1023 
significand=10000000000000000000000000000000000000000000000000000]
[Double number=8.98846567431158153448e+307 sign=1 exponent=1023 
significand=10000000000000000000000000000000000000000000000000001]
[Double number=0.e+327 sign=1 exponent=1022 
significand=10000000000000000000000000000000000000000000000000000]

到目前为止,所有三个错误打印的数字都有0个有效数字(隐含前导1),指数值1023(正常数字的Emax),1022(Emax - 1)或-1023(特殊指数值)对于±0和次正规数,Emin - 1)。

看起来toExponent至少没有正确处理这三种情况 。是否有其他数字打印不正确?

尝试检查toExponential是否会产生其他精度值的正确结果。

trace(Number(8.98846567431157953864e+307).toExponential(2)); // 0.e+309
trace(Number(8.98846567431157953864e+307).toExponential(1)); // 0.e+308
trace(Number(8.98846567431157953864e+307).toExponential(0)); // 1e+308 - less bad!

如果有人对我的Double课程感兴趣,我会发布它。我还编写了更快的实现next(x:Number)和previous(x:Number)函数,它们工作得非常快,而且不会弄乱数字的内部位。

参考文献: TeamCity REST API

0 个答案:

没有答案