Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions 1-js/05-data-types/02-number/1-sum-interface/solution.md
Original file line number Diff line number Diff line change
@@ -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"`.
Nếu không, `a` `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"`.
6 changes: 3 additions & 3 deletions 1-js/05-data-types/02-number/1-sum-interface/task.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
18 changes: 9 additions & 9 deletions 1-js/05-data-types/02-number/2-why-rounded-down/solution.md
Original file line number Diff line number Diff line change
@@ -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
```

10 changes: 5 additions & 5 deletions 1-js/05-data-types/02-number/2-why-rounded-down/task.md
Original file line number Diff line number Diff line change
Expand Up @@ -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` `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?

Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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`.

8 changes: 4 additions & 4 deletions 1-js/05-data-types/02-number/3-repeat-until-number/task.md
Original file line number Diff line number Diff line change
Expand Up @@ -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]

10 changes: 5 additions & 5 deletions 1-js/05-data-types/02-number/4-endless-loop-error/solution.md
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -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.
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.
4 changes: 2 additions & 2 deletions 1-js/05-data-types/02-number/4-endless-loop-error/task.md
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
10 changes: 5 additions & 5 deletions 1-js/05-data-types/02-number/8-random-min-max/solution.md
Original file line number Diff line number Diff line change
@@ -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) {
Expand Down
8 changes: 4 additions & 4 deletions 1-js/05-data-types/02-number/8-random-min-max/task.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
26 changes: 13 additions & 13 deletions 1-js/05-data-types/02-number/9-random-int-min-max/solution.md
Original file line number Diff line number Diff line change
@@ -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) {
Expand All @@ -11,28 +11,28 @@ 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` `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
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);
}
Expand All @@ -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);
}
Expand All @@ -55,12 +55,12 @@ 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
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.
10 changes: 5 additions & 5 deletions 1-js/05-data-types/02-number/9-random-int-min-max/task.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,19 @@ 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` `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
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ở.
Loading