You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: 1-js/05-data-types/02-number/article.md
+31-34Lines changed: 31 additions & 34 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -26,11 +26,11 @@ In other words, `"e"` multiplies the number by `1` with the given zeroes count.
26
26
27
27
```js
28
28
1e3=1*1000
29
-
1.23e6=1.23*1000000
29
+
1.23e6=1.23*1000000
30
30
```
31
31
32
32
33
-
Now let's write something very small. Say, 1 microsecond (one millionth of a second):
33
+
Now let's write something very small. Say, 1 microsecond (one millionth of a second):
34
34
35
35
```js
36
36
let ms =0.000001;
@@ -39,7 +39,7 @@ let ms = 0.000001;
39
39
Just like before, using `"e"` can help. If we'd like to avoid writing the zeroes explicitly, we could say:
40
40
41
41
```js
42
-
let ms =1e-6; // six zeroes to the left from 1
42
+
let ms =1e-6; // six zeroes to the left from 1
43
43
```
44
44
45
45
If we count the zeroes in `0.000001`, there are 6 of them. So naturally it's `1e-6`.
@@ -153,7 +153,7 @@ There are two ways to do so:
153
153
```
154
154
155
155
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.
156
-
156
+
157
157
```js run
158
158
let num = 12.34;
159
159
alert( num.toFixed(1) ); // "12.3"
@@ -170,7 +170,7 @@ There are two ways to do so:
170
170
171
171
```js run
172
172
let num = 12.34;
173
-
alert( num.toFixed(5) ); // "12.34000", added zeroes to make exactly 5 digits
173
+
alert( num.toFixed(5) ); // "12.34000", added zeroes to make exactly 5 digits
174
174
```
175
175
176
176
We can convert it to a number using the unary plus or a `Number()` call: `+num.toFixed(5)`.
@@ -182,7 +182,7 @@ Internally, a number is represented in 64-bit format [IEEE-754](http://en.wikipe
182
182
If a number is too big, it would overflow the 64-bit storage, potentially giving an infinity:
183
183
184
184
```js run
185
-
alert( 1e500 ); // Infinity
185
+
alert( 1e500 ); // Infinity
186
186
```
187
187
188
188
What may be a little less obvious, but happens quite often, is the loss of precision.
@@ -193,7 +193,7 @@ Consider this (falsy!) test:
193
193
alert( 0.1 + 0.2 == 0.3 ); // *!*false*/!*
194
194
```
195
195
196
-
That's right, if we check whether the sum of `0.1` and `0.2` is `0.3`, we get `false`.
196
+
That's right, if we check whether the sum of `0.1` and `0.2` is `0.3`, we get `false`.
197
197
198
198
Strange! What is it then if not `0.3`?
199
199
@@ -207,7 +207,7 @@ But why does this happen?
207
207
208
208
A number is stored in memory in its binary form, a sequence of 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.
209
209
210
-
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)`.
210
+
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)`.
211
211
212
212
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.
213
213
@@ -227,40 +227,39 @@ That's why `0.1 + 0.2` is not exactly `0.3`.
227
227
```smart header="Not only JavaScript"
228
228
The same issue exists in many other programming languages.
229
229
230
-
PHP, Java, C, Perl, Ruby give exactly the same result, because they are based on the same numeric format.
230
+
PHP, Java, C, Perl, Ruby give exactly the same result, because they are based on the same numeric format.
231
231
```
232
232
233
-
Can we work around the problem? Sure, there're a number of ways:
234
-
235
-
1. We can 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):
233
+
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):
236
234
237
-
```js run
238
-
let sum = 0.1 + 0.2;
239
-
alert( sum.toFixed(2) ); // 0.30
240
-
```
235
+
```js run
236
+
let sum = 0.1 + 0.2;
237
+
alert( sum.toFixed(2) ); // 0.30
238
+
```
241
239
242
-
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:
240
+
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:
243
241
244
-
```js run
245
-
let sum = 0.1 + 0.2;
246
-
alert( +sum.toFixed(2) ); // 0.3
247
-
```
242
+
```js run
243
+
let sum = 0.1 + 0.2;
244
+
alert( +sum.toFixed(2) ); // 0.3
245
+
```
248
246
249
-
2. We can temporarily turn numbers into integers for the maths and then revert it back. It works like this:
247
+
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:
This works because when we do `0.1 * 10 = 1` and `0.2 * 10 = 2` then both numbers become integers, and there's no precision loss.
254
+
So, multiply/divide approach reduces the error, but doesn't remove it totally.
256
255
257
-
3. If we were dealing with a shop, then the most radical solution would be to store all prices in cents and use no fractions at all. But what if we apply a discount of 30%? In practice, totally evading fractions is rarely feasible, so the solutions above help avoid this pitfall.
256
+
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.
@@ -272,7 +271,7 @@ JavaScript doesn't trigger an error in such events. It does its best to fit the
272
271
```smart header="Two zeroes"
273
272
Another funny consequence of the internal representation of numbers is the existence of two zeroes: `0` and `-0`.
274
273
275
-
That's because a sign is represented by a single bit, so every number can be positive or negative, including a zero.
274
+
That's because a sign is represented by a single bit, so every number can be positive or negative, including a zero.
276
275
277
276
In most cases the distinction is unnoticeable, because operators are suited to treat them as the same.
278
277
```
@@ -326,10 +325,10 @@ Please note that an empty or a space-only string is treated as `0` in all numeri
326
325
327
326
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:
328
327
329
-
1. It works with `NaN`: `Object.is(NaN, NaN) === true`, that's a good thing.
328
+
1. It works with `NaN`: `Object.is(NaN, NaN) === true`, that's a good thing.
330
329
2. Values `0` and `-0` are different: `Object.is(0, -0) === false`, it rarely matters, but these values technically are different.
331
330
332
-
In all other cases, `Object.is(a, b)` is the same as `a === b`.
331
+
In all other cases, `Object.is(a, b)` is the same as `a === b`.
333
332
334
333
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)).
335
334
```
@@ -423,7 +422,7 @@ For different numeral systems:
423
422
424
423
For converting values like `12pt` and `100px` to a number:
425
424
426
-
- 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.
425
+
- 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.
427
426
428
427
For fractions:
429
428
@@ -433,5 +432,3 @@ For fractions:
433
432
More mathematical functions:
434
433
435
434
- 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.
0 commit comments