diff --git a/1-js/05-data-types/02-number/1-sum-interface/solution.md b/1-js/05-data-types/02-number/1-sum-interface/solution.md
index 96b2eef2cc..e49e7e5dcf 100644
--- a/1-js/05-data-types/02-number/1-sum-interface/solution.md
+++ b/1-js/05-data-types/02-number/1-sum-interface/solution.md
@@ -7,6 +7,6 @@ let b = +prompt("The second number?", "");
alert( a + b );
```
-注意一元符号 `+` 在 `prompt` 前面。它会把获取的值转换成数字。
+注意在 `prompt` 前面的一元加号 `+`。它会立刻把获取的值转换成数字。
-否则,`a` 和 `b` 会是字符串,它们的总和就是它们的连接,即:`“1”+“2”=“12”`。
+否则,`a` 和 `b` 会是字符串,它们的总和就是它们的连接,即:`"1" + "2" = "12"`。
diff --git a/1-js/05-data-types/02-number/1-sum-interface/task.md b/1-js/05-data-types/02-number/1-sum-interface/task.md
index 123a44d6e1..5c0c0aba38 100644
--- a/1-js/05-data-types/02-number/1-sum-interface/task.md
+++ b/1-js/05-data-types/02-number/1-sum-interface/task.md
@@ -2,10 +2,10 @@ importance: 5
---
-# 来自访客的总数
+# 来自访客的数字求和
创建一个脚本,提示访问者输入两个数字,然后显示它们的总和。
[demo]
-提示:类型会有一个问题。
+提示:这有一个类型陷阱。
diff --git a/1-js/05-data-types/02-number/2-why-rounded-down/solution.md b/1-js/05-data-types/02-number/2-why-rounded-down/solution.md
index 6aa1ef7eb0..68e67cb793 100644
--- a/1-js/05-data-types/02-number/2-why-rounded-down/solution.md
+++ b/1-js/05-data-types/02-number/2-why-rounded-down/solution.md
@@ -1,4 +1,4 @@
-在 `6.35` 内部,小数部分是一个无限的二进制。在这种情况下,它存储的时候有一个精度的缺失。
+在 `6.35` 内部,小数部分是一个无限的二进制。在这种情况下,它的存储会存在一个精度的损失。
让我们来看看:
@@ -6,25 +6,25 @@
alert( 6.35.toFixed(20) ); // 6.34999999999999964473
```
-精度缺失可能会导致数字的增加和减小。在这种特殊情况下,数字可能会变小了一点,这就是为什么它减小了。
+精度损失可能会导致数字的增加和减小。在这种特殊情况下,数字可能会变小了一点,这就是为什么它减小了。
-那么 `1.35` 是怎样样的呢?
+那么 `1.35` 是怎样的呢?
```js run
alert( 1.35.toFixed(20) ); // 1.35000000000000008882
```
-在这里,精度缺失使得这个数字更大一些,所以这个数字变大了一些。
+在这里,精度损失使得这个数字更大了一些,所以这个数字变大了一些。
**如果我们希望以正确的方式四舍五入,我们如何使用 `6.35` 为例来解决这个问题?**
-在四舍五入之前,我们应该把它接近整数:
+在四舍五入之前,我们应该使它更接近整数:
```js run
alert( (6.35 * 10).toFixed(20) ); // 63.50000000000000000000
```
-请注意 `63.5` 完全没有精度缺失。这是因为小数部分 `0.5` 实际上是 `1 / 2`。除以2的幂的分数在二进制系统中被精确地表示,现在我们可以围绕它来解决问题:
+请注意 `63.5` 完全没有精度缺失。这是因为小数部分 `0.5` 实际上是 `1/2`。以 2 为分母的分数在二进制系统中可以被精确地表示,现在我们可以对它进行四舍五入了:
```js run
diff --git a/1-js/05-data-types/02-number/2-why-rounded-down/task.md b/1-js/05-data-types/02-number/2-why-rounded-down/task.md
index 711704ff51..fb8effbbe3 100644
--- a/1-js/05-data-types/02-number/2-why-rounded-down/task.md
+++ b/1-js/05-data-types/02-number/2-why-rounded-down/task.md
@@ -4,7 +4,7 @@ importance: 4
# 为什么 6.35.toFixed(1) == 6.3?
-根据文档 `Math.round` 和 `toFixed`,最近的数字四舍五入:`0..4` 会被舍去,而 `5..9` 会前进一位。
+根据文档 `Math.round` 和 `toFixed` 均将数字进行四舍五入:`0..4` 会被舍去,而 `5..9` 会前进一位。
例如:
diff --git a/1-js/05-data-types/02-number/3-repeat-until-number/_js.view/test.js b/1-js/05-data-types/02-number/3-repeat-until-number/_js.view/test.js
index 219fa8068e..6bd0123dba 100644
--- a/1-js/05-data-types/02-number/3-repeat-until-number/_js.view/test.js
+++ b/1-js/05-data-types/02-number/3-repeat-until-number/_js.view/test.js
@@ -18,7 +18,7 @@ describe("readNumber", function() {
assert.strictEqual(readNumber(), 0);
});
- it("continues the loop unti meets a number", function() {
+ it("continues the loop until meets a number", function() {
prompt.onCall(0).returns("not a number");
prompt.onCall(1).returns("not a number again");
prompt.onCall(2).returns("1");
@@ -35,4 +35,4 @@ describe("readNumber", function() {
assert.isNull(readNumber());
});
-});
\ No newline at end of file
+});
diff --git a/1-js/05-data-types/02-number/3-repeat-until-number/solution.md b/1-js/05-data-types/02-number/3-repeat-until-number/solution.md
index 30c000b3b0..3da8eee13d 100644
--- a/1-js/05-data-types/02-number/3-repeat-until-number/solution.md
+++ b/1-js/05-data-types/02-number/3-repeat-until-number/solution.md
@@ -15,8 +15,8 @@ function readNumber() {
alert(`Read: ${readNumber()}`);
```
-该解决方案有点复杂,可能是因为我们需要处理 null/空行。
+该解决方案有点复杂,可能是因为我们需要处理 `null`/空行。
-所以我们实际上接受输入,直到它成为“常规数字”。null(取消)和空行都适合该条件,因为在数字形式中它们是 `0`。
+所以我们实际上一直接受输入,直到输入的内容为“常规数字”。`null`(取消)和空行也都适合该条件,因为在数字形式中它们是 `0`。
-在我们停止之后,我们需要专门处理 null 和空行(返回 null),因为将它们转换为数字将返回 `0`。
+在我们停止之后,我们需要专门处理 `null` 和空行(返回 `null`),因为将它们转换为数字将返回 `0`。
diff --git a/1-js/05-data-types/02-number/3-repeat-until-number/task.md b/1-js/05-data-types/02-number/3-repeat-until-number/task.md
index 1ea3e3d33e..c689e91d1a 100644
--- a/1-js/05-data-types/02-number/3-repeat-until-number/task.md
+++ b/1-js/05-data-types/02-number/3-repeat-until-number/task.md
@@ -2,12 +2,12 @@ importance: 5
---
-# 重复检测,直到输入是一个数字
+# 重复检测,直到输入的是一个数字
-创建一个函数 `readNumber`,它提示输入一个数字,直到访问者输入一个有效的数字。
+创建一个函数 `readNumber`,它提示输入一个数字,直到访问者输入一个有效的数字为止。
结果值必须作为数字返回。
-访问者也可以通过输入空行或按“取消”来停止该过程。在这种情况下,函数应该返回 `null`。
+访问者也可以通过输入空行或点击“取消”来停止该过程。在这种情况下,函数应该返回 `null`。
[demo]
diff --git a/1-js/05-data-types/02-number/4-endless-loop-error/solution.md b/1-js/05-data-types/02-number/4-endless-loop-error/solution.md
index 16201a3458..08a47fc1fd 100644
--- a/1-js/05-data-types/02-number/4-endless-loop-error/solution.md
+++ b/1-js/05-data-types/02-number/4-endless-loop-error/solution.md
@@ -1,6 +1,6 @@
那是因为 `i` 永远不会等于 `10`。
-运行它以查看 `i` 的实际值:
+运行它以查看 `i` 的 **真实** 值:
```js run
let i = 0;
@@ -10,8 +10,8 @@ while (i < 11) {
}
```
-他们中没有一个完全是 `10`。
+它们中没有一个完全是 `10`。
-发生这样的事情是因为在添加像 `0.2` 这样的分数时出现了精度损失。
+发生这样的事情是因为在添加像 `0.2` 这样的小数时出现了精度损失。
-结论:在处理小数部分时避免相等检查。
+结论:在处理小数部分时,应避免相等检查。
diff --git a/1-js/05-data-types/02-number/8-random-min-max/solution.md b/1-js/05-data-types/02-number/8-random-min-max/solution.md
index 562be1f62f..a1eed8e6e5 100644
--- a/1-js/05-data-types/02-number/8-random-min-max/solution.md
+++ b/1-js/05-data-types/02-number/8-random-min-max/solution.md
@@ -1,9 +1,9 @@
-我们需要将区间 0..1 中的所有值“映射”为从最小值到最大值。
+我们需要将区间 0..1 中的所有值“映射”为从 `min` 到 `max`。
这可以分两个阶段完成:
-1. 如果我们将 0..1 的随机数乘以 `max-min`,则可能值的间隔从 0..1 增加到 `0..max-min`。
-2. 现在,如果我们添加 `min`,则可能的间隔将从 `min` 变为 `max`。
+1. 如果我们将 0..1 的随机数乘以 `max-min`,则随机数的取值范围从 0..1 增加到 `0..max-min`。
+2. 现在,如果我们将 `min` 值与随机数相加,则随机数的取值范围就变为了从 `min` 到 `max`。
函数实现:
diff --git a/1-js/05-data-types/02-number/8-random-min-max/task.md b/1-js/05-data-types/02-number/8-random-min-max/task.md
index ecfa3447b6..5563b261fd 100644
--- a/1-js/05-data-types/02-number/8-random-min-max/task.md
+++ b/1-js/05-data-types/02-number/8-random-min-max/task.md
@@ -2,11 +2,11 @@ importance: 2
---
-# 从最小到最大的随机数
+# 从 min 到 max 的随机数
-用内置函数Math.random() 创建一个从 0 到 1 的随机值(不包括 1 )。
+内置函数 `Math.random()` 会创建一个 `0` 到 `1` 的随机值(不包括 `1`)。
-编写随机函数(min,max)以生成从最小到最大(不包括最大值)的随机浮点数。
+编写函数 `random(min, max)` 以生成从 `min` 到 `max`(不包括 `max`)的随机浮点数。
实例:
diff --git a/1-js/05-data-types/02-number/9-random-int-min-max/solution.md b/1-js/05-data-types/02-number/9-random-int-min-max/solution.md
index b9c7a095e0..309378857b 100644
--- a/1-js/05-data-types/02-number/9-random-int-min-max/solution.md
+++ b/1-js/05-data-types/02-number/9-random-int-min-max/solution.md
@@ -1,6 +1,6 @@
# 简单但错误的解决方案
-最简单但错误的解决方案是从 `min` 到 `max` 生成一个值并取它四舍五入的值:
+最简单但错误的解决方案是生成一个范围在 `min` 到 `max` 的值,并取对其进行四舍五入后的值:
```js run
function randomInteger(min, max) {
@@ -11,11 +11,11 @@ function randomInteger(min, max) {
alert( randomInteger(1, 3) );
```
-这个函数是能起作用的,但不正确。获得边缘值 `min` 和 `max` 的概率是其他值的两倍。
+这个函数是能起作用的,但不正确。获得边缘值 `min` 和 `max` 的概率比其他值低两倍。
-如果你多次运行这个例子,你会很容易看到 `2` 出现的频率最高。
+如果你将上面这个例子运行多次,你会很容易看到 `2` 出现的频率最高。
-发生这种情况是因为 `Math.round()` 从间隔 `1..3` 获得随机数并按如下所示进行四舍五入:
+发生这种情况是因为 `Math.round()` 从范围 `1..3` 中获得随机数,并按如下所示进行四舍五入:
```js no-beautify
values from 1 ... to 1.4999999999 become 1
@@ -27,12 +27,12 @@ values from 2.5 ... to 2.9999999999 become 3
# 正确的解决方案
-这项任务有很多正确的解决方案。其中之一是调整间隔边界。为了确保相同的时间间隔,我们可以生成从 0.5 到 3.5 的值,从而将所需的概率添加到边缘:
+这个题目有很多正确的解决方案。其中之一是调整取值范围的边界。为了确保相同的取值范围,我们可以生成从 0.5 到 3.5 的值,从而将所需的概率添加到取值范围的边界:
```js run
*!*
function randomInteger(min, max) {
- // now rand is from (min-0.5) to (max+0.5)
+ // 现在范围是从 (min-0.5) 到 (max+0.5)
let rand = min - 0.5 + Math.random() * (max - min + 1);
return Math.round(rand);
}
@@ -41,7 +41,7 @@ function randomInteger(min, max) {
alert( randomInteger(1, 3) );
```
-另一种方法是使用 `Math.floor` 作为从 `min` 到 `max+1` 的随机数:
+另一种方法是使用 `Math.floor` 来取范围从 `min` 到 `max+1` 的随机数:
```js run
*!*
@@ -63,4 +63,4 @@ values from 2 ... to 2.9999999999 become 2
values from 3 ... to 3.9999999999 become 3
```
-所有间隔的长度相同,所以最终能够均匀分配。所有整数出现的概率都相同了。
+所有间隔的长度相同,从而使最终能够均匀分配。
diff --git a/1-js/05-data-types/02-number/9-random-int-min-max/task.md b/1-js/05-data-types/02-number/9-random-int-min-max/task.md
index 8ae2b30676..1f67bcddfa 100644
--- a/1-js/05-data-types/02-number/9-random-int-min-max/task.md
+++ b/1-js/05-data-types/02-number/9-random-int-min-max/task.md
@@ -2,11 +2,11 @@ importance: 2
---
-# 从最小到最大的随机整数
+# 从 min 到 max 的随机整数
-创建一个函数 `randomInteger(min,max)`,该函数从 `min` 到 `max` 生成随机整数,包括 `min` 和 `max` 作为可能值。
+创建一个函数 `randomInteger(min, max)`,该函数会生成从 `min` 到 `max` 的随机整数,生成的值包括 `min` 和 `max`。
-来自间隔 `min..max` 的任何数字必须以相同的概率出现。
+取值范围在 `min..max` 中的任何数字出现的概率必须相同。
功能示例:
@@ -17,4 +17,4 @@ alert( random(1, 5) ); // 3
alert( random(1, 5) ); // 5
```
-您可以使用[上一个任务](info:task/random-min-max)的解决方案作为基础。
+你可以使用 [上一个任务](info:task/random-min-max) 的解决方案作为基础。
diff --git a/1-js/05-data-types/02-number/article.md b/1-js/05-data-types/02-number/article.md
index 0bc8381e1c..baf16d90b7 100644
--- a/1-js/05-data-types/02-number/article.md
+++ b/1-js/05-data-types/02-number/article.md
@@ -1,36 +1,40 @@
# 数字类型
-JavaScript 中的所有数字都以 64 位格式 [IEEE-754](http://en.wikipedia.org/wiki/IEEE_754-1985) 存储,也称为“双精度”。
+在现代 JavaScript 中,有两种类型的数字:
-让我们回顾一下并展开我们目前了解的内容。
+1. JavaScript 中常规的数字以 64 位的形式 [IEEE-754](http://en.wikipedia.org/wiki/IEEE_754-1985) 存储,也称为“双精度浮点数”。这些是我们大多数时候使用的数字,我们将在本章中讨论它们。
+
+2. BigInt 数字,用于表示任意长度的整数。有时会用到它们,因为常规的数字类型无法表示大于 253 或小于 -253 的数字。由于 BigInt 只会在少数特殊领域中才会用到,因此我们在特殊的章节 中对其进行了介绍。
+
+因此,这里我们将讨论常规的数字类型。让我们开始学习它们吧。
## 编写数字的更多方法
-想象一下,我们需要写 10 亿。显而易见的方法是:
+想象一下,我们需要写 10 亿。显而易见的方式是:
```js
let billion = 1000000000;
```
-但在现实生活中,我们通常避免写一长串零,因为它很容易输入错误。另外,我们很懒。我们通常会为十亿或七十三亿写一些类似于 `1bn` 的数字,为 `7.3bn`。对于大多数人来说也是如此。
+但在现实生活中,我们通常避免写一长串零,因为它很容易输入错误。另外,我们很懒。我们通常会将 10 亿或 73 亿写成类似于 `1bn` 和 `7.3bn` 的形式。对于大多数人来说也是如此。
在 JavaScript 中,我们通过在数字后附加字母 "e" 来缩短数字,并指定零的数量来计数:
```js run
-let billion = 1e9; // 1 billion, literally: 1 and 9 zeroes
+let billion = 1e9; // 10 亿,字面意义:1 和 9 个零
-alert( 7.3e9 ); // 7.3 billions (7,300,000,000)
+alert( 7.3e9 ); // 73 亿(7,300,000,000)
```
-换句话说,`"e"` 把数字乘以 `1` 后面跟着指定数量的 0。
+换句话说,`"e"` 把数字乘以 `1` 后面跟着给定数量的 0 的数来计数。
```js
1e3 = 1 * 1000
1.23e6 = 1.23 * 1000000
```
-
现在让我们写一些非常小的东西。例如:1 微秒(百万分之一秒):
+
```js
let ms = 0.000001;
```
@@ -38,50 +42,49 @@ let ms = 0.000001;
就像以前一样,使用 `"e"` 可以提供帮助。如果我们想避免明确地写零,我们可以说:
```js
-let ms = 1e-6; // six zeroes to the left from 1
+let ms = 1e-6; // 1 左边有 6 个 0
```
+如果我们数一下 `0.000001` 中的零,共有 6 个。所以自然是 `1e-6`。
-如果我们计算 `0.000001` 中的零,则有 6 个。所以自然是 `1e-6`。
-
-换句话说,`e` 后面的负数表示除以 1 后面跟着给定数量的 0:
+换句话说,`e` 后面的负数表示除以 1 后面跟着给定数量的 0 的数:
```js
-// -3 divides by 1 with 3 zeroes
+// -3 除以 1 后面有 3 个 0 的数
1e-3 = 1 / 1000 (=0.001)
-// -6 divides by 1 with 6 zeroes
+// -6 除以 1 后面有 6 个 0 的数
1.23e-6 = 1.23 / 1000000 (=0.00000123)
```
### 十六进制,二进制和八进制数字
-[十六进制](https://en.wikipedia.org/wiki/Hexadecimal)数字在 JavaScript 中被广泛用于表示颜色,编码字符以及其他许多事物。所以很自然地,写一个更简短的方法:`0x` 然后是数字。
+[十六进制](https://en.wikipedia.org/wiki/Hexadecimal) 数字在 JavaScript 中被广泛用于表示颜色,编码字符以及其他许多事物。所以很自然地,这有一种更简短的编写方法:`0x` 后面加上数字。
例如:
```js run
alert( 0xff ); // 255
-alert( 0xFF ); // 255 (the same, case doesn't matter)
+alert( 0xFF ); // 255(一样,与大小写无关)
```
-虽然二进制和八进制数字系统很少使用,但也支持使用 `0b` 和 `0o` 前缀:
+虽然二进制和八进制数字系统很少使用,但也可以使用 `0b` 和 `0o` 前缀来编写:
```js run
-let a = 0b11111111; // binary form of 255
-let b = 0o377; // octal form of 255
+let a = 0b11111111; // 二进制形式的 255
+let b = 0o377; // 八进制形式的 255
-alert( a == b ); // true, the same number 255 at both sides
+alert( a == b ); // true,两边都是数字 255
```
只有这三种进制支持这种写法。对于其他进制,我们应该使用函数 `parseInt`(我们将在本章后面看到)。
## toString(base)
-方法 `num.toString(base)` 返回带有给定 `base` 的进制中 `num` 的字符串表示。
+方法 `num.toString(base)` 返回带有给定 `base` 的进制中数字 `num` 的字符串表示。
-举个例子:
+例如:
```js run
let num = 255;
@@ -95,18 +98,18 @@ alert( num.toString(2) ); // 11111111
- **base=16** 用于十六进制颜色,字符编码等,数字可以是 `0..9` 或 `A..F`。
- **base=2** 主要用于调试按位操作,数字可以是 `0` 或 `1`。
-- **base=36** 是最大值,数字可以是 `0..9` 或 `A..Z`。整个拉丁字母用来表示一个数字。对于 `36` 来说,一个有趣而有用的例子是,当我们需要将一个较长的数字标识符变成较短的时候,例如做一个简短的URL。可以简单地用基数为 `36` 的数字系统表示:
+- **base=36** 是最大值,数字可以是 `0..9` 或 `A..Z`。整个拉丁字母用来表示一个数字。对于 `36` 来说,一个有趣且有用的例子是,当我们需要将一个较长的数字标识符变成较短的时候,例如做一个简短的URL。可以简单地用基数为 `36` 的数字系统表示:
```js run
alert( 123456..toString(36) ); // 2n9c
```
-```warn header="调用方法的两个点"
-请注意 `123456..toString(36)` 中的两个点不是拼写错误。如果我们想直接在一个数字上调用一个方法,比如上面例子中的 `toString`,那么我们需要在它后面放置两个点 `..`。
+```warn header="两给点来调用方法"
+请注意 `123456..toString(36)` 中的两个点不是拼写错误。如果我们想直接在一个数字上调用一个方法,比如上面例子中的 `toString`,那么我们需要在这个数字的后面放置两个点 `..`。
-如果我们放置一个点:`123456.toString(36)`,那么会出现错误,因为 JavaScript 语法暗示了第一个点之后的小数部分。如果我们再放一个点,那么 JavaScript 知道小数部分是空的,现在进入方法。
+如果我们放置一个点:`123456.toString(36)`,那么就会出现错误,因为 JavaScript 语法默认第一个点之后的部分是小数部分。如果我们再放一个点,那么 JavaScript 知道小数部分是空的,现在进入方法。
-也可以写 `(123456).toString(36)`。
+也可以写成 `(123456).toString(36)`。
```
## 数值修约(Rounding)
@@ -122,10 +125,10 @@ alert( num.toString(2) ); // 11111111
: 向上舍入:`3.1` 变成 `4`,`-1.1` 变成 `-1`。
`Math.round`
-: 向最近的整数舍入:`3.1` 变成 `3`, 3.6` 变成 `4`,`-1.1` 变成 `-1`。
+: 向最近的整数舍入:`3.1` 变成 `3`,`3.6` 变成 `4`,`-1.1` 变成 `-1`。
`Math.trunc`(IE 浏览器不支持这个方法)
-: 删除小数点后的所有内容而不舍入:`3.1` 变成 `3`,`-1.1` 变成 `-1`。
+: 删除小数点后的所有内容而不进行舍入:`3.1` 变成 `3`,`-1.1` 变成 `-1`。
以下是总结它们之间差异的表格:
@@ -137,47 +140,47 @@ alert( num.toString(2) ); // 11111111
|`-1.6`| `-2` | `-1` | `-2` | `-1` |
-这些函数涵盖处理数字小数部分的所有可能方法。但是如果我们想在十进制后将数字四舍五入到 `n` 位呢?
+这些函数涵盖了处理数字小数部分的所有可能方法。但是如果我们想将数字四舍五入到小数点后的第 `n` 个数字,该怎么办呢?
-例如,我们有 `1.2345`,并且想把它舍入到 2 位数,只得到 `1.23`。
+例如,我们有 `1.2345`,并且想把它舍入到小数点后 2 位,只需要得到 `1.23`。
有两种方法可以这样做:
1. 乘法和除法
- 例如,要将数字四舍五入到小数点后的第二个数字,我们可以将数字乘以 100,调用舍入函数,然后再将其除回 100。
+ 例如,要将数字四舍五入到小数点后的第二个数字,我们可以将数字乘以 100,调用舍入函数,然后再通过除法将其转换回来。
```js run
let num = 1.23456;
alert( Math.floor(num * 100) / 100 ); // 1.23456 -> 123.456 -> 123 -> 1.23
```
-2. 函数 [toFixed(n)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toFixed) 将点数后的数字四舍五入到 `n` 个数字并返回结果的字符串表示。
+2. 方法 [toFixed(n)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toFixed) 将小数点后的数字四舍五入到 `n` 个,返回结果的字符串表示。
```js run
let num = 12.34;
alert( num.toFixed(1) ); // "12.3"
```
- 这会向上或向下舍入到最接近的值,类似于 `Math.round`:
+ 这个方法会将数字向最近的值进行舍入,类似于 `Math.round`:
```js run
let num = 12.36;
alert( num.toFixed(1) ); // "12.4"
```
- 请注意 `toFixed` 的结果是一个字符串。如果小数部分比所需要的短,则在结尾添加零:
+ 请注意 `toFixed` 的结果是一个字符串。如果小数部分比所需要的短,则会在末尾添加零:
```js run
let num = 12.34;
- alert( num.toFixed(5) ); // "12.34000", added zeroes to make exactly 5 digits
+ alert( num.toFixed(5) ); // "12.34000",添加 0,以精确生成小数点后五位的小数
```
- 我们可以使用一元加号或 `Number()` 调用将其转换为数字:`+ num.toFixed(5)`。
+ 我们可以使用一元加号或 `Number()` 调用,将其转换为数字:`+num.toFixed(5)`。
## 不精确计算
-在 js 内部,一个数字以 64 位格式 [IEEE-754](http://en.wikipedia.org/wiki/IEEE_754-1985) 表示,所以正好有 64 位可以存储一个数字:其中 52 个被使用存储这些数字,其中 11 个存储小数点的位置(它们对于整数为零),1 位用于符号。
+在 JavaScript 内部,一个数字是以 64 位的格式 [IEEE-754](https://en.wikipedia.org/wiki/IEEE_754-2008_revision) 表示的,所以正好有 64 位可以存储一个数字:其中 52 位被用于存储数字,11 位用于存储小数点的位置(对于整数则为零),剩下的 1 位用于存储符号。
如果一个数字太大,它会溢出 64 位存储,可能会输出无穷大:
@@ -193,7 +196,7 @@ alert( 1e500 ); // Infinity
alert( 0.1 + 0.2 == 0.3 ); // *!*false*/!*
```
-没错,如果我们检查 `0.1` 和 `0.2` 的总和是否为 `0.3`,们会得到 `false`。
+这是对的,如果我们检查 `0.1` 和 `0.2` 的和是否为 `0.3`,我们会得到 `false`。
奇怪!那么如果不是 `0.3`,那么又是什么呢?
@@ -201,17 +204,17 @@ alert( 0.1 + 0.2 == 0.3 ); // *!*false*/!*
alert( 0.1 + 0.2 ); // 0.30000000000000004
```
-哎哟!这里的错误有更大的误差。想象一下,你正在制作一个电子购物网站,访问者将 `0.10 美元` 和 `0.20 美元` 商品放入他的图表中。订单总额将是 `$ 0.30000000000000004`。这会让任何人感到惊讶。
+啥!这个结果造成的后果会比一个错误的比较要大得多。想象一下,你正在建立一个电子购物网站,访问者将 `0.10 美元` 和 `0.20 美元` 的商品放入了他的购物车中。订单总额为 `$ 0.30000000000000004`。这会让任何人感到惊讶。
但为什么会发生这样的事呢?
-一个数字以二进制形式存储在内存中,一个 1 和 0 的序列。但是像十进制数字系统看起来很简单的 `0.1`,`0.2` 这样的小数实际上是二进制形式的循环小数。
+一个数字以二进制形式存储在内存中,一个 1 和 0 的序列。但是在十进制数字系统看起来很简单的 `0.1`,`0.2` 这样的小数,实际上是二进制形式的无限循环小数。
-换句话说,什么是 `0.1`?`0.1` 就是把 1 除以 10 `1/10`,即十分之一。在十进制数字系统中,这些数字很容易表示。将它比作三分之一:`1/3`。它变成了循环小数 `0.33333(3)`。
+换句话说,什么是 `0.1`?`0.1` 就是把 1 除以 10 `1/10`,即十分之一。在十进制数字系统中,这些数字很容易表示。而对于数字三分之一:`1/3`。则为无限循环小数 `0.33333(3)`。
-所以,按这种用 `10` 划分可以保证在十进制系统中运行良好,但用 `3` 划分不是。出于同样的原因,在二进制数字系统中,`2` 的幂的分割保证工作,但 `1/10` 变成一个无限的二进制小数。
+因此,按这种用 `10` 划分可以保证在十进制系统中运行良好,但用 `3` 划分则不行。出于同样的原因,在二进制数字系统中,`2` 的幂的分割可以保证工作,但 `1/10` 变成了一个无限的二进制小数。
-使用二进制系统无法*精确*存储 *0.1* 或 *0.2*,就像没有办法将三分之一存储为十进制小数一样。
+使用二进制系统无法 **精确** 存储 *0.1* 或 *0.2*,就像没有办法将三分之一精确存储为十进制小数一样。
数字格式 IEEE-754 通过四舍五入到最接近的可能数字来解决此问题。这些舍入规则通常不允许我们看到 `极小的精确度损失`,因此数字显示为 `0.3`。但要小心,损失依然存在。
@@ -220,66 +223,62 @@ alert( 0.1 + 0.2 ); // 0.30000000000000004
alert( 0.1.toFixed(20) ); // 0.10000000000000000555
```
-当我们给两个数字求和时,他们的“精度损失”会加起来。
+当我们给两个数字求和时,它们的“精度损失”会加起来。
-这就是为什么 `0.1 + 0.2` 不等于 `0.3` 的原因。
+这就是为什么 `0.1 + 0.2` 不等于 `0.3`。
```smart header="不仅仅是 JavaScript"
许多其他编程语言也存在同样的问题。
-PHP, Java, C, Perl, Ruby 给出完全相同的结果,因为它们基于相同的数字格式。
+PHP,Java,C,Perl,Ruby 都给出了完全相同的结果,因为它们都基于相同的数字格式。
```
-我们能解决这个问题吗?当然,有很多方法:
+我们能解决这个问题吗?当然,最常用的方法就是使用 [toFixed(n)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toFixed) 方法来对计算结果进行舍入:
-1. 我们可以在特定函数的帮助下对结果进行四舍五入 [toFixed(n)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toFixed):
-
- ```js run
- let sum = 0.1 + 0.2;
- alert( sum.toFixed(2) ); // 0.30
- ```
+```js run
+let sum = 0.1 + 0.2;
+alert( sum.toFixed(2) ); // 0.30
+```
- 请注意 `toFixed` 总是返回一个字符串。它确保它在小数点后有 2 位数字。如果我们有电子购物并需要显示 `0.30 美元`,这实际上很方便。对于其他情况,我们可以使用一元加号将它强制为一个数字:
+请注意 `toFixed` 总是返回一个字符串。它确保小数点后有 2 位数字。如果我们有电子购物并需要显示 `0.30 美元`,这实际上很方便。对于其他情况,我们可以使用一元加号将其强制转换为数字:
- ```js run
- let sum = 0.1 + 0.2;
- alert( +sum.toFixed(2) ); // 0.3
- ```
+```js run
+let sum = 0.1 + 0.2;
+alert( +sum.toFixed(2) ); // 0.3
+```
-2. 我们可以暂时将数字转换为数学整数,然后将其恢复。它是这样工作的:
+我们可以将数字暂时乘以 100(或更大的数字),将其转换为整数进行数学运算,然后通过除法将其恢复。当我们使用整数进行数学运算时,误差有所减少,但在进行除法操作时仍会造成误差:
- ```js run
- alert( (0.1 * 10 + 0.2 * 10) / 10 ); // 0.3
- alert( (0.28 * 100 + 0.14 * 100) / 100); // 0.4200000000000001
- ```
+```js run
+alert( (0.1 * 10 + 0.2 * 10) / 10 ); // 0.3
+alert( (0.28 * 100 + 0.14 * 100) / 100); // 0.4200000000000001
+```
- 这是有效的,因为当我们做 `0.1 * 10 = 1` 和 `0.2 * 10 = 2` 时,那么这两个数字就变成了整数,并且没有精度损失。
+因此,乘/除法可以减少误差,但是不能完全消除误差。
-3. 如果我们在与一家商店打交道,那么最激进的解决方案就是将所有价格存储在美分中,并且根本不使用分数。但是,如果我们应用 30% 的折扣呢?在实践中,完全回避分数是很难实现的,所以上述解决方案有助于避免这种缺陷。
+有时我们可以尝试完全避开小数。就像我们与一家商店打交道一样,我们可以用美分而不是美元来存储价格。但是,如果我们应用 30% 的折扣呢?实际上,完全逃避小数几乎是不可能的。只需要在需要时将它们切分成圆形即可。
-````smart header="有趣的事情"
+````smart header="有趣的事儿"
尝试运行这个:
```js run
-// Hello! I'm a self-increasing number!
-alert( 9999999999999999 ); // shows 10000000000000000
+// 你好!我是一个自增数!
+alert( 9999999999999999 ); // 显示 10000000000000000
```
-出现了同样的问题:精度的损失。该号码有 64 位,其中 52 位可用于存储数字,但这还不够。所以最不重要的数字就消失了。
+这出现了同样的问题:精度的损失。计算机中以 64 位的格式存储数字,其中 52 位可用于存储数字,但这还不够。所以最不重要的数字就消失了。
-JavaScript 在这种事件中不会触发错误。它尽最大努力使数字符合所需的格式,但不幸的是,这种格式不够大到满足需求。
+JavaScript 在这种情况下不会触发错误。它尽最大努力使数字符合所需的格式,但不幸的是,这种格式不够大到满足需求。
````
```smart header="两个零"
数字内部表示的另一个有趣结果是存在两个零:`0` 和 `-0`。
-这是因为一个符号由一个位表示,所以每个数字可以是正数或负数,包括零。
+这是因为符号是由一个位表示的,所以每个数字都可以是正数或负数,包括零。
-在大多数情况下,这种区别并不明显,因为操作员可以将它们视为相同。
+在大多数情况下,这种区别并不明显,因为操作符将它们视为相同的。
```
-
-
## 测试:isFinite 和 isNaN
还记得这两个特殊的数值吗?
@@ -287,7 +286,7 @@ JavaScript 在这种事件中不会触发错误。它尽最大努力使数字符
- `Infinity`(和 `-Infinity`)是一个特殊的数值,比任何数值都大(小)。
- `NaN` 代表一个错误。
-它们属于 `数字` 类型,但不是 `普通` 数字,因此有特殊函数可以检查它们:
+它们属于 `数字` 类型,但不是 `普通` 数字,因此有用于检查它们的特殊函数:
- `isNaN(value)` 将其参数转换为数字,然后测试它是否为 `NaN`:
@@ -297,38 +296,38 @@ JavaScript 在这种事件中不会触发错误。它尽最大努力使数字符
alert( isNaN("str") ); // true
```
- 但是我们需要这个功能吗?我们不能只使用比较 `=== NaN` 吗?对不起,但答案是否定的。值 "NaN" 是独一无二的,它不等于任何东西,包括它本身:
+ 但是我们需要这个函数吗?我们不能只使用比较 `=== NaN` 吗?对不起,答案是否定的。值 "NaN" 是独一无二的,它不等于任何东西,包括它本身:
```js run
alert( NaN === NaN ); // false
```
-- `isFinite(value)` 将其参数转换为数字,如果是常规数字,则返回 `true`,而不是 `NaN / Infinity / -Infinity`:
+- `isFinite(value)` 将其参数转换为数字,如果是常规数字,则返回 `true`,而不是 `NaN/Infinity/-Infinity`:
```js run
alert( isFinite("15") ); // true
- alert( isFinite("str") ); // false, because a special value: NaN
- alert( isFinite(Infinity) ); // false, because a special value: Infinity
+ alert( isFinite("str") ); // false,因为是一个特殊的值:NaN
+ alert( isFinite(Infinity) ); // false,因为是一个特殊的值:Infinity
```
-有时 `isFinite` 用于验证字符串值是否为常规数字:
+有时 `isFinite` 用于验证字符串值是否为一个常规数字:
```js run
let num = +prompt("Enter a number", '');
-// 结果会是 true,除非你输入无穷大,无穷大或不是数字
+// 结果会是 true,除非你输入 Infinity,-Infinity 或非数字
alert( isFinite(num) );
```
-请注意,所有数字函数(包括 `isFinite`)中的空字符串或空格字符串均被视为 `0`。
+请注意,所有数字函数(包括 `isFinite`)均将空字符串或空格字符串视为 `0`。
```smart header="与 Object.is 进行比较"
-有一种特殊的内置方法 [Object.is](mdn:js/Object/is),它可以比较 `===` 等值,但对于两种边缘情况更可靠:
+有一种特殊的内置方法 [Object.is](mdn:js/Object/is),它可以像 `===` 一样对值进行比较,但对于两种边缘情况更可靠:
-1. 它适用于 `NaN`: `Object.is(NaN,NaN)=== true`,这是件好事。
-2. 值 `0` 和 `-0` 是不同的:`Object.is(0,-0)=== false`,它不是很重要,但这些值在技术上是不同的。
+1. 它适用于 `NaN`:`Object.is(NaN,NaN)=== true`,这是件好事。
+2. 值 `0` 和 `-0` 是不同的:`Object.is(0,-0)=== false`,从技术上讲,这个比较结果是对的,因为在计算机内部,数字的符号位可能是不同的,即使其他所有位均为零也是如此。
在所有其他情况下,`Object.is(a,b)` 与 `a === b` 相同。
@@ -338,7 +337,7 @@ alert( isFinite(num) );
## parseInt 和 parseFloat
-使用加号 `+` 或 `Number()` 的数字转换是严格的。如果一个值不完全是一个数字,就会失败:
+使用加号 `+` 或 `Number()` 的数字转换是严格的。如果一个值不完全是数字,就会失败:
```js run
alert( +"100px" ); // NaN
@@ -346,24 +345,24 @@ alert( +"100px" ); // NaN
唯一的例外是字符串开头或结尾的空格,因为它们会被忽略。
-但在现实生活中,我们经常以单位表示值,比如 CSS 中的 `"100px"` 或 `"12pt"`。在许多国家,货币符号也超过了金额,所以我们有 `"19€"`,并希望从中提取一个数值。
+但在现实生活中,我们经常看到有单位的值,比如 CSS 中的 `"100px"` 或 `"12pt"`。并且在许多国家,货币符号被放在了金额的后面,所以我们有 `"19€"`,并希望从中提取出一个数值。
这就是 `parseInt` 和 `parseFloat` 的作用。
-它们从字符串中“读出”一个数字,直到无法读取为止。如果发生错误,则返回收集的数字。函数 `parseInt` 返回一个整数,而 `parseFloat` 将返回一个浮点数:
+它们从字符串中“读出”一个数字,直到无法读取为止。如果发生错误,则返回收集到的数字。函数 `parseInt` 返回一个整数,而 `parseFloat` 返回一个浮点数:
```js run
alert( parseInt('100px') ); // 100
alert( parseFloat('12.5em') ); // 12.5
-alert( parseInt('12.3') ); // 12, only the integer part is returned
-alert( parseFloat('12.3.4') ); // 12.3, the second point stops the reading
+alert( parseInt('12.3') ); // 12,只有整数部分被返回 only the integer part is returned
+alert( parseFloat('12.3.4') ); // 12.3,第二个点终止了数字“读取”
```
有时候 `parseInt / parseFloat` 会返回 `NaN`。一般发生在没有数字可读的情况下:
```js run
-alert( parseInt('a123') ); // NaN, the first symbol stops the process
+alert( parseInt('a123') ); // NaN,第一个符号终止了“读取”
```
````smart header="parseInt(str, radix)` 的第二个参数"
@@ -371,7 +370,7 @@ alert( parseInt('a123') ); // NaN, the first symbol stops the process
```js run
alert( parseInt('0xff', 16) ); // 255
-alert( parseInt('ff', 16) ); // 255, without 0x also works
+alert( parseInt('ff', 16) ); // 255,没有 0x 也有效
alert( parseInt('2n9c', 36) ); // 123456
```
@@ -407,30 +406,30 @@ JavaScript 有一个内置的 [Math](https://developer.mozilla.org/en/docs/Web/J
alert( Math.pow(2, 10) ); // 2 的 10 次幂 = 1024
```
-这里有 `Math` 对象中的更多函数和常量,包括三角函数,你可以在这里找到它 [docs for the Math](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Math)。
+这里有 `Math` 对象中的更多函数和常量,包括三角函数,你可以在 [Math 的文档](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Math) 中找到它们。
## 总结
-写非常大的数字:
+要写有很多零的数字:
- 附加 `"e"` 来省略 0,e 后面的数字就是零的个数。就像:`123e6` 是 `123` 后面接 6 个零。
-- `"e"` 后面的负数将导致数字除以 1 后面接着给定数量的零。e-6 那是一百万分之一。
+- `"e"` 后面的负数会使数字除以 1 后面接着给定数量的零。例如 `123e-6` 表示 `0.000123`(`123` 百万分之一)。
对于不同的进制:
- 可以在十六进制(`0x`),八进制(`0o`)和二进制(`0b`)系统中直接写入数字。
-- `parseInt(str,base)` 解析来自任何数字系统的整数,其基数为:`2≤base≤36`。
-- `num.toString(base)` 将数字转换为数字系统中具有给定 `base` 的字符串。
+- `parseInt(str,base)` 在给定的基数(base)下,将字符串 `str` 解析为整数,其中基数范围为:`2 ≤ base ≤ 36`。
+- `num.toString(base)` 在给定的基数(base)下,将数字转换为字符串。
-将 `12pt` 和 `100px` 等值转换为数字:
+将像 `12pt` 和 `100px` 这样的值转换为数字:
-- 使用 `parseInt / parseFloat` 进行 `软` 转换,它从字符串中读取一个数字,然后返回错误发生前可以读取的值。
+- 使用 `parseInt / parseFloat` 进行“软”转换,它从字符串中读取一个数字,然后返回在错误发生前可以读取到的数字。
-分数:
+对于小数:
-- 使用 `Math.floor`、`Math.ceil`、`Math.trunc`、`Math.round` 或 `num.toFixed(precision)` 截取。
-- 请记住,使用分数时会损失精度。
+- 使用 `Math.floor`、`Math.ceil`、`Math.trunc`、`Math.round` 或 `num.toFixed(precision)` 进行舍入。
+- 请记住,使用小数时也会损失精度。
更多的数学函数:
-- 需要时请参阅 [Math](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Math) 对象,虽然这个文档非常小,但是它可以满足基础的要求。
+- 需要时请参阅 [Math](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Math) 对象文档。虽然这个文档非常小,但是可以满足基本的需求。