1
00:00:02,310 --> 00:00:08,070
Speaking of the binary system and the decimal system, you might remember that sometimes throughout the

2
00:00:08,070 --> 00:00:12,510
course, you've got a strange output for a seemingly easy calculations.

3
00:00:12,510 --> 00:00:20,370
Let's say we're adding .2 and .4, now what we get as a result is actually this which makes little

4
00:00:20,370 --> 00:00:20,880
sense,

5
00:00:20,880 --> 00:00:21,180
right,

6
00:00:21,180 --> 00:00:23,380
this should be 0.6

7
00:00:23,430 --> 00:00:31,140
and indeed if you would compare the result of that with 0.6, you would get false. Why is 0.2

8
00:00:31,140 --> 00:00:37,860
+ 0.4 not equal to 0.6 in Javascript? I mean that's certainly not what

9
00:00:37,860 --> 00:00:39,760
we learned in math.

10
00:00:39,810 --> 00:00:47,300
Well it's all coming down to that binary system which Javascript and which actually all programming

11
00:00:47,300 --> 00:00:54,770
languages use behind the scenes and the decimal system in which we, the programmer, work. When we say 0.2

12
00:00:54,770 --> 00:00:58,900
and 0.4, we're of course working in the decimal system,

13
00:00:58,910 --> 00:01:06,110
so with a base of 10. Now Javascript internally as you learned works with the binary system

14
00:01:06,170 --> 00:01:14,260
and as I also just said, pretty much all programming languages do that. Now therefore, Javascript converts

15
00:01:14,290 --> 00:01:19,930
this number to the binary system for doing the calculation and then basically converts it back to give

16
00:01:19,930 --> 00:01:25,420
us an output that makes sense to us humans because we rather work with the decimal system than with the

17
00:01:25,420 --> 00:01:28,660
binary system, right? Now that's exactly the issue,

18
00:01:28,750 --> 00:01:34,780
it's important to understand that in the end, numbers like this one here with decimal places are in the

19
00:01:34,780 --> 00:01:38,010
end just represented as fractions of integers

20
00:01:38,020 --> 00:01:45,670
you could say, so for example 0.2 in the decimal system could be represented by 1/5 and

21
00:01:45,670 --> 00:01:51,430
0.4 could be 2/5 of course, in the decimal system.

22
00:01:51,610 --> 00:01:55,750
So in a decimal system, these calculations are super simple right,

23
00:01:55,750 --> 00:01:58,440
we can perform them perfectly.

24
00:01:58,780 --> 00:02:02,700
Now in the binary system, that's different, to understand this,

25
00:02:02,740 --> 00:02:08,620
let's first of all have a look at a calculation which we can't really solve or where we have no perfect

26
00:02:08,620 --> 00:02:11,320
result in the decimal system as well

27
00:02:11,320 --> 00:02:16,040
and that would be 1/3. In the decimal system,

28
00:02:16,150 --> 00:02:23,110
we get this number when we try to do that calculation because as you are aware in the decimal system,

29
00:02:23,110 --> 00:02:25,980
we can't find a perfect solution for this division

30
00:02:26,200 --> 00:02:33,550
and in the binary system, similar cases exist, not for 1/3 necessarily but for example,

31
00:02:33,550 --> 00:02:35,780
for 1/5.

32
00:02:35,830 --> 00:02:41,680
Now for that, it can be convenient to find out how numbers are represented in the binary system and

33
00:02:41,680 --> 00:02:44,280
that can easily be done by entering a number,

34
00:02:44,410 --> 00:02:50,050
for example 1 and if it's just an integer, you should wrap it between parentheses to tell Javascript that

35
00:02:50,050 --> 00:02:56,880
now with a dot, you're accessing a method on the number and not adding a decimal place to it.

36
00:02:57,010 --> 00:03:02,890
So then you can enter to string here and to string actually takes an optional argument where you can

37
00:03:02,890 --> 00:03:09,670
define the base to which you want to convert that number, if you enter two here, we're printing the number

38
00:03:09,670 --> 00:03:15,130
1 in the binary system which however still is 1 because in the binary system, we have the numbers or

39
00:03:15,130 --> 00:03:17,080
the digits 0 and 1,

40
00:03:17,200 --> 00:03:20,330
so 1 is also 1 in the binary system,

41
00:03:20,430 --> 00:03:28,810
now that changes if we try 5 here. Remember 0.2 is the same as 1/5, now 5 in the

42
00:03:28,810 --> 00:03:31,530
binary system is 101,

43
00:03:31,960 --> 00:03:37,000
so in the end you're dividing one by 101 in the binary system when you're trying to

44
00:03:37,000 --> 00:03:44,290
express 0.2. You can actually see the exact result of that division if you execute 1/5

45
00:03:44,290 --> 00:03:51,520
and then call to string at a base of two, this number here, that's in the end what we end up

46
00:03:51,520 --> 00:03:56,730
with in the binary system if we try to divide 1 by 5 in the decimal system,

47
00:03:56,770 --> 00:04:02,890
so this is the result of the to the binary system converted calculation Javascript performed.

48
00:04:03,010 --> 00:04:09,640
So this number, 0.2 in the end is this number here in the binary system you could say, you can

49
00:04:09,640 --> 00:04:17,470
of course also see that if you call to string here and add two here as a base on 0.2, here we

50
00:04:17,470 --> 00:04:22,630
don't need the parentheses because we already have one dot in there and therefore it's clear to Javascript

51
00:04:22,630 --> 00:04:23,700
that this is the number

52
00:04:23,740 --> 00:04:25,890
and this is then a method on the number.

53
00:04:25,900 --> 00:04:29,860
So this is how this number is represented in the binary system

54
00:04:29,890 --> 00:04:31,450
and here it's simply getting cut off

55
00:04:31,480 --> 00:04:38,500
but in the end this pattern here would be repeated infinitely in the binary system, just like the three

56
00:04:38,830 --> 00:04:47,270
is repeated infinitely in the decimal system if we divide one by three. So there simply are certain fractions

57
00:04:47,360 --> 00:04:51,600
where there is no perfect solution in the binary system just as

58
00:04:51,720 --> 00:04:57,080
there are certain divisions, like 1/3 where there is no perfect solution in the decimal

59
00:04:57,080 --> 00:04:57,820
system

60
00:04:58,040 --> 00:05:02,540
and it's because of that why we end up with this strange result here.

61
00:05:02,720 --> 00:05:07,920
In the end both 0.2 and 0.4 don't yield a perfect result,

62
00:05:08,000 --> 00:05:15,890
so if we then add these two not perfect results, we get a imperfect result because we add two numbers

63
00:05:16,010 --> 00:05:21,860
which can't really be solved in the end. It's the same as if you would say 1/3 +

64
00:05:21,860 --> 00:05:25,820
1/3 + 1/3.

65
00:05:25,820 --> 00:05:30,770
Now here, we get one because Javascript does some rounding for us to give us a result that makes sense

66
00:05:30,800 --> 00:05:36,770
but in the end, you are working here with 0.33333 + 0.33333

67
00:05:36,800 --> 00:05:42,030
+ 0.33333 in the decimal system and hence you would end up with something like this

68
00:05:42,030 --> 00:05:49,320
in a decimal system, you can't really reach 1 and it's the same for the binary system with 0.2

69
00:05:49,320 --> 00:05:55,590
+ 0.4, you can't really reach 0.6 because in the binary system, both these numbers

70
00:05:55,950 --> 00:06:01,890
can't really be solved, there isn't a finite amount of decimal places that would be needed to represent

71
00:06:01,920 --> 00:06:02,930
each number.

72
00:06:03,300 --> 00:06:10,530
Now often in Javascript, Javascript fixes this for us, it shows us a number that makes sense to us even

73
00:06:10,530 --> 00:06:13,470
though in the binary system, it can't really be represented, 

74
00:06:13,470 --> 00:06:19,170
for example if we just use 0.2. You just learned that there is no perfect representation of

75
00:06:19,170 --> 00:06:20,650
that in the binary system.

76
00:06:20,760 --> 00:06:27,480
Still if Javascript converts the binary representation, which just to bring it back in memory was this

77
00:06:27,480 --> 00:06:33,660
here, when it converts this back to a decimal number to output it to us, it converts it back into a perfect

78
00:06:33,660 --> 00:06:41,250
decimal number and not in to something like this but this is just a trick by Javascript and many programming

79
00:06:41,250 --> 00:06:42,520
languages do that,

80
00:06:42,660 --> 00:06:45,210
they of course don't want to show this to us,

81
00:06:45,210 --> 00:06:50,820
instead they want to give us a result that makes sense to us and they're generally pretty smart about

82
00:06:51,060 --> 00:06:54,990
rounding the numbers they got in the binary system.

83
00:06:55,020 --> 00:07:01,440
Nonetheless, you can see that there is imprecision if you use another method which is to fixed, to fix

84
00:07:01,440 --> 00:07:02,840
does not convert this,

85
00:07:02,940 --> 00:07:09,060
instead here you can set a certain amount of digits you want to output and for example if you enter 20 here,

86
00:07:09,060 --> 00:07:16,590
you force Javascript to represent this as a number with 20 decimal places and you see, at some point

87
00:07:16,590 --> 00:07:19,280
of time, we can see that imprecision here,

88
00:07:19,380 --> 00:07:25,530
so Javascript is really just doing some smart rounding for us when it just outputs 0.2, behind

89
00:07:25,530 --> 00:07:26,370
the scenes,

90
00:07:26,370 --> 00:07:31,450
that number looks like that. Now is that a problem?

91
00:07:31,450 --> 00:07:31,800
No,

92
00:07:31,840 --> 00:07:35,530
generally that's not a problem. For most calculations,

93
00:07:35,540 --> 00:07:40,000
this automatic rounding works just fine.

94
00:07:40,000 --> 00:07:45,760
Now if you want to output a number to the user, you of course want to avoid that 0.2 +

95
00:07:45,760 --> 00:07:50,850
0.4 is printed like this somewhere on your page. To avoid

96
00:07:50,850 --> 00:07:56,830
this, you can use that to fixed method you just learned about, there for example you could force Javascript

97
00:07:56,830 --> 00:08:02,620
to just display two decimal places and you would end up with a perfectly fine number

98
00:08:02,620 --> 00:08:09,720
and of course you can specify any amount of decimal places you want - 2, 1, 0, whatever you want and Javascript

99
00:08:09,730 --> 00:08:13,930
will round it and avoid showing this imprecision here.

100
00:08:13,960 --> 00:08:21,150
So for outputting results to your end users, to fixed is a great way of working around that issue here.

101
00:08:21,160 --> 00:08:27,130
Now there are certain other calculations however where you don't just worry about the thing or the result

102
00:08:27,160 --> 00:08:30,520
you show to the user but about the result itself.

103
00:08:30,520 --> 00:08:34,780
Let's say you have an online shop and you're working with prices there.

104
00:08:34,780 --> 00:08:46,420
Now if something costs 20.2 euros or dollars and you send that to your server to charge the credit

105
00:08:46,420 --> 00:08:54,500
card by that amount, then behind the scenes, you are sending this number to your servers

106
00:08:54,500 --> 00:08:58,840
and therefore here in the end, you're charging not enough.

107
00:08:58,850 --> 00:09:05,060
Now of course chances are that when you're charging something like this, the payment service you're using

108
00:09:05,120 --> 00:09:11,420
automatically rounds this to fix your error or do anything like that but chances are also that you in the end

109
00:09:11,420 --> 00:09:18,090
do introduce some small errors and therefore you sometimes might charge too much or too little

110
00:09:18,230 --> 00:09:22,710
and over time, even such small deviations can really add up.

111
00:09:22,730 --> 00:09:29,420
Imagine Amazon charging to a little bit too much or a little bit too less on every transaction, well

112
00:09:29,450 --> 00:09:34,120
they're handling thousands of transactions every hour of course,

113
00:09:34,130 --> 00:09:39,590
so there, that would quickly add up and therefore, there are situations where you need perfect precision.

114
00:09:40,250 --> 00:09:42,310
Now to get perfect precision,

115
00:09:42,320 --> 00:09:49,310
one common solution is to simply multiply your number with 100 in the end so that you only work

116
00:09:49,310 --> 00:09:50,750
with integers.

117
00:09:50,750 --> 00:09:53,180
Now you learned there are no integers in Javascript,

118
00:09:53,180 --> 00:09:58,310
everything is a floating point number but of course this integer here whilst it not being an integer

119
00:09:58,520 --> 00:10:00,860
would be this floating point number

120
00:10:00,920 --> 00:10:07,650
and this can be represented perfectly in binary notation so you won't have any imprecision here.

121
00:10:07,670 --> 00:10:13,870
So working with integers only can be one workaround around such imprecision here.

122
00:10:14,000 --> 00:10:20,270
You also can find certain Javascript packages and libraries, by the way libraries are a topic we'll

123
00:10:20,270 --> 00:10:25,610
have a closer look in detail later in the course but certain third-party add-ons you can add to your

124
00:10:25,610 --> 00:10:28,040
page, to your application so to say

125
00:10:28,040 --> 00:10:36,440
which also provides you tools, utility functions to fix such imprecision or of course, you know you are

126
00:10:36,440 --> 00:10:43,340
using some service maybe on your server or some third-party service your web app talks to which fixes

127
00:10:43,340 --> 00:10:44,620
such issues for you.

128
00:10:44,840 --> 00:10:49,100
Again often, they may not matter especially for outputting something to the user,

129
00:10:49,100 --> 00:10:54,740
you can just use to fixed but in some cases where they do matter, you should be aware of that imprecision

130
00:10:54,890 --> 00:11:00,620
and that there are workarounds, like for example only working with integers by multiplying with

131
00:11:00,620 --> 00:11:01,810
100 for example.
