Task

Explicitly implement   long multiplication.

This is one possible approach to arbitrary-precision integer algebra.



For output, display the result of    264 * 264.

Optionally, verify your result against builtin arbitrary precision support.

The decimal representation of    264    is:

18,446,744,073,709,551,616

The output of    264 * 264    is    2128,    and is:

340,282,366,920,938,463,463,374,607,431,768,211,456



// Long multiplication per WP article referenced by task description.
// That is, multiplicand is multiplied by single digits of multiplier
// to form intermediate results.  Intermediate results are accumulated
// for the product.  Used here is the abacus method mentioned by the
// article, of summing intermediate results as they are produced,
// rather than all at once at the end.
//
// Limitations:  Negative numbers not supported, superfluous leading zeros
// not generally removed.
package main
 
import "fmt"
 
// argument validation
func d(b byte) byte {
    if b < '0' || b > '9' {
        panic("digit 0-9 expected")
    }
    return b - '0'
}
 
// add two numbers as strings
func add(x, y string) string {
    if len(y) > len(x) {
        x, y = y, x
    }
    b := make([]byte, len(x)+1)
    var c byte
    for i := 1; i <= len(x); i++ {
        if i <= len(y) {
            c += d(y[len(y)-i])
        }
        s := d(x[len(x)-i]) + c
        c = s / 10
        b[len(b)-i] = (s % 10) + '0'
    }
    if c == 0 {
        return string(b[1:])
    }
    b[0] = c + '0'
    return string(b)
}
 
// multipy a number by a single digit
func mulDigit(x string, y byte) string {
    if y == '0' {
        return "0"
    }
    y = d(y)
    b := make([]byte, len(x)+1)
    var c byte
    for i := 1; i <= len(x); i++ {
        s := d(x[len(x)-i])*y + c
        c = s / 10
        b[len(b)-i] = (s % 10) + '0'
    }
    if c == 0 {
        return string(b[1:])
    }
    b[0] = c + '0'
    return string(b)
}
 
// multiply two numbers as strings
func mul(x, y string) string {
    result := mulDigit(x, y[len(y)-1])
    for i, zeros := 2, ""; i <= len(y); i++ {
        zeros += "0"
        result = add(result, mulDigit(x, y[len(y)-i])+zeros)
    }
    return result
}
 
// requested output
const n = "18446744073709551616"
 
func main() {
    fmt.Println(mul(n, n))
}