Skip to content

Commit

Permalink
Merge branch 'master' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
pixari authored Jul 15, 2019
2 parents 4111161 + c126576 commit f2c053b
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 7 deletions.
42 changes: 36 additions & 6 deletions content/02-arithmetic-operators.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,25 +11,31 @@
## 1. Why 0.1 + 0.2 = 0.300000004?

> Example:
```js
0.1 + 0.2; // 0.300000004
```

### Explanation
This is not just a javascript language limitation but also a limitation for many other programming languages(C or Java or C++) . This is a problem with the format(IEEE 754 -binary floating point) that computers internally use to represent the numbers. This format cannot represent the numbers like 0.1 or 0.2 accurately because they store the numbers in binary and floating number cannot store all the decimal numbers properly

This is not just a javascript language limitation but also a limitation for many other programming languages(C or Java or C++) . This is a problem with the format(IEEE 754 -binary floating point) that computers internally use to represent the numbers. This format cannot represent the numbers like 0.1 or 0.2 accurately because they store the numbers in binary and floating number cannot store all the decimal numbers properly
For Example, 0.1 would be coverted in the following way

```
0.1 = 1/10 => 1/16 + (1/10-1/16) => 1/32 + (0.0375-1/32) ....so on
0.1 = 1/10 => 1/16 + (1/10-1/16) => 1/32 + (0.0375-1/32) ....so on
and the ultimate result would be around 0.1000000000000000055511151231257827021181583404541015625
```
So when the code is compiled or transpiled or interpreted,0.1 will be rounded/chopped off to nearest number in the representable binary format and hence when arithmetic operations are performed , there can be small rounding errors .Hence we get 0.300000004 instead of 0.3, when we add 0.1 and 0.2 . For more detailed explanation,check out this [paper by David Goldberg](https://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html)

So when the code is compiled or transpiled or interpreted,0.1 will be rounded/chopped off to nearest number in the representable binary format and hence when arithmetic operations are performed , there can be small rounding errors .Hence we get 0.300000004 instead of 0.3, when we add 0.1 and 0.2 . For more detailed explanation,check out this [paper by David Goldberg](https://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html)
and [article](https://blog.angularindepth.com/javascripts-number-type-8d59199db1b6)

### Fix
### Fix

There is a simple fix to this issue as shown below

```javascript
var a = 0.1+0.2 //0.300000004
var b = +(0.1+0.2).toFixed(1);//round off to avoid errorneous value and convert it back to number by using +
var a = 0.1 + 0.2; //0.300000004
var b = +(0.1 + 0.2).toFixed(1); //round off to avoid errorneous value and convert it back to number by using +
//b = 0.3
```
Alternatively, if you want to compare floating point values, you can use this solution from [Kyle Simpson's "You Don't Know JS"](https://github.com/getify/You-Dont-Know-JS/blob/master/types%20%26%20grammar/ch2.md) which uses what is commonly known as "machine epsilon" as a tolerance value.
Expand All @@ -49,3 +55,27 @@ if (!Number.EPSILON) {
Number.EPSILON = Math.pow(2,-52);
}
```
=======
## 2. Why (! + [] + [] + ![]).length is 9?

> Example:
```js
(!+[] + [] + ![]).length; // 9
```

### Explanation

JavaScript does operations from right to left.
The + operand first tries to add the left to the right, if that isn't possible it tries to convert the operand on the right to a number and if it can't do that it converts it to a string. If there is something to the left of the + it adds them together, and if it can't it sticks around. If there is nothing to the left it goes away.
The ! operand converts the operand to the right to a boolean and then reverts it.
The detailed explaniation see also the test.

```
expect(!+[] + [] + ![])
.toBe((!+[]) + ([]) + (![]))
.toBe('true' + '' + 'false')
.toHaveLength(9);
```

For more detailed explanation,check out this [by Tomas Forsman](https://dev.to/tomasforsman/why-length-is-9-2i4l)
9 changes: 8 additions & 1 deletion test/spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,13 @@ describe(`Chapter 2 - Arithmetic operators`, () => {
expect(adding).not.toBe(0.3);
expect(+adding.toFixed(1)).toBe(0.3);
});
it(`The ! operand converts the operand to the right to a boolean and then reverts it.`, () => {
expect(!+[] + [] + ![])
.toBe((!+[]) + ([]) + (![]))
.toBe('true' + '' + 'false')
.toBe('truefalse')
.toHaveLength(9);
});
});
describe(`Chapter 3 -Types`, () => {
it(`NaN is a number`, () => {
Expand All @@ -47,7 +54,7 @@ describe(`Chapter 3 -Types`, () => {
expect(Number([undefined])).toBe(0);
});
});
describe(`Chapter 4 - operators`, () => {});
describe(`Chapter 4 - operators`, () => { });
it(`What is the double negation?`, () => {
expect(!!true)
.toBe(!!new Boolean(true))
Expand Down

0 comments on commit f2c053b

Please sign in to comment.