DWise1: Old German Multiplication Method


"Do the math!" - Sega 16-bit video game-set commercial, c. mid-1980's

Abstract

A couple weeks ago on YouTube I stumbled upon an odd offering: Altes Multiplizieren - vergessenes Wissen! Das hast du noch nie gesehen! ("Old Multiplication -- Forgotten Knowledge. You have never seen that before!"). The video series is "Lernen mit Lehrer Schmidt" ("Learn with Teacher Schmidt") and appears to be math videos by a math teacher, though at his web site he also covers topics such as physics, German (grammar and literature), and handicrafts. They are of course in German without subtitles.

Basically, the method is to iteratively double one number and halve the other (always rounding down), then adding together all the doubled numbers for which the corresponding halved numbers are odd. It looks very strange and I was about to try to figure it out with an algebraic proof when I saw a comment describe it as a binary operation. I immediately recognized it as the standard binary multiplication method I had learned decades ago for my computer science degree; I hadn't realized that because this one was using decimal numbers instead of binary ones. Now what he's doing makes perfect sense.

This method is certainly old. Most of the comments either said that they had never seen this before or else their grandparents had shown it to them (these were mainly middle-aged or senior themselves). What I'm still not sure of is whether this was indeed how everybody used to be taught in German schools and if this method was also used in other countries. We do know that binary mathematics go back to ancient India and Egypt, so it would make sense that a mathematician would have devised this method long ago. I have found this method described in Wikipedia as Russian Peasant Multiplication, the advantage being that you do not need to memorize multiplication tables but rather you only need to know how to multiply and divide by 2 and to add.

 

Since not everybody understands German, I'm writing this page to present the method in English. Then I describe binary multiplication to show how and why this works.

 


The Method

Here's the basic procedure:
  1. Write the numbers side by side with the smaller number on the left.
  2. Successively double the number on the right and halve the number on the left until the number on the left is one (1). When you halve an odd number, just drop the fraction (ie, round down).
  3. Cross out (ie, remove) all lines where the number on the left is even.
  4. Add all the remaining numbers on the right and you get the answer.

Here are the examples from the video:

  • Set up the problems and do the doubling and halving:
  •     5 × 25        4 × 35        3 × 25       5 × 35        7 × 45        6 × 40        7 × 21      12 × 31
    
       5 --  25      4 --  35      3 -- 25      5 --  35      7 --  45      6 --  40      7 -- 21     12 --  31
       2 --  50      2 --  70      1 -- 50      2 --  70      3 --  90      3 --  80      3 -- 42      6 --  62
       1 -- 100      1 -- 140                   1 -- 140      1 -- 180      1 -- 160      1 -- 84      3 -- 124
                                                                                                       1 -- 248   
    

  • Eliminate the lines with an even number on the left by crossing out those lines:
  •     5 × 25        4 × 35        3 × 25       5 × 35        7 × 45        6 × 40        7 × 21      12 × 31
    
       5 --  25      4 --  35      3 -- 25      5 --  35      7 --  45      6 --  40      7 -- 21     12 --  31 
       2 --  50      2 --  70      1 -- 50      2 --  70      3 --  90      3 --  80      3 -- 42      6 --  62 
       1 -- 100      1 -- 140                   1 -- 140      1 -- 180      1 -- 160      1 -- 84      3 -- 124
                                                                                                       1 -- 248   
    
    

  • Add the remaining numbers on the right, which are the ones with an odd number on the left:
  •     5 × 25        4 × 35        3 × 25       5 × 35        7 × 45        6 × 40        7 × 21      12 × 31
    
       5 --  25      4 --  35      3 -- 25      5 --  35      7 --  45      6 --  40      7 -- 21     12 --  31 
       2 --  50      2 --  70      1 -- 50      2 --  70      3 --  90      3 --  80      3 -- 42      6 --  62 
       1 -- 100      1 -- 140                   1 -- 140      1 -- 180      1 -- 160      1 -- 84      3 -- 124
                                                                                                       1 -- 248   
           -----         -----         ----         -----         -----         -----        -----         -----
            125           140           75           175           315           240          147           372
    

    And so you can see that it works.

    If your browser does not support the strikethrough tag that I used, then refer to this write-up as you watch the video, in which Lehrer Schmidt writes all this out, one problem at a time (yes, that really is how they write ones and sevens and nines). There you can see him crossing out the lines with an even number on the left and leaving those lines out of the addition step.

     


    How It Works (Multiplying in Binary)

    So how does it work? I was ready to try to work it out algebraically when I noticed an entry in the comments section that this was binary multiplication. It was about four decades ago and I forget whether it was while working on my computer science degree or before that while going through military technical training as an electronic computer systems repairman (more likely the latter) that we were taken through how a computer performs integer multiplication. Basically, that operation is a series of shifts and conditional adds, which I will discuss below.

    But first we need some background knowledge so that everyone can understand it.

     

    Basic Number Theory

    Don't be afraid. It's just simply how we do position-value numbers (which you just know as "numbers") and how that translates to other number bases (maybe the only new concept for you here). That was a most of the "New Math" in the mid-1960's when I had it in junior high summer school. I understood it completely right away, but then we spent weeks of monotonous busy work in order to drum it into us (Trivia note: in German student slang, a teacher is a "Pauker", a drum beater, because he drums the subject matter into your head).

    We'll work first in decimal, AKA "Base 10" because it uses ten digits which range from 0 to 9. Those digits are placed into positions in the number which define their values. The other number bases work their numbers the same way as decimal, the difference being how many digits they use which will also change the positions' values.

    For example, consider the number 1234, one thousand two hundred thirty four. Going from right to left, the positions are "the one's place", "the ten's place", "the hundred's place", and "the thousand's place". So to find the value of 1234, we take each digit, multiply it by its position's value, and finally add them all together. Therefore:

    1234 = 1 × 1,000 + 2 × 100 + 3 × 10 + 4 × 1 = 1,000 + 200 + 30 + 4
    Yeah, it's that simple. And the New Math had us spend half the summer decomposing numbers and then performing basic arithmetic with those decomposed numbers. But it helps us to understand how to work with other number bases.

    Please note that the position values are based on the powers of the number of digits in the number base, which for decimal is 10:

    1 = 100; 10 = 101; 100 = 102; 1,000 = 103
    Therefore:
    1234 = 1 × 103 + 2 × 102 + 3 × 101 + 4 × 100 = 4 + 30 + 200 + 1,000
    That more general form is the key to creating numbers in other number bases. Since our goal here is working in binary, let's examine that.

    Binary, Base 2, has two digits, 1 and 0. The position values of a binary number are:

    20 = 1
    21 = 2
    22 = 4
    23 = 8
    24 = 16
    25 = 32
    26 = 64
    27 = 128
    So if we take the binary number 00100111, we find that we have ones in the 32's place, the 4's place, the 2's place, and the 1's place. To convert that number to its decimal equivalent, we add the values of the ones: 32 + 4 + 2 + 1 = 39. I should also mention that with 8 bits (binary digits) you can express 256 (28) values ranging from 0 to 255.

    I'll quickly mention two other bases that programmers have commonly worked with: octal (Base 8) and hexadecimal (Base 16). The reason why they are so common is because you can easily convert back and forth between them and binary. With three bits you can represent 8 digits (0 to 7) and with 4 bits you can represent 16 digits (0 to F). To convert from binary to octal or hexadecimal you group the bits by 3 or by 4, respectively, and simply read them. Every experienced programmer has the binary code for those digits memorized from repeated use. These two number bases are of no use in this discussion, but if you're interested in learning more about them then follow those links to their Wikipedia articles.

     

    Long Multiplication

    Since binary multiplication is derived from decimal long multiplication, we'll review decimal first.

    Let's start with an example problem: 4,096 × 1,024 = 4,194,304 (yes, that's 212 × 210 = 222; I am a programmer after all). We will need this terminology: 4,096 is the multiplicand, 1,024 is the multiplier, and 4,194,304 is the product.

    I will use the standard form that I learned in elementary school in the late 1950's. I'm qualifying this just in case they've changed how they teach it 1, or in case you're from a country where it's done differently. So to examine that standard form, let's revert to the New Math approach of the mid-60's in order to see exactly what's happening:

  • Decompose the multiplier and write the problem thus:
  • product = 4,096 × (1,000 × 1 + 100 × 0 + 10 × 2 + 1 × 4)

  • Applying the commutative property to the decomposed multiplier, we reorder its terms to the order we will use in long multiplication:
  • product = 4,096 × (1 × 4 + 10 × 2 + 100 × 0 + 1,000 × 1)

  • Now apply the distributive property:
  • product = 4,096 × (1 × 4 + 10 × 2 + 100 × 0 + 1,000 × 1)
                = (4,096 × 1 × 4) + (4,096 × 10 × 2) + (4,096 × 100 × 0) + (4,096 × 1,000 × 1)

  • Of course, the terms being multiplied by zero will be zero and hence can just be dropped out:
  • product = (4,096 × 1 × 4) + (4,096 × 10 × 2) + (4,096 × 1,000 × 1)

  • Next, in each term we multiply the multiplicand by the indicated powers of ten, which is accomplished by shifting the multiplicand left one place per zero:
  • product = (4,096 × 4) + (40,960 × 2) + (4,096,000 × 1)

  • Now in each term we multiply the multiplicand by the multiplier's digits:
  • product = (4,096 × 4) + (40,960 × 2) + (4,096,000 × 1)
    product = 16,384 + 81,920 + 4,096,000

  • And finally we add the terms together to get the product:
  • product = 4,194,304

    That is what we are doing in long multiplication. We will use this understanding to approach long multiplication in binary.

    Now let's apply our understanding to the standard format (at least the one taught when I went through the program):

  • Write the problem, leaving out those pesky commas:
  •          4096    Multiplicand
           × 1024    Multiplier
        ---------
    
    

  • Multiply the multiplier's 1's digit (4) to the multiplicand with zero shift (ie, × 100):
  •          4096    Multiplicand
           × 1024    Multiplier
        ---------
            16384
    
    

  • Multiply the multiplier's 10's digit (2) to the multiplicand with a left shift of 1 (ie, × 101). Note that I am including the right-most zero in order to show that explicit multiplication by a power of ten, whereas we were taught to just shift it left and leave a blank:
  •          4096    Multiplicand
           × 1024    Multiplier
        ---------
            16384
            81920   
    
    

  • Multiply the multiplier's 100's digit (0) to the multiplicand with a left shift of 2 (ie, × 102). Since we're multiplying by zero, we do not write anything down. However, another left shift has occurred, which we will see in the next step.
  •          4096    Multiplicand
           × 1024    Multiplier
        ---------
            16384
            81920   
    
    

  • Multiply the multiplier's 1,000's digit (1) to the multiplicand with a left shift of 3 (ie, × 103):
  •          4096    Multiplicand
           × 1024    Multiplier
        ---------
            16384
            81920   
          4096000
    
    

  • Add the terms to get the product:
  •          4096    Multiplicand
           × 1024    Multiplier
        ---------
            16384
            81920   
          4096000
        ---------
          4194304    Product
    

    And just so that you can see it in a more familiar form, here is the final result with zeros replaced by blanks:

             4096    Multiplicand
           × 1024    Multiplier
        ---------
            16384
            8192   
          4096
        ---------
          4194304    Product
    

    Now as we move on to long multiplication in binary, we will see that it works the same way. However, there are a couple things that makes it much easier and which are reflected in this "Old Multiplication" method.

     


    Footnote 1:
    In 1964 Tom Lehrer wrote his satirical song, New Math, for the US version of the TV weekly news satire, That Was The Week That Was (TW3). The song was released on Tom Lehrer's album, That Was The Year That Was, along with his other songs for TW3 and his performance of the song in concert is on YouTube.

    The premise of the song is that the changes in the New Math means that parents can no longer help their children with their homework, so he offers a quick lesson to bring the parents up to speed with a simple subtraction problem. After doing it in decimal (Base 10), he notices that the book asks that we do it in Base 8 (octal -- "Don't worry. Base 8 is just like Base 10 if you're missing two fingers.").

    While working with that problem, he reveals an earlier case of a change in how borrowing in subtraction was done. I was taught to "borrow 1" (actually 10 because of position values) from the top digit immediately to the left. But (in 1964) if you're over 35 or went to a private school, you would add 1 to the bottom digit immediately to the left. My mother told me that that was how she was taught to do it. I have a 1914 arithmetic primer for grades 1 through 6 which uses that same technique.

    Another example was when my older sister was learning algebra, so our father would help her with her homework. Then one day she brought home a note from her teacher asking our father to stop helping her because he was using different methods from what they were teaching.


     

    Binary Multiplication

    Long multiplication in binary works like long multiplication in decimal, except for two things:

    1. Since the place values are in powers of two, when you shift a binary number to the left, then you are multiplying it by 2. And when you shift to the right, you are dividing by 2. This fact ties in directly to the "Old Multiplication" method.

    2. The only things you will multiply the multiplicand by will be either zero or one. Multiplying anything by zero is always zero. Multiplying anything by one is always itself -- just keep in mind that for each iteration we will have shifted the multiplicand to the left.

    That second item, that you're multiplying by only 0 or 1, both of which are trivial to do. That is one reason why Lehrer Schmidt's method is so easy to use.

    Addition of two bits (A and B) can be represented by the following truth table:

    A + B
    ABSumCarry
    0000
    0110
    1010
    1101

    Note the last line where you add 1 + 1 = 2, which in binary would be 102, just as in decimal 5 + 5 = 1010. In both cases, the sum in that position is zero with a 1 being carried to the next higher position.

    Since keeping track of carries can get messy in long-column addition in binary, I will modify the long-multiplication method slightly by performing an addition in each iteration, thus maintaining a running subtotal. This will also reflect how the integer multiplication algorithm is performed on a computer.

    For our example, let's use one of Lehrer Schmidt's examples: 12 × 31. In binary, 1210 = 11002 and 3110 = 111112. For this example I will not show leading zeros, but in a computer those leading zeros will be there.

  • Set up the problem:
  •       11002 × 111112
    
            11111    Multiplicand
           × 1100    Multiplier
        ---------
    
    

  • Multiply the multiplier's 1's digit (0) to the multiplicand with zero shift (ie, 20) Since we're multiplying by zero, we do not write anything down.
  •         11111    Multiplicand
           × 1100    Multiplier
        ---------
    
    

  • Multiply the multiplier's 2's digit (0) to the multiplicand with a left shift of one (ie, 21) Since we're multiplying by zero, we do not write anything down.
  •         11111    Multiplicand
           × 1100    Multiplier
        ---------
    
    

  • Multiply the multiplier's 4's digit (1) to the multiplicand with a left shift of two (ie, 22) Since we're multiplying by one, write the shifted multiplicand down. Since it's the first term, do not add (nothing to add it to except zero).
  •         11111    Multiplicand
           × 1100    Multiplier
        ---------
          1111100
    
    

  • Multiply the multiplier's 8's digit (1) to the multiplicand with a left shift of three (ie, 23) Since we're multiplying by one, write the shifted multiplicand down and add it to the previous term.
            11111    Multiplicand
           × 1100    Multiplier
        ---------
          1111100
         11111000
        ---------
        101110100
    
    

  • Since the remaining higher-order bits of the multiplier are all zero, the subtotal is the final sum and hence the product.
  •         11111    Multiplicand
           × 1100    Multiplier
        ---------
          1111100
         11111000
        ---------
        101110100    Product
    
        1011101002 = 37210
    
    
  • Refer to the description of Lehrer Schmidt's method and look at this problem, 12 31, and note:

    1. We get the same product, 372.

    2. Lehrer Schmidt's example ignored the first two multiplications (evens) and only uses the last two (odds), just as we just did.

    So this demonstrates that Lehrer Schmidt's method is using binary multiplication. However, in order to more closely match what he's doing we need to look at how computers multiply integers.

     

    How Computers Multiply

    One of the techniques that programmers use is to "play computer" with pencil and paper. That is to say that we will test an algorithm or code function by stepping through the algorithm/code writing down the values of all the variables and examining the results. That is basically what Lehrer Schmidt is doing in his method. And I will do the same here.

    Here is a highly simplified explanation of how computers work. In general (ie, actual mileage may vary in some specialized hardware):

     

    So from the perspective of CPU instructions and registers, here is the algorithm for performing integer multiplication:

    1. Load two shift registers with the multiplier and multiplicand and zero out a third register, an accumulator, which will end up containing the product.
    2. If the multiplier is zero, exit. The product is in the accumulator.
    3. Test the least significant bit (LSB) of the multiplier. If the LSB is a 1, then add the multiplicand to the accumulator.
    4. Shift the multiplicand left by 1 (double it) and shift the multiplier right by 1 (halve it).
    5. Goto Step 2.

    Did I forget to define even and odd numbers? Algebraically, an even number is 2n while an odd number is 2n+1. In a binary number, if the least significant bit (LSB) is a zero, then the number is even, but if the LSB is a one then the number is odd.

    Now let's play computer! This is what I have done repeatedly for the four decades of my computer engineering training and career.

    First, let's assign values to registers. If we were doing this in a higher-level language, these would be variables -- for the last few decades of my career, I mostly worked in C, which occupies a gray zone between higher- and lower-level languages, a comfortable place for a traditional programmer to be in.

    Let's set up three registers/variables: the multiplier, the multiplicand, and the accumulator as referred to in the algorithm specified directly above. The accumulator (to which the shifted multiplicand will be added as per the algorithm and which will end up containing the product). We will load the multiplier value into the multiplier, the multiplicand into the multiplicand, and zero into the accumulator. Also note that, if registers are used, the multiplier and multiplicand registers must support shifting.

    Our example will be one of Lehrer Schmidt's examples: 5 × 25 → 1012 × 110012:

        5 × 25 --> 1012 × 110012
    
       multiplier     multiplicand    accumulator
        0101             11001               0        Load the registers.
        0101             11001           11001        Shift.  LSB is 1 (ie, line is odd) so add to the accumulator.
        0010            110010           11001        Shift.  LSB is 0 (ie, line is even) so do not add to the accumulator.
        0001           1100100         1111101        Shift.  LSB is 1 (ie, line is odd) so add to the accumulator.
        0000          11001000         1111101        multiplier is zero, so exit. Product is in the accumulator.
        
       11111012 = 12510
    

    Here's another example, the one we did binary long multiplication one above, 4 × 35:

        4 × 35 --> 11002 × 111112
    
       multiplier     multiplicand    accumulator
        1100             11111               0        Initialize the registers.
        1100             11111               0        Shift.  LSB is 0 (ie, line is even) so do not add to the accumulator.
        0110            111110               0        Shift.  LSB is 0 (ie, line is even) so do not add to the accumulator.
        0011           1111100         1111100        Shift.  LSB is 1 (ie, line is odd) so add to the accumulator
        0001          11111000       101110100        Shift.  LSB is 1 (ie, line is odd) so add to the accumulator
        0000          11111000       101110100        multiplier is zero, so exit. Product is in the accumulator.
    
        1011101002 = 37210
    

     

    That is what Lehrer Schmidt is doing in his video, except he keeps the values in their decimal form instead going straight to binary. Decimal numbers still retain their binary properties; you just cannot see that.

     


    The Multiplication Algorithm in C

    Here's a simple implementation of the binary multiplication algorithm in a higher-level language, C. Note that I have not tested it for negative numbers (which would be represented with two's complement, but I've taxed your brain too much already).

        long multiply(int multiplicand, int multiplier)
        {
            long acc = 0L;           // declare accumulator and initialize it to zero
    
            // ensure that multiplicand is non-zero
            if (multiplicand)
            {
                while (multiplier)       // loop while multiplier is not zero
                {                        // in all tests, zero == false, non-zero == true
                    if (multiplier & 1)  // perform AND to test LSB.  
                    {                    //  if LSB is 1, then multiplier is odd
                        acc += multiplicand;    // add multiplicand to the accumulator
                    }
                    multiplicand <<= 1;   // double multiplicand; shift left by one
                    multiplier >>= 1;     // halve multiplier; shift right by one
                }
            }
    
            return acc;
        }
    

    This code is provided solely for educational purposes and should not be used in commercial products. Besides, C fully supports multiplication and division. This kind of code would only be needed for emulating multiplication in assembly programs for processors that do have a multiply instructions, but in that case you should be using a third-party math emulation package.

     


    Return to DWise1's Home Page

    Contact me.


    Share and enjoy!

    First uploaded on 2019 September 27.