CodeGym /课程 /Frontend SELF ZH /处理浮点数

处理浮点数

Frontend SELF ZH
第 37 级 , 课程 0
可用

1.1 浮点数的舍入

浮点数在英语中称为 floating point number — 带小数点的数字:在美国,小数和整数部分由点分隔。这就是 float 名称的由来。

正如我们已经讨论过的,将浮点数 (float) 转换为整数 (int) 时,它总是向下舍入到整数 — 它的小数部分被忽略。但很容易想到一种情况,即需要将小数简单地舍入到最近的整数,或者向上舍入。怎么做呢?

对于这种情况,JavaScript 中有一个内置函数 round()。它甚至在创建 Math 库之前就被发明了,所以它不包括在其中。而用于向下和向上舍入的函数位于 math 库中。

Math.round() 函数

Math.round() 函数将数字舍入到最近的整数:

    
      Math.round(浮点数)
    
  

此函数将返回最接近传入的浮点数的整数。

例子:

命令 结果
let x = Math.round(4.1); 4
let x = Math.round(4.5); 5
let x = Math.round(4.9); 5

Math.ceil() 函数

Math.ceil() 函数将数字向上舍入到整数:

命令 结果
let x = Math.ceil(4.1); 5
let x = Math.ceil(4.5); 5
let x = Math.ceil(4.9); 5

Math.floor() 函数

Math.floor() 函数将数字向下舍入到整数:

命令 结果
let x = Math.floor(4.1); 4
let x = Math.floor(4.5); 4
let x = Math.floor(4.9); 4

如果你很难记住这些命令,一个小小的英语课程可能会帮你:

  • math — 数学
  • round — 圆/舍入
  • ceiling — 天花板
  • floor — 地板

1.2 浮点数的结构

JavaScript 中的 number 类型可以存储的值范围从 -1.7*10308 到 +1.7*10308。如此巨大的值范围是因为 number 类型的结构与整数类型完全不同。每个 number 类型的变量包含两个数字:第一个称为 尾数,第二个称为 指数

假设我们有一个数字 123456789,并将其存储为 number 类型变量。然后这个数字将被转换为 1.23456789*108,在 number 类型中将存储数字 1.234567898。红色部分标出了“数字的有效部分”(尾数),蓝色部分表示指数。

这种方法可以存储非常大的数字和非常小的数字。但由于数字的大小限制为 8 个字节(64 位),部分位用于存储 指数(以及数字和指数的符号),尾数的最大长度限制为 15 个数字。

这是一种非常简化的浮点数结构描述:更详细的解释请参见 链接

1.3 使用浮点数时的精度损失

使用浮点数时始终要记住,浮点数是不精确的。总会有 舍入误差、从十进制转换到二进制时的误差,以及最常见的情况 — 在相加/相减非常不同大小的数字时的精度损失

最后一种情况对于编程新手来说是最意想不到的。

如果从数字 109 中减去 1/109,我们将再次得到 109

减去不同大小的数字 解释
1000000000.000000000
-      0.000000001
1000000000.000000000
第二个数字太小,其有效部分被忽略(用灰色标出)。 红色标出了 15 个有效数字

怎么说呢,编程和数学不完全一样。

1.4 比较浮点数的危险

当比较浮点数时,程序员会面临另一种危险。由于使用这些数字时可能会累积舍入误差,可能出现这样的情况,浮点数应该是相等的,但它们并不相等。反之亦然:数字应该不相等,但它们却相等。

例子:

命令 解释
let a = 1000000000.0
let b = 0.000000001
let c = a – b
在变量 a 中将有值 1000000000.0
在变量 c 中将有值 1000000000.0
(变量 b 中的数字太小)。

在上面的例子中,ac 不应该相等,但它们相等。

或者我们来看另一个例子:

命令 解释
let a = 1.00000000000000001
let b = 1.00000000000000002
在变量 a 中将有值 1.0
在变量 b 中将有值 1.0

在实践中,浮点数比较是这样进行的:

如果数字的差(绝对值)小于某个非常小的数字,它们被认为是相等的。

例子:

JavaScript
    
      let a = 0.00000000012;
      let b = 0.000000000011;

      if (Math.abs(a - b) < 0.00001) {
        console.log("相等");
      } else {
        console.log("不相等");
      }
    
  
评论
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION