This tutorial shows how to work with large numbers in Scratch. In this tutorial, numbers may be larger than 1e+21 (1 with 21 zeroes after it)—the limit above which Scratch automatically converts numbers to scientific notation. Instead of using default arithmetic blocks (which round and use scientific notation) on large numbers, these scripts work with numbers' digits to get accurate results.
This method works by displaying the number as a string. This will make the number display normally, no matter now large it is.
| These blocks work only with positive integers. |
Preparation
Variables
(carry): The digit carried.(result): This will store the result.(a index): Which digit of(a)to use.(b index): Which digit of(b)to use.(num): A partial answer.
Blocks
define (a) + (b): Additiondefine (a) - (b): Subtractiondefine (a) × (b): Multiplicationdefine (a) ÷ (b): Division
Scripts
Addition
define (a) + (b) set [a index v] to (length of (a)) set [b index v] to (length of (b)) set [carry v] to [0] set [result v] to [] repeat until <<<(a index) < [1]> and <(b index) < [1]>> and <(carry) = [0]>> set [num v] to (((letter (a index) of (a)) + (letter (b index) of (b))) + (carry)) set [result v] to (join ((num) mod (10)) (result)) set [carry v] to ([floor v] of ((num) / (10))) change [a index v] by (-1) change [b index v] by (-1) end
Subtraction
define (a) - (b) set [a index v] to (length of (a)) set [b index v] to (length of (b)) set [carry v] to [1] // carry = 0 will mean borrowing set [result v] to [] repeat until <<(a index) < [1]> and <(b index) < [1]>> set [num v] to (((letter (a index) of (a)) - (letter (b index) of (b))) + ((9) + (carry))) set [result v] to (join ((num) mod (10)) (result)) set [carry v] to ([floor v] of ((num) / (10))) change [a index v] by (-1) change [b index v] by (-1) end
Multiplication
define (a) × (b)
set [a index v] to (length of (a))
set [b index v] to (length of (b))
set [carry v] to [0]
set [result v] to []
repeat until <<((a index) + (b index)) < [2]> and <(carry) = [0]>>
if <(b index) < [1]> then
change [a index v] by ((b index) - (1))
set [b index v] to [1]
end
set [num v] to (carry)
repeat until <<(a index) < [1]> or <(b index) > (length of (b))>>
change [num v] by ((letter (a index) of (a)) * (letter (b index) of (b)))
change [a index v] by (-1)
change [b index v] by (1)
end
set [result v] to (join ((num) mod (10)) (result))
set [carry v] to ([floor v] of ((num) / (10)))
set [b index v] to (((b index) - (1)) - ((length of (a)) - (a index)))
set [a index v] to (length of (a))
end
Division
(carry:: variables) will give the remainder. |
define (a) ÷ (b) if <(b) = (0)> then // Checks for a division by 0 set [result v] to [NaN] set [carry v] to [NaN] stop [this script v] end set [a index v] to [0] set [carry v] to [] repeat until <not<(b:: custom) > (carry)>> change [a index v] by (1) set [carry v] to (join (carry) (letter (a index) of (a))) end set [result v] to [] repeat (((length of (a)) - (a index)) + (1)) change [a index v] by (1) set [result v] to (join (result) ([floor v] of ((carry) / (b)))) set [carry v] to (join ((carry) mod (b)) (letter (a index) of (a))) end