Skip to content
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("Перше число?", "");
let b = +prompt("Друге число?", "");

alert( a + b );
```

Note the unary plus `+` before `prompt`. It immediately converts the value to a number.
Зверніть увагу на одиничний плюс `+` перед `prompt`. Це відразу перетворює значення в число.

Otherwise, `a` and `b` would be string their sum would be their concatenation, that is: `"1" + "2" = "12"`.
В іншому випадку, `a` і` b` будуть рядками, і в результаті вони об'єднаються (конкатинуються), тобто: `"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
# Сума чисел від відвідувача

Create a script that prompts the visitor to enter two numbers and then shows their sum.
Напишіть скрипт, який просить відвідувача ввести два числа, і в результаті показує їх суму.

[demo]

P.S. There is a gotcha with types.
P.S. Тут є цікавий момент з типами
19 changes: 9 additions & 10 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,32 @@
Internally the decimal fraction `6.35` is an endless binary. As always in such cases, it is stored with a precision loss.
Десятковий дріб `6.35` являє собою нескінченний двійковий код. Як завжди в таких випадках, він зберігається з втратою точності.

Let's see:
Подивимось:
Comment thread
alexandrtovmach marked this conversation as resolved.

```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.
Втрата точності може спричинити як збільшення, так і зменшення числа. У цьому конкретному випадку число стає трохи меншим, тому в��но округляється вниз.

And what's for `1.35`?
А що для `1.35`?

```js run
alert( 1.35.toFixed(20) ); // 1.35000000000000008882
```

Here the precision loss made the number a little bit greater, so it rounded up.
Тут втрата точності зробила число трохи більшим, тому воно округляється вверх.

**How can we fix the problem with `6.35` if we want it to be rounded the right way?**
**Як ми можемо виправити проблему з числом `6.35`, якщо хочемо, щоб воно було правильно округлене?**

We should bring it closer to an integer prior to rounding:
Ми повинні наблизити його до цілого числа до округлення:

```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:
Зауважте, що `63.5` взагалі не має втрат на точність. Це тому, що десяткова частина `0.5` насправді є `1/2`. Дроби, розділені на `2`, точно представлені у двійковій системі, і ми можемо її округлити:


```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(округлене) -> 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?
# Чому 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.
Згідно з документацією `Math.round` і `toFixed`, округлюють до найближчого числа: `0..4` ведуть вниз, а` 5..9` ведуть вгору.

For instance:
Наприклад:

```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`?
У подібному прикладі нижче, чому `6.35` округляється до `6.3`, а не `6.4`?

```js run
alert( 6.35.toFixed(1) ); // 6.3
```

How to round `6.35` the right way?
Як правильно округлити `6.35`?

Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ function readNumber() {
let num;

do {
num = prompt("Enter a number please?", 0);
num = prompt("Введіть число", 0);
} while ( !isFinite(num) );

if (num === null || num === '') return null;
Expand Down
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("Введіть число", 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.
Рішення є дещо складнішим, аніж здається, тому що нам потрібно обробляти `null` та порожні рядки.

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`.
Таким чином, ми фактично приймаємо вхід, поки він не стане "звичайним числом". Обидва `null` (скасування), та порожній рядок відповідають цій умові, оскільки в числовій формі вони є `0`.

After we stopped, we need to treat `null` and empty line specially (return `null`), because converting them to a number would return `0`.
Після того, як ми зупинилися, нам потрібно обробити `null` і порожній рядок спеціально (повернути `null`), тому що їх перетворення у число поверне `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
# Повторюйте, поки вхід не буде числом

Create a function `readNumber` which prompts for a number until the visitor enters a valid numeric value.
Створіть функцію `readNumber`, яка запросить число, поки відвідувач не введе дійсне числове значення.

The resulting value must be returned as a number.
Отримане значення потрібно повернути як число.

The visitor can also stop the process by entering an empty line or pressing "CANCEL". In that case, the function should return `null`.
Відвідувач також може зупинити процес, ввівши порожній рядок або натиснувши "CANCEL". У цьому випадку функція повинна повернути `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`.
Це тому, що `i` ніколи не буде дорівнювати `10`.

Run it to see the *real* values of `i`:
Запустіть код, щоб побачити *реальні* значення `i`:

```js run
let i = 0;
Expand All @@ -10,8 +10,8 @@ while (i < 11) {
}
```

None of them is exactly `10`.
Жодне значення не `10`.

Such things happen because of the precision losses when adding fractions like `0.2`.
Такі речі трапляються через втрати точності при додаванні дробів на зразок `0.2`.

Conclusion: evade equality checks when working with decimal fractions.
Висновок: уникайте порівняннь при роботі з десятковими дробами.
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
# Випадковий безкінечний цикл

This loop is infinite. It never ends. Why?
Цей цикл безкінечний. Він ніколи не закінчується. Чому?

```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`.
Нам потрібно перевести всі значення з інтервалу 0..1 у значення від `min` до` max`.

That can be done in two stages:
Це можна зробити у два етапи:

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. Якщо помножити випадкове число з 0..1 на `max-min`, то інтервал можливих значень збільшується від `0..1` до `0..max-min`.
2. Тепер, якщо ми додамо `min`, можливий інтервал стає від `min` до `max`.

The function:
Функція:

```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
# Випадкове число від min до max

The built-in function `Math.random()` creates a random value from `0` to `1` (not including `1`).
Вбудована функція `Math.random()` створює випадкове значення від `0` до` 1` (не враховуючи `1`).

Write the function `random(min, max)` to generate a random floating-point number from `min` to `max` (not including `max`).
Напишіть функцію `random(min, max)` для створення випадкового числа з плаваючою крапкою від `min` до `max` (не враховуючи `max`).

Examples of its work:
Приклади його роботи:

```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
# Просте, але неправильне рішення

The simplest, but wrong solution would be to generate a value from `min` to `max` and round it:
Найпростішим, але неправильним рішенням буде генерувати значення від `min` до `max` і округляти його:

```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.
Функція працює, але вона неправильна. Ймовірність отримати граничні значення `min` і `max` в два рази менше, ніж будь-які інші.

If you run the example above many times, you would easily see that `2` appears the most often.
Якщо ви запускаєте приклад вище, багато разів, ви легко побачите, що `2` з’являється найчастіше.

That happens because `Math.round()` gets random numbers from the interval `1..3` and rounds them as follows:
Це відбувається тому, що `Math.round()` отримує випадкові числа з інтервалу `1..3` і округляє їх так:

```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`.
Тепер ми можемо чітко бачити, що `1` генерується вдвічі рідше ніж `2`. І те саме з `3`.

# The correct solution
# Правильне рішення

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:
Існує багато правильних рішень задачі. Один з них - коригування інтервальних меж. Щоб забезпечити однакові інтервали, ми можемо генерувати значення від `0.5 до 3.5`, тим самим додаючи необхідні ймовірності до граничних значеннь:

```js run
*!*
function randomInteger(min, max) {
// now rand is from (min-0.5) to (max+0.5)
// тепер rand від (min-0.5) до (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`:
Альтернативним способом може бути використання `Math.floor` для випадкового числа від `min` до `max + 1`:

```js run
*!*
function randomInteger(min, max) {
// here rand is from min to (max+1)
// тепер rand від min до (max+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:
Тепер усі інтервали відображаються таким чином:

```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.
Всі інтервали мають однакову довжину, що робить остаточний розподіл рівномірним.
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
# Довільне ціле число від min до max

Create a function `randomInteger(min, max)` that generates a random *integer* number from `min` to `max` including both `min` and `max` as possible values.
Створіть функцію `randomInteger(min, max)`, яка генерує випадкове *ціле* число від `min` до `max` включно.

Any number from the interval `min..max` must appear with the same probability.
Будь-яке число з інтервалу `min..max` повинно з'являтися з однаковою ймовірністю.


Examples of its work:
Приклади його роботи:

```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.
Ви можете використовувати рішення [попереднього завдання](info:task/random-min-max) як основу.
Loading