Discuss Scratch

crabraveprogrammer
Scratcher
100+ posts

Why Scratch cant do math (0.1 + 0.2 = 0.300...004)

Ok, so if you have never ran into this, if you run this*:
((0.1) + (0.2))
you will get 0.3000000000000000000000000000000000000000000004.
If you run
<((0.1) + (0.2)) = [0.3]>
you will get false.
WHY IS THIS HAPPING TO ME I AM SO ANGRY????
(**note this is not Scratch's fault, it happens in all programming languages, including Scratch's parent programming language JavaScript)

So, actually, all variables are stored in binary. All math is done with binary, and all inputs defined by a user must be converted to Binary. When you want to display a variable… it must be converted back to Base-10.

Computers do not use math with fractions… the use decimals (technically floating point decimal). So, what is 0.1 in binary?
It is 0.000110011000110011000110011000110011000110011000110011…….

Oh no, we have a problem. We cannot display 0.1 in binary… It is a forever repeating decimal.

Of course, computers know they must stop trying to get a gigantic decimal… So that is why you can't do gigantic math like 4 billion * Googol * pi or any numbers that are really long, as really long base-10 numbers are usually really long Binary numbers. And, in our case, a really long Binary number….

So, anyway, hope you learned something new today.

Wow you are know smarter than the computer the computer thinks 0.1 + 0.2 = 0.300…004
Sheep_maker
Scratcher
1000+ posts

Why Scratch cant do math (0.1 + 0.2 = 0.300...004)

Float point numbers are fun! Technically, 0.1 is represented in memory as
0011111110111001100110011001100110011001100110011001100110011010
which is basically what you have but in a form similar to scientific notation (where the base is 2, the blue is the exponent, minus 1023 or something like that, and the green is the coefficient) since conventional computers don't store decimal points in memory
Sheep_maker
Scratcher
1000+ posts

Why Scratch cant do math (0.1 + 0.2 = 0.300...004)

Also, the product of 4 billion, a googol, and pi is doable with floating point numbers, though you'll lose some precision:
((4e9) * ((1e100) * (3.141592653589793))) // 1.2566370614359172e+110
In binary,
0101011011001010110000001110100010110010111100110010010000011011
You can see that the exponent in blue has changed. Floating point numbers can change their precision by changing the exponent part of the number, hence the “floating” (as opposed to fixed point numbers)

The maximum finite number that can be stored as a double precision floating point number (which is what Scratch, JS, and Python use) is 1.7976931348623157 * 10^308 (three times more digits than a googol):
0111111111101111111111111111111111111111111111111111111111111111
6d66yh
Scratcher
100+ posts

Why Scratch cant do math (0.1 + 0.2 = 0.300...004)

crabraveprogrammer wrote:

Ok, so if you have never ran into this, if you run this you will get 0.3000000000000000000000000000000000000000000004.
What kind of system do you have with so much precision? Isn't it 0.30000000000000004? The string generator actually does an intellectual thing that rounds to just enough digits to distinguish the double from other doubles. As no 16 significant places representation rounds exactly to the value, it uses 17 significant places, and it is a really complex thing.
Greg8128
Scratcher
500+ posts

Why Scratch cant do math (0.1 + 0.2 = 0.300...004)

crabraveprogrammer0 wrote:

We cannot display 0.1 in binary… It is a forever repeating decimal.
Why not?
Many languages let you store numbers as fractions. If you can store a “3” and a “10” then you can store “3/10” exactly. It is a custom data type though.
Why doesn't JavaScript do this by default? Probably to improve performance

As an aside, the ancient COBOL programming language stored numbers by storing 2 decimal digits in each byte, essentially using binary to store numbers in base 10. Thus, 0.1 + 0.2 would be exactly 0.3

Last edited by Greg8128 (April 25, 2021 06:46:04)

Jonathan50
Scratcher
1000+ posts

Why Scratch cant do math (0.1 + 0.2 = 0.300...004)

Greg8128 wrote:

crabraveprogrammer0 wrote:

We cannot display 0.1 in binary… It is a forever repeating decimal.
Why not?
Try using long division in binary to find 1 divided by 1010 (ten.)

(Ok, you don't really have to. )

Like so:
              ____
0.00011001100
---------------
1010)1.000000000000
1010
------
1100
1010
----
10000 This is the dividend times a power of two, so you can stop here.
1010
-----
1100
1010
----
10000

Last edited by Jonathan50 (April 25, 2021 07:54:12)

46009361
Scratcher
1000+ posts

Why Scratch cant do math (0.1 + 0.2 = 0.300...004)

Sorry, the Scratch Team isn't accepting new guides right now. Even griffpatch's Scratcharia got broken a while ago due to the new cloud data limitations, which have since been upgraded from 128 to 256 characters.
Chiroyce
Scratcher
1000+ posts

Why Scratch cant do math (0.1 + 0.2 = 0.300...004)

46009361 wrote:

Sorry, the Scratch Team isn't accepting new guides right now. Even griffpatch's Scratcharia got broken a while ago due to the new cloud data limitations, which have since been upgraded from 128 to 256 characters.
uhh … we're talking about floating point numbers, decimals and fractions, not ☁ Cloud Variable limits.
gdpr5b78aa4361827f5c2a08d700
Scratcher
1000+ posts

Why Scratch cant do math (0.1 + 0.2 = 0.300...004)

Floating point errors.

EDIT: misread the OP, thought this was a question

Last edited by gdpr5b78aa4361827f5c2a08d700 (April 25, 2021 18:30:27)

Greg8128
Scratcher
500+ posts

Why Scratch cant do math (0.1 + 0.2 = 0.300...004)

Jonathan50 wrote:

Greg8128 wrote:

crabraveprogrammer0 wrote:

We cannot display 0.1 in binary… It is a forever repeating decimal.
Why not?
Try using long division in binary to find 1 divided by 1010 (ten.)

(Ok, you don't really have to. )

Like so:
              ____
0.00011001100
---------------
1010)1.000000000000
1010
------
1100
1010
----
10000 This is the dividend times a power of two, so you can stop here.
1010
-----
1100
1010
----
10000
That's just one way to store numbers using binary data. You could also store a rational number as a pair of integers (numerator and denominator)
6d66yh
Scratcher
100+ posts

Why Scratch cant do math (0.1 + 0.2 = 0.300...004)

Greg8128 wrote:

Jonathan50 wrote:

Greg8128 wrote:

crabraveprogrammer0 wrote:

We cannot display 0.1 in binary… It is a forever repeating decimal.
Why not?
Try using long division in binary to find 1 divided by 1010 (ten.)

(Ok, you don't really have to. )

Like so:
              ____
0.00011001100
---------------
1010)1.000000000000
1010
------
1100
1010
----
10000 This is the dividend times a power of two, so you can stop here.
1010
-----
1100
1010
----
10000
That's just one way to store numbers using binary data. You could also store a rational number as a pair of integers (numerator and denominator)
However, rational storage is not natively supported in hardware, making doubles the better option.
Jonathan50
Scratcher
1000+ posts

Why Scratch cant do math (0.1 + 0.2 = 0.300...004)

Greg8128 wrote:

That's just one way to store numbers using binary data. You could also store a rational number as a pair of integers (numerator and denominator)
Right, the OP meant it can't be written as a sequence of digits with a radix point (in what's according to Wikipedia called a positional numeral system.)

Floating-point numbers (which Sheep_maker demonstrated) and fixed-point numbers (that just means a number is represented by that number times some power of the base, so for example if you have a 32-bit machine word, the higher order 16 bits could be the integer part and the lower order 16 bits the fractional part) make arithmetic simpler for the machine. It's like if you only had to add fractions with denominators that were powers of ten. The disadvantage is they precisely represent different sets of numbers (if the numerator and denominator are arbitrary precision integers then one can represent any rational number in the manner you're describing, though some will take more space because of the denominator.)

Last edited by Jonathan50 (April 25, 2021 21:51:03)

VilladeOnScratch
Scratcher
51 posts

Why Scratch cant do math (0.1 + 0.2 = 0.300...004)

how would I fix this?
god286
Scratcher
1000+ posts

Why Scratch cant do math (0.1 + 0.2 = 0.300...004)

VilladeOnScratch wrote:

how would I fix this?
If you are handling money, which only goes to the 0.01 place, then you could just count in cents (100 cents = 1 dollar) and this issue would go away.
If you are handling something else, use the same method but instead of using 0.01 maybe use 0.0001 or some other number depending on your precision amount.

Powered by DjangoBB