Google Chrome 或 Node.js 中的 V8 toString(radix) 方法如何处理浮点数?
How does the V8 toString(radix) method in Google Chrome or in Node.js handle floating point numbers?
该方法对整数有效,例如
(25).toString(2)
= '11001'
(25).toString(16)
= '19'
(25).toString(36)
= 'p'
但是输入浮点数会导致
(0.1).toString(2)
= '0.0001100110011001100110011001100110011001100110011001101'
(0.1).toString(16)
= '0.1999999999999a'
(0.1).toString(36)
= '0.3lllllllllm'
据说 V8 是一个开源引擎。但是,我无法在存储库中找到此方法的确切实现以便理解它。函数如何处理浮点数?
(此处为 V8 开发人员。)
@pilchard 的 link 是对的;更具体地说,您要查找的函数是 DoubleToRadixCString.
观察到 0.1(十进制)是其二进制表示形式中的非终止分数(当然,这就是双精度数在计算机中的存储方式)很好地说明了 0.1 * 3 == 0.30000000000000004
的根本原因:非终止分数必然在某个点被截断,这构成了舍入误差,而某些操作使这些舍入误差可见。它是十进制中类似效果的二进制等价物:当您将 1/3 表示为“0.333333”时(任意选择 6 位数字作为表示的长度,但如果您仅在 100 位数字后切断,那不会真正改变任何东西),并且将其乘以 3,得到“0.999999”,而不是 1。
该方法对整数有效,例如
(25).toString(2)
= '11001'
(25).toString(16)
= '19'
(25).toString(36)
= 'p'
但是输入浮点数会导致
(0.1).toString(2)
= '0.0001100110011001100110011001100110011001100110011001101'
(0.1).toString(16)
= '0.1999999999999a'
(0.1).toString(36)
= '0.3lllllllllm'
据说 V8 是一个开源引擎。但是,我无法在存储库中找到此方法的确切实现以便理解它。函数如何处理浮点数?
(此处为 V8 开发人员。)
@pilchard 的 link 是对的;更具体地说,您要查找的函数是 DoubleToRadixCString.
观察到 0.1(十进制)是其二进制表示形式中的非终止分数(当然,这就是双精度数在计算机中的存储方式)很好地说明了 0.1 * 3 == 0.30000000000000004
的根本原因:非终止分数必然在某个点被截断,这构成了舍入误差,而某些操作使这些舍入误差可见。它是十进制中类似效果的二进制等价物:当您将 1/3 表示为“0.333333”时(任意选择 6 位数字作为表示的长度,但如果您仅在 100 位数字后切断,那不会真正改变任何东西),并且将其乘以 3,得到“0.999999”,而不是 1。