20160819 01:25:18 +00:00



# Russian Peasant Multiplication





20200205 16:46:06 +00:00



From Assembly to Basic to Javascript!

20160819 01:33:28 +00:00




20200205 16:46:06 +00:00



Here are my implementations of Russian Peasant Multiplication implemented in various languages:

20160819 01:25:18 +00:00




20200205 16:46:06 +00:00



* 6502 Assembly Language (Both [ca65](rpm_ca65.s) and [merlin32](rpm_m32.s) sources)

20160819 01:25:18 +00:00



* Applesoft BASIC




* JavaScript (Procedural version)




* JavaScript (OOP version)





20160819 01:33:28 +00:00



A .dsk image has been provided as an convenience.

20160819 01:25:18 +00:00







To see how much faster the Assembly version is then the BASIC version:








```




RUN RPM.BAS




BRUN RPM.BIN




```








And enter in `123456789` * `987654321` respectively for A and B ...








 Version  Time 




::




 Applesoft  33 s 




 Assembly  ~1 s 





20160819 14:17:35 +00:00



# So what the heck is it?





20160819 14:52:19 +00:00



An alternative algorithm to implement multiplication using only:

20160819 14:17:35 +00:00




20200205 16:46:25 +00:00



* bitshifts (left and right), and

20160819 14:17:35 +00:00



* addition.





20160819 15:13:09 +00:00



Example of "traditional" multiplication:

20160819 14:17:35 +00:00







In base 10:








```




86




x 57









602




430




====




4902




```








In base 2:





20160819 14:20:26 +00:00



```

20160819 14:17:35 +00:00



01010110 (86)




00111001 (57)









01010110 (86 * 2^0 = 86)

20200205 16:46:48 +00:00



00000000 (86 * 2^1 = 172) < wasted work, partial sum = 0




00000000 (86 * 2^2 = 344) < wasted work, partial sum = 0

20160819 14:17:35 +00:00



01010110 (86 * 2^3 = 688)




01010110 (86 * 2^4 = 1376)




01010110 (86 * 2^5 = 2752)




==============




01001100100110 (4902 = 86*2^0 + 86*2^3 + 86*2^4 + 86*2^5)

20160819 14:20:26 +00:00



```

20160819 14:17:35 +00:00







Example of Russian Peasant multiplication:








In Base 10:








```

20200205 16:48:04 +00:00



A B B Odd? Sum = 0




86 57 Yes + A = 86




x 2 = 172 / 2 = 28 No = 86




x 2 = 344 / 2 = 14 No = 86




x 2 = 688 / 2 = 7 Yes + A = 774




x 2 = 1376 / 2 = 3 Yes + A = 2150




x 2 = 2752 / 2 = 1 Yes + A = 4902

20160819 14:17:35 +00:00



```








In Base 2:








```

20160819 15:13:09 +00:00



A B Sum = 0




01010110 00111001 + A = 00000001010110 (b is odd)




010101100 00011100 = 00000001010110




0101011000 00001110 = 00000001010110




01010110000 00000111 + A = 00001100000110 (b is odd)




010101100000 00000011 + A = 00100001100110 (b is odd)




0101011000000 00000001 + A = 01001100100110 (b is odd)

20160819 14:17:35 +00:00



```

20200205 16:48:04 +00:00







In Base 8:








```




A B B Odd? Sum = 0




126 71 Yes + A = 126




x 2 = 254 / 2 = 34 No = 126




x 2 = 530 / 2 = 16 No = 126




x 2 = 1260 / 2 = 7 Yes + A = 1406




x 2 = 2540 / 2 = 3 Yes + A = 4146




x 2 = 5300 / 2 = 1 Yes + A = 11446




```








In Base 16:








```




A B B Odd? Sum = 0




56 39 Yes + A = 56




x 2 = AC / 2 = 1C No = 56




x 2 = 158 / 2 = E No = 56




x 2 = 2B0 / 2 = 7 Yes + A = 306




x 2 = 560 / 2 = 3 Yes + A = 866




x 2 = AC0 / 2 = 1 Yes + A = 1326




```





20200205 16:48:54 +00:00



Algorithm:








1. Initialize Sum < zero




2. If B is odd then add A to Sum. In C nomenclature: `Sum += A;`




3. Multiply A by 2  that is, Shift A **left** by one. In C nomenclature: `A <<= 1;`




4. Divide B by 2  that is, Shift B **right** by one. In C nomenclature: ` B >>= 1;`




5. If B is zero then STOP




6. Goto step 2








For a "BigInt" or "BigNumber" library this _isn't_ the most efficient way to




multiply numbers but it is rather trivial to implement. You only need a few




functions:








* `isEven()`




* `isZero()`




* `Shl()`




* `Shr()`




* `AddTo()`

20200205 16:48:04 +00:00



