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 f2c81437d..8252babdd 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
@@ -1,12 +1,12 @@
```js run demo
-let a = +prompt("The first number?", "");
-let b = +prompt("The second number?", "");
+let a = +prompt("Số đầu tiên?", "");
+let b = +prompt("Số thứ hai?", "");
alert( a + b );
```
-Note the unary plus `+` before `prompt`. It immediately converts the value to a number.
+Lưu ý dấu cộng đơn nguyên `+` trước `prompt`. Nó ngay lập tức chuyển đổi giá trị thành một số.
-Otherwise, `a` and `b` would be string their sum would be their concatenation, that is: `"1" + "2" = "12"`.
\ No newline at end of file
+Nếu không, `a` và `b` sẽ là chuỗi, tổng của chúng sẽ là phần nối của chúng, nghĩa là: `"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 780126640..6e6677189 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
---
-# Sum numbers from the visitor
+# Tổng số từ khách truy cập
-Create a script that prompts the visitor to enter two numbers and then shows their sum.
+Tạo tập lệnh nhắc khách nhập hai số rồi hiển thị tổng của chúng.
[demo]
-P.S. There is a gotcha with types.
+Tái bút: Có một gotcha với các loại.
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 a17a4671a..6e11c35e2 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,33 +1,33 @@
-Internally the decimal fraction `6.35` is an endless binary. As always in such cases, it is stored with a precision loss.
+Bên trong, phân số thập phân `6,35` là một số nhị phân vô tận. Như mọi khi trong những trường hợp như vậy, nó được lưu trữ với độ chính xác bị mất.
-Let's see:
+Hãy xem nào:
```js run
alert( 6.35.toFixed(20) ); // 6.34999999999999964473
```
-The precision loss can cause both increase and decrease of a number. In this particular case the number becomes a tiny bit less, that's why it rounded down.
+Mất độ chính xác có thể gây ra cả tăng và giảm số. Trong trường hợp cụ thể này, con số trở nên nhỏ hơn một chút, đó là lý do tại sao nó được làm tròn xuống.
-And what's for `1.35`?
+Và `1,35` là gì?
```js run
alert( 1.35.toFixed(20) ); // 1.35000000000000008882
```
-Here the precision loss made the number a little bit greater, so it rounded up.
+Ở đây, độ chính xác bị mất khiến con số lớn hơn một chút, vì vậy nó được làm tròn lên.
-**How can we fix the problem with `6.35` if we want it to be rounded the right way?**
+**Làm cách nào để chúng ta có thể khắc phục sự cố với `6.35` nếu chúng ta muốn nó được làm tròn đúng cách?**
-We should bring it closer to an integer prior to rounding:
+Chúng ta nên đưa nó đến gần một số nguyên hơn trước khi làm tròn:
```js run
alert( (6.35 * 10).toFixed(20) ); // 63.50000000000000000000
```
-Note that `63.5` has no precision loss at all. That's because the decimal part `0.5` is actually `1/2`. Fractions divided by powers of `2` are exactly represented in the binary system, now we can round it:
+Lưu ý rằng `63,5` hoàn toàn không mất độ chính xác. Đó là vì phần thập phân `0,5` thực ra là `1/2`. Các phân số chia cho lũy thừa của `2` được biểu diễn chính xác trong hệ thống nhị phân, bây giờ chúng ta có thể làm tròn nó:
```js run
-alert( Math.round(6.35 * 10) / 10); // 6.35 -> 63.5 -> 64(rounded) -> 6.4
+alert( Math.round(6.35 * 10) / 10 ); // 6.35 -> 63.5 -> 64(làm tròn) -> 6.4
```
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 568c26480..bb6eaca9f 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
@@ -2,21 +2,21 @@ importance: 4
---
-# Why 6.35.toFixed(1) == 6.3?
+# Tại sao 6.35.toFixed(1) == 6.3?
-According to the documentation `Math.round` and `toFixed` both round to the nearest number: `0..4` lead down while `5..9` lead up.
+Theo tài liệu `Math.round` và `toFixed` đều làm tròn đến số gần nhất: `0..4` dẫn đầu xuống trong khi `5..9` dẫn đầu.
-For instance:
+Ví dụ:
```js run
alert( 1.35.toFixed(1) ); // 1.4
```
-In the similar example below, why is `6.35` rounded to `6.3`, not `6.4`?
+Trong ví dụ tương tự bên dưới, tại sao `6.35` được làm tròn thành `6.3` chứ không phải `6.4`?
```js run
alert( 6.35.toFixed(1) ); // 6.3
```
-How to round `6.35` the right way?
+Làm thế nào để làm tròn `6,35` đúng cách?
diff --git a/1-js/05-data-types/02-number/3-repeat-until-number/_js.view/solution.js b/1-js/05-data-types/02-number/3-repeat-until-number/_js.view/solution.js
index a8c30c010..2e0cdbf0a 100644
--- a/1-js/05-data-types/02-number/3-repeat-until-number/_js.view/solution.js
+++ b/1-js/05-data-types/02-number/3-repeat-until-number/_js.view/solution.js
@@ -3,10 +3,10 @@ function readNumber() {
let num;
do {
- num = prompt("Enter a number please?", 0);
+ num = prompt("Vui lòng nhập số?", 0);
} while ( !isFinite(num) );
if (num === null || num === '') return null;
return +num;
-}
\ 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 005116d17..eef999913 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
@@ -4,7 +4,7 @@ function readNumber() {
let num;
do {
- num = prompt("Enter a number please?", 0);
+ num = prompt("Vui lòng nhập số?", 0);
} while ( !isFinite(num) );
if (num === null || num === '') return null;
@@ -15,9 +15,9 @@ function readNumber() {
alert(`Read: ${readNumber()}`);
```
-The solution is a little bit more intricate that it could be because we need to handle `null`/empty lines.
+Giải pháp phức tạp hơn một chút có thể là do chúng ta cần xử lý `null`/dòng trống.
-So we actually accept the input until it is a "regular number". Both `null` (cancel) and empty line also fit that condition, because in numeric form they are `0`.
+Vì vậy, chúng ta thực sự chấp nhận đầu vào cho đến khi nó là "số thông thường". Cả `null` (hủy) và dòng trống cũng phù hợp với điều kiện đó, vì ở dạng số chúng là `0`.
-After we stopped, we need to treat `null` and empty line specially (return `null`), because converting them to a number would return `0`.
+Sau khi dừng, chúng ta cần xử lý đặc biệt `null` và dòng trống (trả về `null`), vì chuyển đổi chúng thành một số sẽ trả về `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 9b172fa8a..f9680dd19 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,13 +2,13 @@ importance: 5
---
-# Repeat until the input is a number
+# Lặp lại cho đến khi đầu vào là một số
-Create a function `readNumber` which prompts for a number until the visitor enters a valid numeric value.
+Tạo một hàm `readNumber` để nhắc nhập một số cho đến khi khách truy cập nhập một giá trị số hợp lệ.
-The resulting value must be returned as a number.
+Giá trị kết quả phải được trả về dưới dạng số.
-The visitor can also stop the process by entering an empty line or pressing "CANCEL". In that case, the function should return `null`.
+Khách truy cập cũng có thể dừng quá trình bằng cách nhập một dòng trống hoặc nhấn "HỦY". Trong trường hợp đó, hàm sẽ trả về `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 8bc55bd02..3f3970d48 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 @@
-That's because `i` would never equal `10`.
+Đó là bởi vì `i` sẽ không bao giờ bằng `10`.
-Run it to see the *real* values of `i`:
+Chạy nó để xem các giá trị *thực* của `i`:
```js run
let i = 0;
@@ -10,8 +10,8 @@ while (i < 11) {
}
```
-None of them is exactly `10`.
+Không cái nào trong số chúng chính xác là `10`.
-Such things happen because of the precision losses when adding fractions like `0.2`.
+Những điều như vậy xảy ra do mất độ chính xác khi cộng các phân số như `0,2`.
-Conclusion: evade equality checks when working with decimal fractions.
\ No newline at end of file
+Kết luận: Tránh kiểm tra bằng nhau khi làm việc với phân số thập phân.
diff --git a/1-js/05-data-types/02-number/4-endless-loop-error/task.md b/1-js/05-data-types/02-number/4-endless-loop-error/task.md
index 592ece31c..0f876a448 100644
--- a/1-js/05-data-types/02-number/4-endless-loop-error/task.md
+++ b/1-js/05-data-types/02-number/4-endless-loop-error/task.md
@@ -2,9 +2,9 @@ importance: 4
---
-# An occasional infinite loop
+# Một vòng lặp vô hạn không thường xuyên
-This loop is infinite. It never ends. Why?
+Vòng lặp này là vô tận. No không bao giờ kết thúc. Tại sao?
```js
let i = 0;
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 8736c3d56..bd9bc8488 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,11 +1,11 @@
-We need to "map" all values from the interval 0..1 into values from `min` to `max`.
+Chúng ta cần "sắp xếp" tất cả các giá trị từ khoảng 0..1 thành các giá trị từ `min` đến `max`.
-That can be done in two stages:
+Điều đó có thể được thực hiện trong hai giai đoạn:
-1. If we multiply a random number from 0..1 by `max-min`, then the interval of possible values increases `0..1` to `0..max-min`.
-2. Now if we add `min`, the possible interval becomes from `min` to `max`.
+1. Nếu chúng ta nhân một số ngẫu nhiên từ 0..1 với `max-min`, thì khoảng các giá trị có thể tăng `0..1` thành `0..max-min`.
+2. Bây giờ nếu chúng ta thêm `min`, thì khoảng thời gian có thể sẽ trở thành từ `min` đến `max`.
-The function:
+Hàm:
```js run
function random(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 7037cfcbb..50820f4e0 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,13 +2,13 @@ importance: 2
---
-# A random number from min to max
+# Một số ngẫu nhiên từ tối thiểu đến tối đa
-The built-in function `Math.random()` creates a random value from `0` to `1` (not including `1`).
+Hàm tích hợp `Math.random()` tạo một giá trị ngẫu nhiên từ `0` đến `1` (không bao gồm `1`).
-Write the function `random(min, max)` to generate a random floating-point number from `min` to `max` (not including `max`).
+Viết hàm `random(min, max)` để tạo một số dấu phẩy động ngẫu nhiên từ `min` đến `max` (không bao gồm `max`).
-Examples of its work:
+Ví dụ về công việc của nó:
```js
alert( random(1, 5) ); // 1.2345623452
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 0950ff812..4cbbc55dc 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 @@
-# The simple but wrong solution
+# Giải pháp đơn giản nhưng sai lầm
-The simplest, but wrong solution would be to generate a value from `min` to `max` and round it:
+Giải pháp đơn giản nhưng sai lầm là tạo ra một giá trị từ `min` đến `max` và làm tròn giá trị đó:
```js run
function randomInteger(min, max) {
@@ -11,11 +11,11 @@ function randomInteger(min, max) {
alert( randomInteger(1, 3) );
```
-The function works, but it is incorrect. The probability to get edge values `min` and `max` is two times less than any other.
+Hàm hoạt động, nhưng nó không chính xác. Xác suất nhận được các giá trị cạnh `min` và `max` thấp hơn hai lần so với bất kỳ giá trị nào khác.
-If you run the example above many times, you would easily see that `2` appears the most often.
+Nếu chạy ví dụ trên nhiều lần, bạn sẽ dễ dàng thấy rằng `2` xuất hiện thường xuyên nhất.
-That happens because `Math.round()` gets random numbers from the interval `1..3` and rounds them as follows:
+Điều đó xảy ra vì `Math.round()` nhận các số ngẫu nhiên từ khoảng `1..3` và làm tròn chúng như sau:
```js no-beautify
values from 1 ... to 1.4999999999 become 1
@@ -23,16 +23,16 @@ values from 1.5 ... to 2.4999999999 become 2
values from 2.5 ... to 2.9999999999 become 3
```
-Now we can clearly see that `1` gets twice less values than `2`. And the same with `3`.
+Bây giờ chúng ta có thể thấy rõ ràng rằng `1` có giá trị ít hơn `2` hai lần. Và tương tự với `3`.
-# The correct solution
+# Giải pháp chính xác
-There are many correct solutions to the task. One of them is to adjust interval borders. To ensure the same intervals, we can generate values from `0.5 to 3.5`, thus adding the required probabilities to the edges:
+Có nhiều giải pháp chính xác cho nhiệm vụ. Một trong số đó là điều chỉnh đường viền khoảng cách. Để đảm bảo các khoảng giống nhau, chúng ta có thể tạo các giá trị từ `0,5 đến 3,5`, do đó thêm các xác suất cần thiết cho các cạnh:
```js run
*!*
function randomInteger(min, max) {
- // now rand is from (min-0.5) to (max+0.5)
+ // bây giờ rand đến từ (min-0.5) to (max+0.5)
let rand = min - 0.5 + Math.random() * (max - min + 1);
return Math.round(rand);
}
@@ -41,12 +41,12 @@ function randomInteger(min, max) {
alert( randomInteger(1, 3) );
```
-An alternative way could be to use `Math.floor` for a random number from `min` to `max+1`:
+Một cách khác có thể là sử dụng `Math.floor` cho một số ngẫu nhiên từ `min` đến `max+1`: 45
```js run
*!*
function randomInteger(min, max) {
- // here rand is from min to (max+1)
+ // ở đây rand là từ tối thiểu đến (tối đa + 1)
let rand = min + Math.random() * (max + 1 - min);
return Math.floor(rand);
}
@@ -55,7 +55,7 @@ function randomInteger(min, max) {
alert( randomInteger(1, 3) );
```
-Now all intervals are mapped this way:
+Bây giờ tất cả các khoảng thời gian được sắp xếp theo cách này:
```js no-beautify
values from 1 ... to 1.9999999999 become 1
@@ -63,4 +63,4 @@ values from 2 ... to 2.9999999999 become 2
values from 3 ... to 3.9999999999 become 3
```
-All intervals have the same length, making the final distribution uniform.
+Tất cả các khoảng có cùng độ dài, làm cho phân phối cuối cùng đồng nhất.
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 4ac7b5fbb..248cba3a3 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,14 +2,14 @@ importance: 2
---
-# A random integer from min to max
+# Một số nguyên ngẫu nhiên từ tối thiểu đến tối đa
-Create a function `randomInteger(min, max)` that generates a random *integer* number from `min` to `max` including both `min` and `max` as possible values.
+Tạo một hàm `randomInteger(min, max)` để tạo ra một số *số nguyên* ngẫu nhiên từ `min` đến `max` bao gồm cả `min` và `max` như các giá trị có thể.
-Any number from the interval `min..max` must appear with the same probability.
+Bất kỳ số nào trong khoảng `min..max` phải xuất hiện với xác suất như nhau.
-Examples of its work:
+Ví dụ về công việc của nó:
```js
alert( randomInteger(1, 5) ); // 1
@@ -17,4 +17,4 @@ alert( randomInteger(1, 5) ); // 3
alert( randomInteger(1, 5) ); // 5
```
-You can use the solution of the [previous task](info:task/random-min-max) as the base.
+Bạn có thể sử dụng giải pháp của [nhiệm vụ trước](info:task/random-min-max) làm cơ sở.
diff --git a/1-js/05-data-types/02-number/article.md b/1-js/05-data-types/02-number/article.md
index 6fd513f43..fae3ca888 100644
--- a/1-js/05-data-types/02-number/article.md
+++ b/1-js/05-data-types/02-number/article.md
@@ -1,98 +1,99 @@
-# Numbers
+# Số
-In modern JavaScript, there are two types of numbers:
+Trong JavaScript hiện đại, có hai loại số:
-1. Regular numbers in JavaScript are stored in 64-bit format [IEEE-754](https://en.wikipedia.org/wiki/IEEE_754-2008_revision), also known as "double precision floating point numbers". These are numbers that we're using most of the time, and we'll talk about them in this chapter.
+1. Các số thông thường trong JavaScript được lưu trữ ở định dạng 64-bit [IEEE-754](https://en.wikipedia.org/wiki/IEEE_754), còn được gọi là "số dấu phẩy động có độ chính xác kép". Đây là những con số mà chúng ta sử dụng trong phần lớn thời gian và chúng ta sẽ nói về chúng trong chương này.
-2. BigInt numbers, to represent integers of arbitrary length. They are sometimes needed, because a regular number can't exceed 253 or be less than -253. As bigints are used in few special areas, we devote them a special chapter .
+2. Số BigInt đại diện cho số nguyên có độ dài tùy ý. Đôi khi chúng cần thiết vì một số nguyên thông thường không thể an toàn vượt quá (253-1) hoặc nhỏ hơn -(253 sup>-1), như chúng ta đã đề cập trước đó trong chương . Vì bigint được sử dụng trong một vài lĩnh vực đặc biệt nên chúng ta dành cho chúng một chương đặc biệt .
-So here we'll talk about regular numbers. Let's expand our knowledge of them.
+Vì vậy, ở đây chúng ta sẽ nói về các số thông thường. Hãy mở rộng kiến thức của chúng ta về chúng.
-## More ways to write a number
-
-Imagine we need to write 1 billion. The obvious way is:
+## Nhiều cách khác để viết một số
```js
let billion = 1000000000;
```
-We also can use underscore `_` as the separator:
+Chúng ta cũng có thể sử dụng dấu gạch dưới `_` làm dấu phân cách:
```js
let billion = 1_000_000_000;
```
-Here the underscore `_` plays the role of the "syntactic sugar", it makes the number more readable. The JavaScript engine simply ignores `_` between digits, so it's exactly the same one billion as above.
+Ở đây, dấu gạch dưới `_` đóng vai trò của "[đường cú pháp](https://en.wikipedia.org/wiki/Syntactic_sugar)", nó làm cho số dễ đọc hơn. JavaScript engine chỉ cần bỏ qua `_` giữa các chữ số, do đó, nó chính xác là một tỷ như trên.
-In real life though, we try to avoid writing long sequences of zeroes. We're too lazy for that. We'll try to write something like `"1bn"` for a billion or `"7.3bn"` for 7 billion 300 million. The same is true for most large numbers.
+Tuy nhiên, trong cuộc sống thực, chúng ta cố gắng tránh viết các chuỗi số 0 dài. Chúng ta quá lười biếng cho việc đó. Chúng ta sẽ cố gắng viết thứ gì đó như `"1 tỷ"` cho một tỷ hoặc `"7,3 tỷ"` cho 7 tỷ 300 triệu. Điều này cũng đúng với hầu hết các số lớn.
-In JavaScript, we can shorten a number by appending the letter `"e"` to it and specifying the zeroes count:
+Trong JavaScript, chúng ta có thể rút ngắn một số bằng cách thêm chữ cái `"e"` vào nó và chỉ định số lượng số 0:
```js run
-let billion = 1e9; // 1 billion, literally: 1 and 9 zeroes
+let billion = 1e9; // 1 tỷ, nghĩa đen: 1 và 9 số 0
-alert( 7.3e9 ); // 7.3 billions (same as 7300000000 or 7_300_000_000)
+alert( 7.3e9 ); // 7,3 tỷ (giống như 7300000000 hoặc 7_300_000_000)
```
-In other words, `e` multiplies the number by `1` with the given zeroes count.
+Nói cách khác, `e` nhân số với `1` với số lượng các số 0 đã cho.
```js
-1e3 = 1 * 1000 // e3 means *1000
-1.23e6 = 1.23 * 1000000 // e6 means *1000000
+1e3 === 1 * 1000; // e3 nghĩa là *1000
+1.23e6 === 1.23 * 1000000; // e6 nghĩa là *1000000
```
-Now let's write something very small. Say, 1 microsecond (one millionth of a second):
+Bây giờ chúng ta hãy viết một cái gì đó rất nhỏ. Giả sử, 1 micro giây (một phần triệu giây):
```js
-let ms = 0.000001;
+let mcs = 0.000001;
```
-Just like before, using `"e"` can help. If we'd like to avoid writing the zeroes explicitly, we could say the same as:
+Giống như trước đây, việc sử dụng `"e"` có thể hữu ích. Nếu chúng ta muốn tránh viết các số 0 một cách rõ ràng, chúng ta có thể viết tương tự như:
```js
-let ms = 1e-6; // six zeroes to the left from 1
+let mcs = 1e-6; // năm số không ở bên trái từ 1
```
-If we count the zeroes in `0.000001`, there are 6 of them. So naturally it's `1e-6`.
+Nếu chúng ta đếm các số 0 trong `0,000001`, thì có 6 số trong số đó. Vì vậy, tự nhiên đó là `1e-6`.
-In other words, a negative number after `"e"` means a division by 1 with the given number of zeroes:
+Nói cách khác, một số âm sau `"e"` có nghĩa là phép chia cho 1 với số lượng các số 0 đã cho:
```js
-// -3 divides by 1 with 3 zeroes
-1e-3 = 1 / 1000 (=0.001)
+// -3 chia cho 1 với 3 số 0
+1e-3 === 1 / 1000; // 0.001
+
+// -6 chia hết cho 1 với 6 chữ số 0
+1.23e-6 === 1.23 / 1000000; // 0.00000123
-// -6 divides by 1 with 6 zeroes
-1.23e-6 = 1.23 / 1000000 (=0.00000123)
+// một ví dụ với một số lớn hơn
+1234e-2 === 1234 / 100; // 12.34, dấu thập phân di chuyển 2 lần
```
-### Hex, binary and octal numbers
+### Số hex, nhị phân và bát phân
-[Hexadecimal](https://en.wikipedia.org/wiki/Hexadecimal) numbers are widely used in JavaScript to represent colors, encode characters, and for many other things. So naturally, there exists a shorter way to write them: `0x` and then the number.
+[Hệ thập lục phân](https://vi.wikipedia.org/wiki/Hệ_thập_lục_phân) được sử dụng rộng rãi trong JavaScript để thể hiện màu sắc, ký tự mã hóa và cho nhiều thứ khác. Vì vậy, một cách tự nhiên, tồn tại một cách viết ngắn hơn: `0x` và sau đó là số.
-For instance:
+Ví dụ:
```js run
alert( 0xff ); // 255
-alert( 0xFF ); // 255 (the same, case doesn't matter)
+alert( 0xFF ); // 255 (giống nhau, viết hoa không quan trọng)
```
-Binary and octal numeral systems are rarely used, but also supported using the `0b` and `0o` prefixes:
+Các hệ thống số nhị phân và bát phân hiếm khi được sử dụng, nhưng cũng được hỗ trợ bằng cách sử dụng tiền tố `0b` và `0o`:
```js run
-let a = 0b11111111; // binary form of 255
-let b = 0o377; // octal form of 255
+let a = 0b11111111; // dạng nhị phân của 255
+let b = 0o377; // dạng bát phân của 255
-alert( a == b ); // true, the same number 255 at both sides
+alert( a == b ); // true, cùng một số 255 ở cả hai bên
```
-There are only 3 numeral systems with such support. For other numeral systems, we should use the function `parseInt` (which we will see later in this chapter).
+Chỉ có 3 hệ thống số với sự hỗ trợ như vậy. Đối với các hệ thống số khác, chúng ta nên sử dụng hàm `parseInt` (mà chúng ta sẽ thấy ở phần sau của chương này).
## toString(base)
-The method `num.toString(base)` returns a string representation of `num` in the numeral system with the given `base`.
+Phương thức `num.toString(base)` trả về một chuỗi đại diện cho `num` trong hệ thống số với `base` đã cho.
-For example:
+Ví dụ:
```js run
let num = 255;
@@ -100,307 +101,334 @@ alert( num.toString(16) ); // ff
alert( num.toString(2) ); // 11111111
```
-The `base` can vary from `2` to `36`. By default it's `10`.
+`base` có thể thay đổi từ `2` đến `36`. Theo mặc định, đó là `10`.
-Common use cases for this are:
+Các trường hợp sử dụng phổ biến cho việc này là:
-- **base=16** is used for hex colors, character encodings etc, digits can be `0..9` or `A..F`.
-- **base=2** is mostly for debugging bitwise operations, digits can be `0` or `1`.
-- **base=36** is the maximum, digits can be `0..9` or `A..Z`. The whole latin alphabet is used to represent a number. A funny, but useful case for `36` is when we need to turn a long numeric identifier into something shorter, for example to make a short url. Can simply represent it in the numeral system with base `36`:
+- **base=16** được sử dụng cho màu hex, mã hóa ký tự, v.v., các chữ số có thể là `0..9` hoặc `A..F`.
+- **base=2** chủ yếu dùng để gỡ lỗi các hoạt động theo bit, các chữ số có thể là `0` hoặc `1`.
+- **base=36** là giá trị lớn nhất, các chữ số có thể là `0..9` hoặc `A..Z`. Toàn bộ bảng chữ cái Latinh được sử dụng để đại diện cho một số. Một trường hợp buồn cười nhưng hữu ích cho `36` là khi chúng ta cần biến một định danh số dài thành một số khác ngắn hơn, chẳng hạn như để tạo một url ngắn. Có thể đơn giản biểu diễn nó trong hệ thống số với cơ số `36`:
```js run
alert( 123456..toString(36) ); // 2n9c
```
-```warn header="Two dots to call a method"
-Please note that two dots in `123456..toString(36)` is not a typo. If we want to call a method directly on a number, like `toString` in the example above, then we need to place two dots `..` after it.
+```warn header="Hai dấu chấm để gọi một phương thức"
+Hãy lưu ý rằng hai dấu chấm trong `123456..toString(36)` không phải là lỗi đánh máy. Nếu chúng ta muốn gọi một phương thức trực tiếp trên một số, như `toString` trong ví dụ trên, thì chúng ta cần đặt hai dấu chấm `..` sau nó.
+
+Nếu chúng ta đặt một dấu chấm đơn: `123456.toString(36)`, thì sẽ xảy ra lỗi, vì cú pháp JavaScript ngụ ý phần thập phân sau dấu chấm đầu tiên. Và nếu chúng ta đặt thêm một dấu chấm, thì JavaScript sẽ biết rằng phần thập phân trống và bây giờ sẽ thực hiện phương thức.
-If we placed a single dot: `123456.toString(36)`, then there would be an error, because JavaScript syntax implies the decimal part after the first dot. And if we place one more dot, then JavaScript knows that the decimal part is empty and now goes the method.
+Cũng có thể viết `(123456).toString(36)`.
-Also could write `(123456).toString(36)`.
```
-## Rounding
+## Làm tròn
-One of the most used operations when working with numbers is rounding.
+Một trong những thao tác được sử dụng nhiều nhất khi làm việc với số là làm tròn số.
-There are several built-in functions for rounding:
+Có một số chức năng tích hợp để làm tròn:
`Math.floor`
-: Rounds down: `3.1` becomes `3`, and `-1.1` becomes `-2`.
+: Làm tròn xuống: `3.1` trở thành `3` và `-1.1` trở thành `-2`.
`Math.ceil`
-: Rounds up: `3.1` becomes `4`, and `-1.1` becomes `-1`.
+: Làm tròn lên: `3.1` trở thành `4` và `-1.1` trở thành `-1`.
`Math.round`
-: Rounds to the nearest integer: `3.1` becomes `3`, `3.6` becomes `4`, the middle case: `3.5` rounds up to `4` too.
+: Làm tròn đến số nguyên gần nhất: `3.1` trở thành `3`, `3.6` trở thành `4`, trường hợp ở giữa: `3.5` cũng làm tròn lên `4`.
-`Math.trunc` (not supported by Internet Explorer)
-: Removes anything after the decimal point without rounding: `3.1` becomes `3`, `-1.1` becomes `-1`.
+`Math.trunc` (không được Internet Explorer hỗ trợ)
+: Xóa mọi thứ sau dấu thập phân mà không làm tròn: `3.1` trở thành `3`, `-1.1` trở thành `-1`.
-Here's the table to summarize the differences between them:
+Đây là bảng để tóm tắt sự khác biệt giữa chúng:
-| | `Math.floor` | `Math.ceil` | `Math.round` | `Math.trunc` |
+| | `Math.floor` | `Math.ceil` | `Math.round` | `Math.trunc` |
|---|---------|--------|---------|---------|
-|`3.1`| `3` | `4` | `3` | `3` |
-|`3.6`| `3` | `4` | `4` | `3` |
-|`-1.1`| `-2` | `-1` | `-1` | `-1` |
-|`-1.6`| `-2` | `-1` | `-2` | `-1` |
+|`3.1`| `3` | `4` | `3` | `3` |
+|`3.6`| `3` | `4` | `4` | `3` |
+|`-1.1`| `-2` | `-1` | `-1` | `-1` |
+|`-1.6`| `-2` | `-1` | `-2` | `-1` |
-These functions cover all of the possible ways to deal with the decimal part of a number. But what if we'd like to round the number to `n-th` digit after the decimal?
+Các hàm này bao gồm tất cả các cách có thể để xử lý phần thập phân của một số. Nhưng nếu chúng ta muốn làm tròn số đến chữ số `thứ n` sau dấu thập phân thì sao?
-For instance, we have `1.2345` and want to round it to 2 digits, getting only `1.23`.
+Chẳng hạn, chúng ta có `1.2345` và muốn làm tròn nó thành 2 chữ số, chỉ nhận được `1.23`.
-There are two ways to do so:
+Có hai cách để làm như vậy:
-1. Multiply-and-divide.
+1. Nhân chia.
- For example, to round the number to the 2nd digit after the decimal, we can multiply the number by `100` (or a bigger power of 10), call the rounding function and then divide it back.
+ Ví dụ: để làm tròn số đến chữ số thứ 2 sau dấu thập phân, chúng ta có thể nhân số đó với `100`, gọi hàm làm tròn rồi chia lại.
```js run
let num = 1.23456;
alert( Math.round(num * 100) / 100 ); // 1.23456 -> 123.456 -> 123 -> 1.23
```
-2. The method [toFixed(n)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toFixed) rounds the number to `n` digits after the point and returns a string representation of the result.
+2. Phương thức [toFixed(n)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toFixed) làm tròn số thành `n` chữ số sau dấu chấm và trả về một chuỗi đại diện của kết quả.
```js run
let num = 12.34;
alert( num.toFixed(1) ); // "12.3"
```
- This rounds up or down to the nearest value, similar to `Math.round`:
+ Điều này làm tròn lên hoặc xuống đến giá trị gần nhất, tương tự như `Math.round`:
```js run
let num = 12.36;
alert( num.toFixed(1) ); // "12.4"
```
- Please note that result of `toFixed` is a string. If the decimal part is shorter than required, zeroes are appended to the end:
+ Hãy lưu ý rằng kết quả của `toFixed` là một chuỗi. Nếu phần thập phân ngắn hơn yêu cầu, các số 0 sẽ được thêm vào cuối:
```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", thêm số 0 để tạo thành chính xác 5 chữ số
```
- We can convert it to a number using the unary plus or a `Number()` call: `+num.toFixed(5)`.
+ Chúng ta có thể chuyển đổi nó thành một số bằng cách sử dụng phép cộng đơn nguyên hoặc lệnh gọi `Number()`, ví dụ viết `+num.toFixed(5)`.
-## Imprecise calculations
+## Tính toán không chính xác
-Internally, a number is represented in 64-bit format [IEEE-754](https://en.wikipedia.org/wiki/IEEE_754-2008_revision), so there are exactly 64 bits to store a number: 52 of them are used to store the digits, 11 of them store the position of the decimal point (they are zero for integer numbers), and 1 bit is for the sign.
+Bên trong, một số được thể hiện ở định dạng 64-bit [IEEE-754](https://en.wikipedia.org/wiki/IEEE_754), do đó, có chính xác 64 bit để lưu trữ một số: 52 bit trong số đó được sử dụng để lưu trữ các chữ số, 11 trong số chúng lưu trữ vị trí của dấu thập phân và 1 bit dành cho dấu.
-If a number is too big, it would overflow the 64-bit storage, potentially giving an infinity:
+Nếu một số thực sự lớn, nó có thể tràn bộ nhớ 64-bit và trở thành một giá trị số đặc biệt `Infinity`:
```js run
-alert( 1e500 ); // Infinity
+alert( 1e500 ); // Vô hạn
```
-What may be a little less obvious, but happens quite often, is the loss of precision.
+Điều có thể ít rõ ràng hơn một chút, nhưng lại xảy ra khá thường xuyên, đó là sự mất đi độ chính xác.
-Consider this (falsy!) test:
+Hãy xem xét bài kiểm tra bằng nhau (sai!) này:
```js run
alert( 0.1 + 0.2 == 0.3 ); // *!*false*/!*
```
-That's right, if we check whether the sum of `0.1` and `0.2` is `0.3`, we get `false`.
+Đúng vậy, nếu chúng ta kiểm tra xem tổng của `0,1` và `0,2` có phải là `0,3` hay không, chúng ta sẽ nhận được `false`.
-Strange! What is it then if not `0.3`?
+Lạ lùng! Vậy thì đó là gì nếu không phải là `0,3`?
```js run
alert( 0.1 + 0.2 ); // 0.30000000000000004
```
-Ouch! There are more consequences than an incorrect comparison here. Imagine you're making an e-shopping site and the visitor puts `$0.10` and `$0.20` goods into their cart. The order total will be `$0.30000000000000004`. That would surprise anyone.
+Ôi! Hãy tưởng tượng bạn đang tạo một trang web mua sắm điện tử và khách truy cập đặt hàng hóa `$0,1` và `$0,2` vào giỏ hàng của họ. Tổng đơn đặt hàng sẽ là `$0,30000000000000004`. Điều đó sẽ làm bất cứ ai ngạc nhiên.
-But why does this happen?
+Nhưng tại sao điều này lại xảy ra?
-A number is stored in memory in its binary form, a sequence of bits - ones and zeroes. But fractions like `0.1`, `0.2` that look simple in the decimal numeric system are actually unending fractions in their binary form.
+Một số được lưu trữ trong bộ nhớ ở dạng nhị phân, một chuỗi các bit - số một và số không. Nhưng các phân số như `0,1`, `0,2` trông có vẻ đơn giản trong hệ thống số thập phân thực ra là các phân số vô tận ở dạng nhị phân của chúng.
-In other words, what is `0.1`? It is one divided by ten `1/10`, one-tenth. In decimal numeral system such numbers are easily representable. Compare it to one-third: `1/3`. It becomes an endless fraction `0.33333(3)`.
+`0,1` là gì? Nó là một chia cho mười `1/10`, một phần mười. Trong hệ thống số thập phân, những số như vậy có thể biểu diễn dễ dàng. So sánh nó với một phần ba: `1/3`. Nó trở thành phân số vô tận `0,33333(3)`.
-So, division by powers `10` is guaranteed to work well in the decimal system, but division by `3` is not. For the same reason, in the binary numeral system, the division by powers of `2` is guaranteed to work, but `1/10` becomes an endless binary fraction.
+Vì vậy, phép chia cho lũy thừa `10` được đảm bảo hoạt động tốt trong hệ thập phân, nhưng phép chia cho `3` thì không. Vì lý do tương tự, trong hệ thống số nhị phân, phép chia cho lũy thừa của `2` được đảm bảo hoạt động, nhưng `1/10` trở thành một phân số nhị phân vô tận.
-There's just no way to store *exactly 0.1* or *exactly 0.2* using the binary system, just like there is no way to store one-third as a decimal fraction.
+Không có cách nào để lưu trữ *chính xác 0,1* hoặc *chính xác 0,2* bằng hệ thống nhị phân, giống như không có cách nào lưu trữ một phần ba dưới dạng phân số thập phân.
-The numeric format IEEE-754 solves this by rounding to the nearest possible number. These rounding rules normally don't allow us to see that "tiny precision loss", but it exists.
+Định dạng số IEEE-754 giải quyết vấn đề này bằng cách làm tròn đến số gần nhất có thể. Các quy tắc làm tròn này thường không cho phép chúng ta thấy "sai số nhỏ" đó, nhưng nó tồn tại.
-We can see this in action:
+Chúng ta có thể thấy điều này trong hành động:
```js run
alert( 0.1.toFixed(20) ); // 0.10000000000000000555
```
-And when we sum two numbers, their "precision losses" add up.
+Và khi chúng ta tính tổng hai số, "sai số chính xác" của chúng sẽ cộng lại.
-That's why `0.1 + 0.2` is not exactly `0.3`.
+Đó là lý do tại sao `0,1 + 0,2` không chính xác là `0,3`.
-```smart header="Not only JavaScript"
-The same issue exists in many other programming languages.
+```smart header="Không chỉ JavaScript"
+Vấn đề tương tự tồn tại trong nhiều ngôn ngữ lập trình khác.
-PHP, Java, C, Perl, Ruby give exactly the same result, because they are based on the same numeric format.
+PHP, Java, C, Perl, Ruby cho kết quả chính xác như nhau, bởi vì chúng dựa trên cùng một định dạng số.
```
-Can we work around the problem? Sure, the most reliable method is to round the result with the help of a method [toFixed(n)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toFixed):
+Chúng ta có thể giải quyết vấn đề không? Chắc chắn rồi, phương pháp đáng tin cậy nhất là làm tròn kết quả với sự trợ giúp của một phương thức [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
+alert( sum.toFixed(2) ); // "0.30"
```
-Please note that `toFixed` always returns a string. It ensures that it has 2 digits after the decimal point. That's actually convenient if we have an e-shopping and need to show `$0.30`. For other cases, we can use the unary plus to coerce it into a number:
+Hãy lưu ý rằng `toFixed` luôn trả về một chuỗi. Nó đảm bảo rằng nó có 2 chữ số sau dấu thập phân. Điều đó thực sự tiện lợi nếu chúng ta có một trang mua sắm điện tử và cần hiển thị `$0,3`. Đối với các trường hợp khác, chúng ta có thể sử dụng dấu cộng đơn nguyên để biến nó thành một số:
```js run
let sum = 0.1 + 0.2;
alert( +sum.toFixed(2) ); // 0.3
```
-We also can temporarily multiply the numbers by 100 (or a bigger number) to turn them into integers, do the maths, and then divide back. Then, as we're doing maths with integers, the error somewhat decreases, but we still get it on division:
+Chúng ta cũng có thể tạm thời nhân các số với 100 (hoặc một số lớn hơn) để biến chúng thành số nguyên, làm phép tính rồi chia lại. Sau đó, khi chúng ta làm toán với các số nguyên, sai số giảm đi phần nào, nhưng chúng ta vẫn nhận được nó khi chia:
```js run
alert( (0.1 * 10 + 0.2 * 10) / 10 ); // 0.3
alert( (0.28 * 100 + 0.14 * 100) / 100); // 0.4200000000000001
```
-So, multiply/divide approach reduces the error, but doesn't remove it totally.
+Vì vậy, phương pháp nhân/chia giúp giảm lỗi, nhưng không loại bỏ hoàn toàn.
-Sometimes we could try to evade fractions at all. Like if we're dealing with a shop, then we can store prices in cents instead of dollars. But what if we apply a discount of 30%? In practice, totally evading fractions is rarely possible. Just round them to cut "tails" when needed.
+Đôi khi chúng ta có thể cố gắng trốn tránh các phân số. Giống như nếu chúng ta đang giao dịch với một cửa hàng, thì chúng ta có thể lưu trữ giá bằng xu thay vì đô la. Nhưng nếu chúng ta áp dụng giảm giá 30% thì sao? Trong thực tế, hiếm khi có thể trốn tránh hoàn toàn các phân số. Chỉ cần làm tròn chúng để cắt "đuôi" khi cần thiết.
-````smart header="The funny thing"
-Try running this:
+````smart header="Điều buồn cười"
+Hãy thử chạy cái này:
```js run
-// Hello! I'm a self-increasing number!
+// Xin chào! Tôi là một con số tự tăng lên!
alert( 9999999999999999 ); // shows 10000000000000000
```
-This suffers from the same issue: a loss of precision. There are 64 bits for the number, 52 of them can be used to store digits, but that's not enough. So the least significant digits disappear.
+Điều này bị cùng một vấn đề: mất độ chính xác. Có 64 bit cho số, 52 trong số đó có thể được sử dụng để lưu trữ các chữ số, nhưng đó là không đủ. Vì vậy, các chữ số ít quan trọng nhất biến mất.
-JavaScript doesn't trigger an error in such events. It does its best to fit the number into the desired format, but unfortunately, this format is not big enough.
+JavaScript không gây ra lỗi trong các sự kiện như vậy. Nó cố gắng hết sức để khớp số vào định dạng mong muốn, nhưng thật không may, định dạng này không đủ lớn.
````
-```smart header="Two zeroes"
-Another funny consequence of the internal representation of numbers is the existence of two zeroes: `0` and `-0`.
+```smart header="Hai con số 0"
+Một hệ quả buồn cười khác của biểu diễn bên trong các số là sự tồn tại của hai số 0: `0` và `-0`.
-That's because a sign is represented by a single bit, so it can be set or not set for any number including a zero.
+Đó là bởi vì một dấu hiệu được biểu thị bằng một bit duy nhất, vì vậy nó có thể được đặt hoặc không được đặt cho bất kỳ số nào kể cả số không.
-In most cases the distinction is unnoticeable, because operators are suited to treat them as the same.
+Trong hầu hết các trường hợp, sự khác biệt là không đáng chú ý, bởi vì các toán tử phù hợp để coi chúng như nhau.
```
-## Tests: isFinite and isNaN
+## Các bài kiểm tra: isFinite and isNaN
-Remember these two special numeric values?
+Nhớ hai giá trị số đặc biệt này không?
-- `Infinity` (and `-Infinity`) is a special numeric value that is greater (less) than anything.
-- `NaN` represents an error.
+- `Infinity` (và `-Infinity`) là một giá trị số đặc biệt lớn hơn (nhỏ hơn) bất kỳ giá trị nào.
+- `NaN` biểu thị lỗi.
-They belong to the type `number`, but are not "normal" numbers, so there are special functions to check for them:
+Chúng thuộc loại `số`, nhưng không phải là số "bình thường", vì vậy có các hàm đặc biệt để kiểm tra chúng:
-- `isNaN(value)` converts its argument to a number and then tests it for being `NaN`:
+- `isNaN(value)` chuyển đổi đối số của nó thành một số và sau đó kiểm tra xem nó có phải là `NaN`:
```js run
alert( isNaN(NaN) ); // true
alert( isNaN("str") ); // true
```
- But do we need this function? Can't we just use the comparison `=== NaN`? Sorry, but the answer is no. The value `NaN` is unique in that it does not equal anything, including itself:
+ Nhưng chúng ta có cần hàm này không? Chúng ta không thể sử dụng phép so sánh `=== NaN` sao? Thật không may. Giá trị `NaN` là duy nhất ở chỗ nó không bằng bất kỳ giá trị nào, kể cả chính nó:
```js run
alert( NaN === NaN ); // false
```
-- `isFinite(value)` converts its argument to a number and returns `true` if it's a regular number, not `NaN/Infinity/-Infinity`:
+- `isFinite(value)` chuyển đổi đối số của nó thành một số và trả về `true` nếu đó là một số thông thường, không phải `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, bởi vì một giá trị đặc biệt: NaN
+ alert( isFinite(Infinity) ); // false, bởi vì một giá trị đặc biệt: Infinity
```
-Sometimes `isFinite` is used to validate whether a string value is a regular number:
+Đôi khi `isFinite` được sử dụng để xác thực xem giá trị chuỗi có phải là số thông thường hay không:
```js run
-let num = +prompt("Enter a number", '');
+let num = +prompt("Nhập một số", '');
-// will be true unless you enter Infinity, -Infinity or not a number
+// sẽ đúng trừ khi bạn nhập Infinity, -Infinity hoặc không phải là số
alert( isFinite(num) );
```
-Please note that an empty or a space-only string is treated as `0` in all numeric functions including `isFinite`.
+Hãy lưu ý rằng một chuỗi trống hoặc chỉ có khoảng trắng được coi là `0` trong tất cả các hàm số bao gồm `isFinite`.
+
+````smart header="`Number.isNaN` và `Number.isFinite`"
+[Phương thức Number.isNaN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isNaN) và [Number.isFinite](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isFinite) là các phiên bản "nghiêm ngặt" hơn của các hàm `isNaN` và `isFinite`. Chúng không tự động chuyển đổi đối số của chúng thành một số, nhưng thay vào đó kiểm tra xem nó có thuộc loại `number` hay không.
+- `Number.isNaN(value)` trả về `true` nếu đối số thuộc loại `number` và là `NaN`. Trong mọi trường hợp khác, nó trả về `false`.
+ ```js run
+ alert( Number.isNaN(NaN) ); // true
+ alert( Number.isNaN("str" / 2) ); // true
+
+ // Lưu ý sự khác biệt:
+ alert( Number.isNaN("str") ); // false, vì "str" thuộc kiểu chuỗi, không phải kiểu số
+ alert( isNaN("str") ); // true, bởi vì isNaN chuyển đổi chuỗi "str" thành một số và nhận được NaN do chuyển đổi này
+ ```
+- `Number.isFinite(value)` trả về `true` nếu đối số thuộc loại `number` và không phải là `NaN/Infinity/-Infinity`. Trong mọi trường hợp khác, nó trả về `false`.
+ ```js run
+ alert( Number.isFinite(123) ); // true
+ alert( Number.isFinite(Infinity) ); // false
+ alert( Number.isFinite(2 / 0) ); // false
+
+ // Lưu ý sự khác biệt:
+ alert( Number.isFinite("123") ); // false, vì "123" thuộc kiểu chuỗi, không phải kiểu số
+ alert( isFinite("123") ); // true, bởi vì isFinite chuyển chuỗi "123" thành số 123
+ ```
+
+Theo một cách nào đó, `Number.isNaN` và `Number.isFinite` đơn giản và dễ hiểu hơn các hàm `isNaN` và `isFinite`. Tuy nhiên, trên thực tế, `isNaN` và `isFinite` chủ yếu được sử dụng vì chúng ngắn hơn để viết.
+````
+
-```smart header="Compare with `Object.is`"
+```smart header="So sánh với `Object.is`"
-There is a special built-in method [`Object.is`](mdn:js/Object/is) that compares values like `===`, but is more reliable for two edge cases:
+Có một phương thức tích hợp đặc biệt `Object.is` để so sánh các giá trị như `===`, nhưng đáng tin cậy hơn cho hai trường hợp cạnh:
-1. It works with `NaN`: `Object.is(NaN, NaN) === true`, that's a good thing.
-2. Values `0` and `-0` are different: `Object.is(0, -0) === false`, technically that's true, because internally the number has a sign bit that may be different even if all other bits are zeroes.
+1. Nó hoạt động với `NaN`: `Object.is(NaN, NaN) === true`, đó là một điều tốt.
+2. Các giá trị `0` và `-0` là khác nhau: `Object.is(0, -0) === false`, về mặt kỹ thuật, điều đó đúng, bởi vì bên trong số có một bit dấu có thể khác ngay cả khi tất cả các giá trị khác bit là số không.
-In all other cases, `Object.is(a, b)` is the same as `a === b`.
+Trong tất cả các trường hợp khác, `Object.is(a, b)` giống như `a === b`.
-This way of comparison is often used in JavaScript specification. When an internal algorithm needs to compare two values for being exactly the same, it uses `Object.is` (internally called [SameValue](https://tc39.github.io/ecma262/#sec-samevalue)).
+Chúng ta đề cập đến `Object.is` ở đây, bởi vì nó thường được sử dụng trong đặc điểm kỹ thuật của JavaScript. Khi thuật toán nội bộ cần so sánh hai giá trị có giống nhau hoàn toàn không, thuật toán đó sẽ sử dụng `Object.is` (được gọi nội bộ là [SameValue](https://tc39.github.io/ecma262/#sec-samevalue)).
```
-## parseInt and parseFloat
+## parseInt và parseFloat
-Numeric conversion using a plus `+` or `Number()` is strict. If a value is not exactly a number, it fails:
+Chuyển đổi số bằng cách sử dụng dấu cộng `+` hoặc `Number()` là nghiêm ngặt. Nếu một giá trị không chính xác là một số, nó sẽ thất bại:
```js run
alert( +"100px" ); // NaN
```
-The sole exception is spaces at the beginning or at the end of the string, as they are ignored.
+Ngoại lệ duy nhất là khoảng trắng ở đầu hoặc cuối chuỗi, vì chúng bị bỏ qua.
-But in real life we often have values in units, like `"100px"` or `"12pt"` in CSS. Also in many countries the currency symbol goes after the amount, so we have `"19€"` and would like to extract a numeric value out of that.
+Nhưng trong cuộc sống thực, chúng ta thường có các giá trị theo đơn vị, như `"100px"` hoặc `"12pt"` trong CSS. Ngoài ra, ở nhiều quốc gia, ký hiệu tiền tệ đi sau số tiền, vì vậy chúng ta có `"19€"` và muốn trích xuất một giá trị số từ đó.
-That's what `parseInt` and `parseFloat` are for.
+Đó là mục đích của `parseInt` và `parseFloat`.
-They "read" a number from a string until they can't. In case of an error, the gathered number is returned. The function `parseInt` returns an integer, whilst `parseFloat` will return a floating-point number:
+Chúng "đọc" một số từ một chuỗi cho đến khi chúng không thể. Trong trường hợp có lỗi, số đã thu thập được trả về. Hàm `parseInt` trả về một số nguyên, trong khi `parseFloat` sẽ trả về một số dấu phẩy động:
```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, chỉ có phần nguyên được trả về
+alert( parseFloat('12.3.4') ); // 12.3, điểm thứ hai dừng việc đọc
```
-There are situations when `parseInt/parseFloat` will return `NaN`. It happens when no digits could be read:
+Có những trường hợp khi `parseInt/parseFloat` sẽ trả về `NaN`. Nó xảy ra khi không có chữ số nào có thể đọc được:
```js run
-alert( parseInt('a123') ); // NaN, the first symbol stops the process
+alert( parseInt('a123') ); // NaN, ký tự đầu tiên dừng quá trình
```
-````smart header="The second argument of `parseInt(str, radix)`"
-The `parseInt()` function has an optional second parameter. It specifies the base of the numeral system, so `parseInt` can also parse strings of hex numbers, binary numbers and so on:
+````smart header="Đối số thứ hai của `parseInt(str, radix)`"
+Hàm `parseInt()` có tham số thứ hai tùy chọn. Nó chỉ định cơ sở của hệ thống số, vì vậy `parseInt` cũng có thể phân tích cú pháp các chuỗi số hex, số nhị phân, v.v.:
```js run
alert( parseInt('0xff', 16) ); // 255
-alert( parseInt('ff', 16) ); // 255, without 0x also works
+alert( parseInt('ff', 16) ); // 255, không có 0x cũng hoạt động
alert( parseInt('2n9c', 36) ); // 123456
```
````
-## Other math functions
+## Các hàm toán học khác
-JavaScript has a built-in [Math](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Math) object which contains a small library of mathematical functions and constants.
+JavaScript có đối tượng [Math](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Math) tích hợp sẵn chứa một thư viện nhỏ chứa các hằng số và hàm toán học.
-A few examples:
+Một vài ví dụ:
`Math.random()`
-: Returns a random number from 0 to 1 (not including 1).
+: Trả về một số ngẫu nhiên từ 0 đến 1 (không bao gồm 1).
```js run
alert( Math.random() ); // 0.1234567894322
alert( Math.random() ); // 0.5435252343232
- alert( Math.random() ); // ... (any random numbers)
+ alert( Math.random() ); // ... (bất kỳ số ngẫu nhiên nào)
```
-`Math.max(a, b, c...)` / `Math.min(a, b, c...)`
-: Returns the greatest/smallest from the arbitrary number of arguments.
+`Math.max(a, b, c...)` và `Math.min(a, b, c...)`
+: Trả về giá trị lớn nhất và nhỏ nhất từ số lượng đối số tùy ý.
```js run
alert( Math.max(3, 5, -10, 0, 1) ); // 5
@@ -408,36 +436,41 @@ A few examples:
```
`Math.pow(n, power)`
-: Returns `n` raised to the given power.
+: Trả về `n` được nâng lên lũy thừa đã cho.
```js run
- alert( Math.pow(2, 10) ); // 2 in power 10 = 1024
+ alert( Math.pow(2, 10) ); // 2 lũy thừa 10 = 1024
```
-There are more functions and constants in `Math` object, including trigonometry, which you can find in the [docs for the Math object](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Math).
+Có nhiều hàm và hằng số hơn trong đối tượng `Math`, bao gồm lượng giác, mà bạn có thể tìm thấy trong [tài liệu cho đối tượng Math](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Math).
+
+## Tóm tắt
+
+Để viết các số có nhiều số 0:
-## Summary
+- Nối `"e"` với các số 0 được tính vào số. Chẳng hạn như: `123e6` giống như `123` với 6 số 0 `123000000`.
+- Một số âm sau `"e"` làm cho số đó bị chia cho 1 với các số 0 đã cho. Ví dụ. `123e-6` có nghĩa là `0,000123` (`123` phần triệu).
-To write numbers with many zeroes:
+Đối với các hệ thống số khác nhau:
-- Append `"e"` with the zeroes count to the number. Like: `123e6` is the same as `123` with 6 zeroes `123000000`.
-- A negative number after `"e"` causes the number to be divided by 1 with given zeroes. E.g. `123e-6` means `0.000123` (`123` millionths).
+- Có thể viết số trực tiếp trong hệ thống hex (`0x`), bát phân (`0o`) và nhị phân (`0b`).
+- `parseInt(str, base)` phân tích chuỗi `str` thành một số nguyên trong hệ thống số với `base`, `2 ≤ base ≤ 36` đã cho.
+- `num.toString(base)` chuyển đổi một số thành một chuỗi trong hệ thống số với `base` đã cho.
-For different numeral systems:
+Đối với các bài kiểm tra số thông thường:
-- Can write numbers directly in hex (`0x`), octal (`0o`) and binary (`0b`) systems.
-- `parseInt(str, base)` parses the string `str` into an integer in numeral system with given `base`, `2 ≤ base ≤ 36`.
-- `num.toString(base)` converts a number to a string in the numeral system with the given `base`.
+- `isNaN(value)` chuyển đổi đối số của nó thành một số và sau đó kiểm tra xem nó có phải là `NaN` không
+- `isFinite(value)` chuyển đổi đối số của nó thành một số và trả về `true` nếu đó là số thông thường, không phải `NaN/Infinity/-Infinity`
-For converting values like `12pt` and `100px` to a number:
+Để chuyển đổi các giá trị như `12pt` và `100px` thành một số:
-- Use `parseInt/parseFloat` for the "soft" conversion, which reads a number from a string and then returns the value they could read before the error.
+- Sử dụng `parseInt/parseFloat` cho chuyển đổi "mềm", đọc một số từ một chuỗi và sau đó trả về giá trị mà chúng có thể đọc được trước khi xảy ra lỗi.
-For fractions:
+Đối với phân số:
-- Round using `Math.floor`, `Math.ceil`, `Math.trunc`, `Math.round` or `num.toFixed(precision)`.
-- Make sure to remember there's a loss of precision when working with fractions.
+- Làm tròn bằng cách sử dụng `Math.floor`, `Math.ceil`, `Math.trunc`, `Math.round` hoặc `num.toFixed(precision)`.
+- Hãy nhớ rằng có sự mất độ chính xác khi làm việc với phân số.
-More mathematical functions:
+Các hàm toán học khác:
-- See the [Math](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Math) object when you need them. The library is very small, but can cover basic needs.
+- Xem đối tượng [Math](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Math) khi bạn cần. Thư viện rất nhỏ, nhưng có thể đáp ứng nhu cầu cơ bản.