Skip to content

Numbers #62

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
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("Перше число?", "");
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:
Подивимось:

```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