如何实现 parseFloat

How to implement parseFloat

想知道如何实现 parseFloat 的低级实现,例如它在 JavaScript 中的工作方式。

我见过的所有类型转换的例子都在某些时候诉诸于使用它,例如 this, this, or this. On the other hand, there is this file which is quite large (from here).

想知道这只是一个非常复杂的函数还是有一个简单的实现。想知道如果它太复杂的话它是如何工作的。

也许this更接近

parseFloat基础数学很简单,小学算术就可以了。如果我们有一个十进制数字,我们可以通过以下方式轻松地将其转换为二进制:

  • 将整数部分除以二。余数(零或一)变成我们正在构建的二进制数字中的一个位。商代替整数部分,我们重复直到整数部分为零。例如,从 13 开始,我们除以得到商 6 和余数 1。然后我们除以 6 得到商 3 和余数 0。然后是 1 和 1,然后是 0 和 1,我们是完毕。我们产生的位,倒序是1101,也就是13的二进制数。
  • 将小整数部分乘以二。整数部分成为二进制数字中的另一位。重复次整数部分,直到它为零或者我们有足够的位来确定结果。例如,对于 .1875,我们乘以 2 得到 .375,其整数部分为 0。再次加倍产生 .75,其整数部分也为 0。接下来我们得到 1.5,其整数部分为1. 现在,当小整数部分 .5 加倍时,我们得到小整数部分为 0 的 1。新位为 .0011.

要确定一个浮点数,我们需要尽可能多的位数(从二进制数字的前导 1 位开始),并且为了四舍五入,我们需要知道下一位和之后的任何位是否非零。 (额外位的信息告诉我们源值和尾数中适合的位的差值是否为零,不是零而是小于适合的最低位的1/2,恰好是最低位的1/2 , 或超过最低位的 1/2。这些信息足以决定在任何常用的舍入模式中是向上舍入还是向下舍入。)

以上信息告诉您在算法的第二部分何时停止乘法。一旦您拥有所有有效位,再加上一位,再加上您有一个非零位或子整数部分为零,您就拥有了所需的所有信息,可以停止了。

然后根据您使用的任何舍入规则(通常舍入到最近的关系到偶数)通过舍入位来构造一个浮点值,将这些位放入浮点数的有效数字中点对象,设置指数记录二进制数首位的位置。

有一些用于检查溢出或下溢或处理次正常值的修饰。不过基础算术只是小学算术

出现问题是因为上面使用了任意大小的数组,并且它不支持使用“e”来引入小数指数的科学记数法,如“2.79e34”。上述算法要求我们维护所有给定的任意长度的十进制数乘除所需的space。通常,我们不想那样做,我们也想要更快的算法。请注意,使用上述算法支持科学记数法还需要任意大小的数组。要填写“2.79e34”的十进制数字,我们必须用“279000000000000000000000000000000000”填充数组。

因此开发了算法以更智能的方式进行转换。我们可以不进行精确计算,而是进行精确计算,但要仔细分析产生的误差,以确保误差太小,不会妨碍我们得到正确的答案。另外,可以提前准备好数据,比如十次方的信息表,这样我们就可以在二进制中得到十次方的近似值,而不必每次转换时都计算它们。

将十进制转换为二进制浮点数的复杂性源于对快速且使用有限资源的算法的需求。允许一些错误导致需要数学证明以确保计算正确,并且试图使例程快速和资源高效导致人们想到使用聪明的技术,这变得棘手并需要证明。