Skip to content

Data types - Numbers #18

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
merged 2 commits into from
Jul 9, 2019
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
6 changes: 2 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,10 @@


```js run demo
let a = +prompt("The first number?", "");
let b = +prompt("The second number?", "");

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.
پی نوشت: حواستان به مدل‌های داده‌ها باشد.
18 changes: 7 additions & 11 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,31 +1,27 @@
Internally the decimal fraction `6.35` is an endless binary. As always in such cases, it is stored with a precision loss.

Let's see:
در درون سیستم، یک عدد دودویی `6.35` بی‌پایان است. مثل همیشه، در این حالات با یک دقت از دست رفته‌ای ذخیره خواهد شد.

```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` است. کسرهای تقسیم شده بر دو به درستی در سیستم دودویی نمایش داده می‌شوند، حالا میتوانیم آن را رند کنیم:

```js run
alert( Math.round(6.35 * 10) / 10); // 6.35 -> 63.5 -> 64(rounded) -> 6.4
Expand Down
12 changes: 5 additions & 7 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,19 @@ 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.

For instance:
بنابر مستندات `Math.round` و `toFixed`، هردو به نزدیکترین عدد آن را رند میکنند: `0..4` به پایین رند میشود و `5..9` به بالا.

به عنوان مثال:
```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 @@ -15,9 +15,8 @@ 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`.

After we stopped, we need to treat `null` and empty line specially (return `null`), because converting them to a number would return `0`.
پس ما تا وقتی ورودی را می‌پذیریم که عدد عادی باشد. هردوی `null` (cancel) و خط خالی هم در این شرایط میگنجد، چونکه در فرم عددی صفر هستند.

بعد از اینکه برنامه متوقف شد بایستی `null` و مخصوصا خط‌های خالی (خروجی `null`) را در نظر بگیریم، چون تبدیل آنها به عدد صفر برمی‌گرداند.
9 changes: 4 additions & 5 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,12 @@ 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]

12 changes: 6 additions & 6 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,7 +1,6 @@
That's because `i` would never equal `10`.

Run it to see the *real* values of `i`:
به این علت است که `i` هیچوقت برابر ده نمیشود.

این تکه کد را اجرا کنید تا مقدار حقیقی `i` را ببینید:
```js run
let i = 0;
while (i < 11) {
Expand All @@ -10,8 +9,9 @@ while (i < 11) {
}
```

None of them is exactly `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.
نتیجه: وقتی با کسرهای اعشاری کار میکنید، از تساوی استفاده نکنید.
5 changes: 2 additions & 3 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,10 +2,9 @@ importance: 4

---

# An occasional infinite loop

This loop is infinite. It never ends. Why?
# یک حلقه‌ی بی‌نهایت

این حلقه بی‌نهایت است. هیچوقت تمام نمی‌شود. چرا؟
```js
let i = 0;
while (i != 10) {
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,12 +1,12 @@
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`.
۱. اگر یک عدد تصادفی از 0..1 را در عددی `max-min` ضرب کنیم، بازه‌ی مقادیر ممکن از `0..1` به `0..max-min` افزایش می‌یابد.

The function:
۲. حالا اگر `min` را اضافه کنیم، بازه‌ی ممکن از `min` تا `max` میشود.

تابع:
```js run
function random(min, max) {
return min + Math.random() * (max - min);
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
# عددی تصادفی از بین مینیمم تا ماکسیمم

The built-in function `Math.random()` creates a random value from `0` to `1` (not including `1`).
تابع از پیش آماده شده‌ی `Math.random()`، یک مقدار تصادفی از `0` تا `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
23 changes: 11 additions & 12 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,23 +11,22 @@ 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.
اگر شما مثال بالا را به کرات اجرا کنید، میبینید که عدد ۲ اکثر اوقات ظاهر می‌شود.

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`.
حالا میتوانیم به وضوح ببینیم که عدد ۲، دو برابر عدد یک مقادیر به آن نسبت داده میشود. همینطور هم برای عدد ۳.
# راه حل صحیح

# 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
*!*
Expand All @@ -41,7 +40,7 @@ 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
*!*
Expand All @@ -55,12 +54,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.
همه ی بازه‌ها الان طول یکسانی دارند و در نهایت توزیع یکسانی دارند.
12 changes: 5 additions & 7 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,17 @@ importance: 2

---

# A random integer from min to 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` که هر دو شامل مقادیر `min` و `max` می‌شود را خروجی می‌دهد.

Any number from the interval `min..max` must appear with the same probability.


Examples of its work:
هر عدد از بازه‌ی `min..max` باید احتمال یکسانی داشته باشد.

مثال‌هایی از کارکردش:
```js
alert( random(1, 5) ); // 1
alert( random(1, 5) ); // 3
alert( random(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