-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlong_multiplication.sf
49 lines (44 loc) · 1.42 KB
/
long_multiplication.sf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#!/usr/bin/ruby
# Long multiplication algorithm.
#
## https://rosettacode.org/wiki/Long_multiplication
#
func add_with_carry(result, addend, addendpos) {
loop {
while (result.len < addendpos+1) {
result.append(0)
}
var addend_digits = (addend.to_i + result[addendpos].to_i -> digits.reverse)
result[addendpos] = addend_digits.pop
addend_digits.len > 0 || break
addend = addend_digits.pop
addendpos++
}
}
func longhand_multiplication(multiplicand, multiplier) {
var result = []
var multiplicand_offset = 0
multiplicand.reverse.each { |multiplicand_digit|
var multiplier_offset = multiplicand_offset
multiplier.reverse.each { |multiplier_digit|
var multiplication_result = (multiplicand_digit.to_i * multiplier_digit.to_i -> to_s)
var addend_offset = multiplier_offset
multiplication_result.reverse.each { |result_digit_addend|
add_with_carry(result, result_digit_addend, addend_offset)
addend_offset++
}
multiplier_offset++
}
multiplicand_offset++
}
return result.join.reverse
}
say longhand_multiplication('18446744073709551616', '18446744073709551616')
assert_eq(longhand_multiplication(Str(2**64), Str(2**128)), Str(2**64 * 2**128))
assert_eq(longhand_multiplication(Str(3**54), Str(5**118)), Str(3**54 * 5**118))