long_multiplication.sf 1.4 KB

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