Long multiplication: Difference between revisions

m
(→‎{{header|Quackery}}: typo and text clarified)
m (→‎{{header|Wren}}: Minor tidy)
 
(44 intermediate revisions by 17 users not shown)
Line 23:
{{trans|Python}}
 
<langsyntaxhighlight lang="11l">F add_with_carry(&result, =addend, =addendpos)
L
L result.len < addendpos + 1
Line 53:
 
V sixtyfour = ‘18446744073709551616’
print(longhand_multiplication(sixtyfour, sixtyfour))</langsyntaxhighlight>
 
{{out}}
Line 62:
=={{header|360 Assembly}}==
For maximum compatibility, we use only the basic 370 instruction set (use of MVCL). Pseudo-macro instruction XPRNT can be replaced by a WTO.
<langsyntaxhighlight lang="360asm">LONGINT CSECT
USING LONGINT,R13
SAVEAREA B PROLOG-SAVEAREA(R15)
Line 334:
LL EQU 94
YREGS
END LONGINT</langsyntaxhighlight>
{{out}}
<pre>
18446744073709551616
340282366920938463463374607431768211456
</pre>
=={{header|AArch64 Assembly}}==
{{works with|as|Raspberry Pi 3B version Buster 64 bits <br> or android 64 bits with application Termux }}
<syntaxhighlight lang AArch64 Assembly>
/* ARM assembly AARCH64 Raspberry PI 3B */
/* program longmulti64.s */
/* REMARK : this program use factors unsigned to 2 power 127
and the result is less than 2 power 255 */
/************************************/
/* Constantes */
/************************************/
/* for this file see task include a file in language AArch64 assembly*/
.include "../includeConstantesARM64.inc"
.equ BUFFERSIZE, 100
 
/***********************************************/
/* structures */
/**********************************************/
/* Définition multi128 */
.struct 0
multi128_N1: // 63-0
.struct multi128_N1 + 8
multi128_N2: // 127-64
.struct multi128_N2 + 8
multi128_N3: // 128-191
.struct multi128_N3 + 8
multi128_N4: // 192-255
.struct multi128_N4 + 8
multi128_end:
/*********************************/
/* Initialized data */
/*********************************/
.data
szMessFactor: .asciz "Factor = "
szMessResult: .asciz "Result = "
szMessStart: .asciz "Program 64 bits start.\n"
szCarriageReturn: .asciz "\n"
 
i128test1: .quad 0,1,0,0 // 2 power 64
/*********************************/
/* UnInitialized data */
/*********************************/
.bss
sZoneConv: .skip BUFFERSIZE // conversion buffer
i128Result1: .skip multi128_end
 
/*********************************/
/* code section */
/*********************************/
.text
.global main
main: // entry of program
ldr x0,qAdrszMessStart
bl affichageMess
ldr x0,qAdri128test1 // origin number
ldr x1,qAdrsZoneConv
mov x2,#BUFFERSIZE
bl convertMultiForString // convert multi number to string
mov x2,x0 // insert conversion in message
mov x0,#3 // string number to display
ldr x1,qAdrszMessFactor
ldr x3,qAdrszCarriageReturn
bl displayStrings // display message
// multiplication
ldr x0,qAdri128test1 // factor 1
ldr x1,qAdri128test1 // factor 2
ldr x2,qAdri128Result1 // result
bl multiplierMulti128
ldr x0,qAdri128Result1
ldr x1,qAdrsZoneConv
mov x2,#BUFFERSIZE
bl convertMultiForString // conversion multi to string
mov x2,x0 // insert conversion in message
mov x0,#3 // number string to display
ldr x1,qAdrszMessResult
ldr x3,qAdrszCarriageReturn
bl displayStrings // display message
100: // standard end of the program
mov x0, #0 // return code
mov x8,EXIT
svc #0 // perform the system call
qAdrszCarriageReturn: .quad szCarriageReturn
qAdrsZoneConv: .quad sZoneConv
qAdri128test1: .quad i128test1
qAdri128Result1: .quad i128Result1
qAdrszMessResult: .quad szMessResult
qAdrszMessFactor: .quad szMessFactor
qAdrszMessStart: .quad szMessStart
/***************************************************/
/* multiplication multi128 by multi128 */
/***************************************************/
// x0 contains address multi128 1
// x1 contains address multi128 2
// x2 contains address result multi128
// x0 return address result (= x2)
multiplierMulti128:
stp x1,lr,[sp,-16]! // save registers
mov x9,x0 // factor 1
mov x10,x1 // factor 2
mov x7,x2 // address result
mov x6,#3 // multi128 size
1:
str xzr,[x7,x6,lsl #3] // init result
subs x6,x6,#1
bge 1b
mov x5,#0 // indice loop 1
2: // loop items factor 1
ldr x0,[x9,x5,lsl #3] // load a item
mov x4,#0
mov x8,#0
3: // loop item factor 2
add x6,x4,x5 // compute result indice
ldr x1,[x10,x4,lsl #3] // load a item factor 2
mul x2,x1,x0 // multiply low 64 bits
umulh x3,x1,x0 // multiply high 64 bits
ldr x1,[x7,x6,lsl #3] // load previous item of result
adds x1,x1,x2 // add low part result multiplication
mov x11,1
csel x2,x11,xzr,cs
adds x1,x1,x8 // add high part precedente
adc x8,x3,x2 // new high part with retenue
str x1,[x7,x6,lsl #3] // store the sum in result
add x4,x4,#1
cmp x4,#3
blt 3b // and loop 2
cmp x8,#0 // high part ?
beq 5f
add x6,x6,#1
cmp x6,#2 // on last item ?
ble 4f
adr x0,szMessErrOverflow // yes -> overflow
bl affichageMess
mov x0,#0 // return 0
b 100f
4:
str x8,[x7,x6,lsl #3] // no store high part in next item
5:
add x5,x5,#1
cmp x5,#3
blt 2b // and loop 1
mov x0,x7
 
100:
ldp x1,lr,[sp],16 // restaur registers
ret
szMessErrOverflow: .asciz "\033[31mOverflow !!\033[0m \n"
.align 4
 
/***************************************************/
/* conversion multi128 unsigned to string */
/***************************************************/
// x0 contains address multi128
// x1 contains address buffer
// x2 contains buffer length
convertMultiForString:
stp x1,lr,[sp,-16]! // save registers
stp x2,x3,[sp,-16]! // save registers
stp x4,x5,[sp,-16]! // save registers
sub sp,sp,#multi128_end // reserve place to stack
mov fp,sp // init address to quotient
mov x5,x1 // save address buffer
mov x3,#0 // init indice
1:
ldr x4,[x0,x3,lsl #3] // load one part of number
str x4,[fp,x3,lsl #3] // copy part on stack
add x3,x3,#1
cmp x3,#4
blt 1b
2:
strb wzr,[x5,x2] // store final 0 in buffer
sub x4,x2,#1 // end number storage
3:
mov x0,fp
mov x1,#10
bl calculerModuloMultiEntier // compute modulo 10
add x0,x0,#0x30 // convert result to character
strb w0,[x5,x4] // store character on buffer
subs x4,x4,#1 //
blt 99f // buffer too low
ldr x0,[fp,#multi128_N1] // test if quotient = zero
cmp x0,#0
bne 3b
ldr x0,[fp,#multi128_N2]
cmp x0,#0
bne 3b
ldr x0,[fp,#multi128_N3]
cmp x0,#0
bne 3b
ldr x0,[fp,#multi128_N4]
cmp x0,#0
bne 3b
 
add x0,x5,x4 // return begin number in buffer
add x0,x0,#1
b 100f
99: // display error if buffer est toop low
adr x0,szMessErrBuffer
bl affichageMess
mov x0,#-1
100:
add sp,sp,#multi128_end // stack alignement
ldp x4,x5,[sp],16 // restaur registers
ldp x2,x3,[sp],16 // restaur registers
ldp x1,lr,[sp],16 // restaur registers
ret
szMessErrBuffer: .asciz "\033[31mBuffer de conversion trop petit !!\033[0m \n"
.align 4
/***************************************************/
/* modulo compute unsigned */
/***************************************************/
// x0 contains address multi128
// x1 contains modulo (positive)
// x0 return modulo
// ATTENTION : le multientier origine est modifié et contient le quotient
calculerModuloMultiEntier: // INFO: calculerModuloMultiEntier
stp x1,lr,[sp,-16]! // save registers
stp x2,x3,[sp,-16]! // save registers
stp x4,x5,[sp,-16]! // save registers
cmp x1,#0
ble 99f
mov x4,x1 // save modulo
mov x3,#3
mov x5,x0 // multi128 address
ldr x0,[x5,x3,lsl 3] // load last part of number in low part of 128 bits
mov x1,#0 // init higt part 128 bits
1:
cmp x3,#0 // end part ?
ble 2f
mov x2,x4 // modulo
bl division64R // divide x0,x1 by x2 in x0,x1 and remainder in x2
str x0,[x5,x3,lsl #3] // store result part low
sub x3,x3,#1 // other part ?
ldr x0,[x5,x3,lsl #3] // load prev part
mov x1,x2 // store remainder on high part of 128 bits
b 1b
2:
mov x2,x4 // modulo
bl division64R
str x0,[x5] // stockage dans le 1er chunk
mov x0,x2 // return remainder
b 100f
99:
adr x0,szMessNegatif
bl affichageMess
mov x0,#-1
100: // fin standard de la fonction
ldp x4,x5,[sp],16 // restaur registers
ldp x2,x3,[sp],16 // restaur registers
ldp x1,lr,[sp],16 // restaur registers
ret
szMessNegatif: .asciz "\033[31mLe diviseur doit être positif !\033[0m\n"
.align 4
/***************************************************/
/* division 128 bits number in 2 registers by 64 bits number */
/***************************************************/
/* x0 contains dividende low part */
/* x1 contains dividende high part */
/* x2 contains divisor */
/* x0 return quotient low part */
/* x1 return quotient high part */
/* x2 return remainder */
division64R:
stp x3,lr,[sp,-16]! // save registers
stp x4,x5,[sp,-16]! // save registers
stp x6,x7,[sp,-16]! // save registers
stp x8,x9,[sp,-16]! // save registers
mov x6,#0 // init high high part of remainder !!
// x1 = high part of number in high part of remainder
mov x7,x0 // low part of number in low part of remainder
mov x3,#0 // init high part quotient
mov x4,#0 // init low part quotient
mov x5,#64
1: // begin loop
lsl x6,x6,#1 // left shift high high part of remainder
cmp x1,0 // if negative ie bit 63 = 1
orr x8,x6,1
csel x6,x8,x6,lt // add left bit high part on high high part
lsl x1,x1,#1 // left shift high part of remainder
cmp x7,0
orr x8,x1,1
csel x1,x8,x1,lt // add left bit low part on high part
lsl x7,x7,#1 // left shift low part of remainder
cmp x4,0
lsl x4,x4,#1 // left shift low part quotient
lsl x3,x3,#1 // left shift high part quotient
orr x8,x3,1
csel x3,x8,x3,lt // add left bit low part on high part
// sub divisor to high part remainder
subs x1,x1,x2
sbcs x6,x6,xzr // sub restr.quad (retenue in french)
bmi 2f // result negative ?
// positive or equal
orr x4,x4,#1 // right bit quotient to 1
b 3f
2: // negative
orr x4,x4,xzr // right bit quotient to 0
adds x1,x1,x2 // and restaure the remainder to precedent value
adc x6,x6,xzr // and restr.quad
3:
subs x5,x5,#1 // decrement indice
bgt 1b // and loop
mov x0,x4 // low part quotient
mov x2,x1 // remainder
mov x1,x3 // high part quotient
100:
ldp x8,x9,[sp],16 // restaur registers
ldp x6,x7,[sp],16 // restaur registers
ldp x4,x5,[sp],16 // restaur registers
ldp x3,lr,[sp],16 // restaur registers
ret
/***************************************************/
/* display multi strings */
/* new version 24/05/2023 */
/***************************************************/
/* x0 contains number strings address */
/* x1 address string1 */
/* x2 address string2 */
/* x3 address string3 */
/* x4 address string4 */
/* x5 address string5 */
/* x6 address string5 */
displayStrings: // INFO: displayStrings
stp x7,lr,[sp,-16]! // save registers
stp x2,fp,[sp,-16]! // save registers
add fp,sp,#32 // save paraméters address (4 registers saved * 8 bytes)
mov x7,x0 // save strings number
cmp x7,#0 // 0 string -> end
ble 100f
mov x0,x1 // string 1
bl affichageMess
cmp x7,#1 // number > 1
ble 100f
mov x0,x2
bl affichageMess
cmp x7,#2
ble 100f
mov x0,x3
bl affichageMess
cmp x7,#3
ble 100f
mov x0,x4
bl affichageMess
cmp x7,#4
ble 100f
mov x0,x5
bl affichageMess
cmp x7,#5
ble 100f
mov x0,x6
bl affichageMess
100:
ldp x2,fp,[sp],16 // restaur registers
ldp x7,lr,[sp],16 // restaur registers
ret
/***************************************************/
/* ROUTINES INCLUDE */
/***************************************************/
/* for this file see task include a file in language AArch64 assembly*/
.include "../includeARM64.inc"
 
</syntaxhighlight>
{{Out}}
<pre>
Program 64 bits start.
Factor = 18446744073709551616
Result = 340282366920938463463374607431768211456
</pre>
 
Line 348 ⟶ 721:
 
First we specify the required operations and declare our number type as an array of digits (in base 2^16):
<langsyntaxhighlight lang="ada">package Long_Multiplication is
type Number (<>) is private;
 
Line 381 ⟶ 754:
Result : out Number;
Remainder : out Digit);
end Long_Multiplication;</langsyntaxhighlight>
Some of the operations declared above are useful helper operations for the conversion of numbers to and from base 10 digit strings.
 
Then we implement the operations:
<langsyntaxhighlight lang="ada">package body Long_Multiplication is
function Value (Item : in String) return Number is
subtype Base_Ten_Digit is Digit range 0 .. 9;
Line 529 ⟶ 902:
return Zero;
end Trim;
end Long_Multiplication;</langsyntaxhighlight>
 
And finally we have the requested test application:
<langsyntaxhighlight lang="ada">with Ada.Text_IO;
with Long_Multiplication;
 
Line 542 ⟶ 915:
begin
Put_Line (Image (N) & " * " & Image (N) & " = " & Image (M));
end Test_Long_Multiplication;</langsyntaxhighlight>
 
{{out}}
Line 550 ⟶ 923:
 
The following implementation uses representation of a long number by an array of 32-bit elements:
<langsyntaxhighlight lang="ada">type Long_Number is array (Natural range <>) of Unsigned_32;
 
function "*" (Left, Right : Long_Number) return Long_Number is
Line 573 ⟶ 946:
end loop;
return (0 => 0);
end "*";</langsyntaxhighlight>
 
The task requires conversion into decimal base. For this we also need division to short number with a remainder. Here it is:
<langsyntaxhighlight lang="ada">procedure Div
( Dividend : in out Long_Number;
Last : in out Natural;
Line 596 ⟶ 969:
Remainder := Unsigned_32 (Accum);
Last := Size;
end Div;</langsyntaxhighlight>
 
With the above the test program:
<langsyntaxhighlight lang="ada">with Ada.Strings.Unbounded; use Ada.Strings.Unbounded;
with Ada.Text_IO; use Ada.Text_IO;
with Interfaces; use Interfaces;
Line 624 ⟶ 997:
begin
Put (X);
end Long_Multiplication;</langsyntaxhighlight>
 
Sample output:
Line 632 ⟶ 1,005:
 
=={{header|Aime}}==
<langsyntaxhighlight lang="aime">data b, c, v;
integer d, e, i, j, s;
 
Line 670 ⟶ 1,043:
}
 
o_form("~\n", c);</langsyntaxhighlight>
 
=={{header|ALGOL 60}}==
{{works with|GNU MARST|2.7}}
{{trans|ATS}}
 
<syntaxhighlight lang="algol60">
procedure multiplyBCD (m, n, u, v, w);
comment
Multiply array u of length m by array v of length n,
putting the result in array w of length (m + n). the
numbers are stored as binary coded decimal, most
significant digit first.
;
value m, n;
integer m, n;
integer array u, v, w;
begin
integer i, j, carry, t;
 
for j := 0 step 1 until n - 1 do
begin
if v[n - 1 - j] = 0 then
begin
comment (optional branch);
w[n - 1 - j] := 0
end
else
begin
carry := 0;
for i := 0 step 1 until m - 1 do
begin
t := (u[m - 1 - i] * v[n - 1 - j])
+ w[m + n - 1 - i - j] + carry;
carry := t % 10; comment (integer division);
w[m + n - 1 - i - j] := t - (carry * 10)
end;
w[n - 1 - j] := carry
end
end
end;
 
procedure printBCD (m, u);
value m;
integer m;
integer array u;
begin
integer i, j;
 
comment Skip leading zeros;
i := 0;
for j := i while j < m - 1 & u[j] = 0 do
i := i + 1;
 
comment Print the digits, and separators;
for j := i step 1 until m - 1 do
begin
if j != i & ((m - j) % 3) * 3 = m - j then
begin
comment Print UTF-8 for a narrow no-break space (U+202F);
outstring (1, "\xE2\x80\xAF")
end;
outchar (1, "0123456789", u[j] + 1)
end
end;
 
begin
integer array u[0 : 19];
integer array v[0 : 19];
integer array w[0 : 39];
 
u[0] := 1; u[1] := 8; u[2] := 4; u[3] := 4;
u[4] := 6; u[5] := 7; u[6] := 4; u[7] := 4;
u[8] := 0; u[9] := 7; u[10] := 3; u[11] := 7;
u[12] := 0; u[13] := 9; u[14] := 5; u[15] := 5;
u[16] := 1; u[17] := 6; u[18] := 1; u[19] := 6;
 
v[0] := 1; v[1] := 8; v[2] := 4; v[3] := 4;
v[4] := 6; v[5] := 7; v[6] := 4; v[7] := 4;
v[8] := 0; v[9] := 7; v[10] := 3; v[11] := 7;
v[12] := 0; v[13] := 9; v[14] := 5; v[15] := 5;
v[16] := 1; v[17] := 6; v[18] := 1; v[19] := 6;
 
multiplyBCD (20, 20, u, v, w);
outstring (1, "u = "); printBCD (20, u); outstring (1, "\n");
outstring (1, "v = "); printBCD (20, v); outstring (1, "\n");
outstring (1, "u × v = "); printBCD (40, w); outstring (1, "\n")
end
</syntaxhighlight>
 
{{out}}
<pre>$ marst long_mult_task.algol60 > algol60-code.c && cc algol60-code.c -lalgol && ./a.out
u = 18 446 744 073 709 551 616
v = 18 446 744 073 709 551 616
u × v = 340 282 366 920 938 463 463 374 607 431 768 211 456</pre>
 
=={{header|ALGOL 68}}==
Line 680 ⟶ 1,147:
[[ALGOL 68G]] allows any precision for '''long long int''' to be defined
when the program is run, e.g. 200 digits.
<langsyntaxhighlight lang="algol68">PRAGMAT precision=200 PRAGMAT
MODE INTEGER = LONG LONG INT;
 
Line 700 ⟶ 1,167:
INTEGER neg two to the power of 64 = -(LONG 2 ** 64);
print(("2 ** 64 * -(2 ** 64) = ", whole(two to the power of 64*neg two to the power of 64,width), new line))
)</langsyntaxhighlight>
Output:
<pre>
Line 713 ⟶ 1,180:
{{works with|ALGOL 68G|Any - tested with release mk15-0.8b.fc9.i386}}
<!-- {{does not works with|ELLA ALGOL 68|Any (with appropriate job cards) - tested with release 1.8.8d.fc9.i386 - translator throws and assert. I'm not sure why.}} -->
<langsyntaxhighlight lang="algol68">MODE DIGIT = INT;
MODE INTEGER = FLEX[0]DIGIT; # an arbitary number of digits #
 
Line 805 ⟶ 1,272:
# finally return the semi-normalised result #
IF leading zeros = UPB out THEN "0" ELSE sign + out[leading zeros+1:] FI
);</langsyntaxhighlight>
 
<langsyntaxhighlight lang="algol68">################################################################
# Finally Define the required INTEGER multiplication OPerator. #
################################################################
Line 829 ⟶ 1,296:
OD;
NORMALISE ab
);</langsyntaxhighlight>
 
<langsyntaxhighlight lang="algol68"># The following standard operators could (potentially) also be defined #
OP - = (INTEGER a)INTEGER: raise integer not implemented error("monadic minus"),
ABS = (INTEGER a)INTEGER: raise integer not implemented error("ABS"),
Line 860 ⟶ 1,327:
INTEGER neg two to the power of 64 = INTEGERINIT(-(LONG 2 ** 64));
print(("2 ** 64 * -(2 ** 64) = ", REPR (two to the power of 64 * neg two to the power of 64), new line))
)</langsyntaxhighlight>
 
Output:
Line 874 ⟶ 1,341:
 
=={{header|ALGOL W}}==
<langsyntaxhighlight lang="algolw">begin
% long multiplication of large integers %
% large integers are represented by arrays of integers whose absolute %
Line 985 ⟶ 1,452:
writeonLargeInteger( twoTo128, ELEMENT_COUNT )
end
end.</langsyntaxhighlight>
{{out}}
<pre>
2^128: 340282366920938463463374607431768211456
</pre>
 
=={{header|APL}}==
{{works with|Dyalog APL}}
 
This function takes two digit vectors of arbitrary size.
<syntaxhighlight lang="apl">longmul←{⎕IO←0
sz←⌈/≢¨x y←↓⌽↑⌽¨⍺⍵
ds←+⌿↑(⌽⍳sz)⌽¨↓(¯2×sz)↑[1]x∘.×y
mlt←{(1⌽⌊⍵÷10)+10|⍵}⍣≡⊢ds
0=≢mlt←(∨\0≠mlt)/mlt:,0
mlt
}</syntaxhighlight>
 
{{out}}
 
<syntaxhighlight lang="apl"> ⎕←input←longmul⍣63⍨⊢,2 ⍝ construct 2*64
1 8 4 4 6 7 4 4 0 7 3 7 0 9 5 5 1 6 1 6
⎕←longmul⍨input ⍝ calculate 2*128
3 4 0 2 8 2 3 6 6 9 2 0 9 3 8 4 6 3 4 6 3 3 7 4 6 0 7 4 3 1 7 6 8 2 1 1 4 5 6</syntaxhighlight>
=={{header|ARM Assembly}}==
{{works with|as|Raspberry Pi <br> or android 32 bits with application Termux}}
<syntaxhighlight lang ARM Assembly>
/* ARM assembly Raspberry PI */
/* program longmulti.s */
 
/* REMARK 1 : this program use routines in a include file
see task Include a file language arm assembly
for the routine affichageMess conversion10
see at end of this program the instruction include */
/* REMARK 2 : this program use factors unsigned to 2 power 95
and the result is less than 2 power 159 */
/* for constantes see task include a file in arm assembly */
/************************************/
/* Constantes */
/************************************/
.include "../constantes.inc"
.equ BUFFERSIZE, 64
 
/***********************************************/
/* structures */
/**********************************************/
/* Définition multi128 */
.struct 0
multi128_N1: // 31-0
.struct multi128_N1 + 4
multi128_N2: // 63-32
.struct multi128_N2 + 4
multi128_N3: // 95-64
.struct multi128_N3 + 4
multi128_N4: // 127-96
.struct multi128_N4 + 4
multi128_N5: // 159-128
.struct multi128_N5 + 4
multi128_end:
/*********************************/
/* Initialized data */
/*********************************/
.data
szMessFactor: .asciz "Factor = "
szMessResult: .asciz "Result = "
szMessStart: .asciz "Program 32 bits start.\n"
szCarriageReturn: .asciz "\n"
 
i128test1: .int 0,0,1,0,0 // 2 power 64
/*********************************/
/* UnInitialized data */
/*********************************/
.bss
sZoneConv: .skip BUFFERSIZE // conversion buffer
i128Result1: .skip multi128_end
 
/*********************************/
/* code section */
/*********************************/
.text
.global main
main: @ entry of program
ldr r0,iAdrszMessStart
bl affichageMess
ldr r0,iAdri128test1 @ origin number
ldr r1,iAdrsZoneConv
mov r2,#BUFFERSIZE
bl convertMultiForString @ convert multi number to string
mov r2,r0 @ insert conversion in message
mov r0,#3 @ string number to display
ldr r1,iAdrszMessFactor
ldr r3,iAdrszCarriageReturn
bl displayStrings @ display message
@ multiplication
ldr r0,iAdri128test1 @ factor 1
ldr r1,iAdri128test1 @ factor 2
ldr r2,iAdri128Result1 @ result
bl multiplierMulti128
ldr r0,iAdri128Result1
ldr r1,iAdrsZoneConv
mov r2,#BUFFERSIZE
bl convertMultiForString @ conversion multi to string
mov r2,r0 @ insert conversion in message
mov r0,#3 @ number string to display
ldr r1,iAdrszMessResult
ldr r3,iAdrszCarriageReturn
bl displayStrings @ display message
100: @ standard end of the program
mov r0, #0 @ return code
mov r7, #EXIT @ request to exit program
svc #0 @ perform the system call
iAdrszCarriageReturn: .int szCarriageReturn
iAdrsZoneConv: .int sZoneConv
iAdri128test1: .int i128test1
iAdri128Result1: .int i128Result1
iAdrszMessResult: .int szMessResult
iAdrszMessFactor: .int szMessFactor
iAdrszMessStart: .int szMessStart
/***************************************************/
/* multiplication multi128 by multi128 */
/***************************************************/
// r0 contains address multi128 1
// r1 contains address multi128 2
// r2 contains address result multi128
// r0 return address result (= r2)
multiplierMulti128:
push {r1-r10,lr} @ save registers
mov r9,r0 @ factor 1
mov r10,r1 @ factor 2
mov r7,r2 @ address result
mov r6,#4 @ multi128 size
mov r5,#0
1:
str r5,[r7,r6,lsl #2] @ init result
subs r6,r6,#1
bge 1b
mov r5,#0 @ indice loop 1
2: @ loop items factor 1
ldr r0,[r9,r5,lsl #2] @ load a item
mov r4,#0
mov r8,#0
3: @ loop item factor 2
add r6,r4,r5 @ compute result indice
ldr r1,[r10,r4,lsl #2] @ oad a item factor 2
umull r2,r3,r1,r0 @ multiply long 32 bits
ldr r1,[r7,r6,lsl #2] @ load previous item of result
adds r1,r1,r2 @ add low part result multiplication
movcc r2,#0 @ high retain
movcs r2,#1
adds r1,r1,r8 @ add high part precedente
adc r8,r3,r2 @ new high part with retenue
str r1,[r7,r6,lsl #2] @ store the sum in result
add r4,r4,#1
cmp r4,#3
blt 3b @ and loop 2
cmp r8,#0 @ high part ?
beq 4f
add r6,r6,#1
cmp r6,#4 @ on last item ?
strle r8,[r7,r6,lsl #2] @ no store high part in next item
ble 4f
adr r0,szMessErrOverflow @ yes -> overflow
bl affichageMess
mov r0,#0 @ return 0
b 100f
4:
add r5,r5,#1
cmp r5,#3
blt 2b @ and loop 1
mov r0,r7
 
100:
pop {r1-r10,pc} @ restaur registers
szMessErrOverflow: .asciz "\033[31mOverflow !!\033[0m \n"
.align 4
/***************************************************/
/* display multi strings */
/***************************************************/
/* r0 contains number strings address */
/* r1 address string1 */
/* r2 address string2 */
/* r3 address string3 */
/* other address on the stack */
/* thinck to add number other address * 4 to add to the stack */
displayStrings: @ INFO: displayStrings
push {r1-r4,fp,lr} @ save des registres
add fp,sp,#24 @ save paraméters address (6 registers saved * 4 bytes)
mov r4,r0 @ save strings number
cmp r4,#0 @ 0 string -> end
ble 100f
mov r0,r1 @ string 1
bl affichageMess
cmp r4,#1 @ number > 1
ble 100f
mov r0,r2
bl affichageMess
cmp r4,#2
ble 100f
mov r0,r3
bl affichageMess
cmp r4,#3
ble 100f
mov r3,#3
sub r2,r4,#4
1: @ loop extract address string on stack
ldr r0,[fp,r2,lsl #2]
bl affichageMess
subs r2,#1
bge 1b
100:
pop {r1-r4,fp,pc}
/***************************************************/
/* conversion multi128 unsigned to string */
/***************************************************/
// r0 contains address multi128
// r1 contains address buffer
// r2 contains buffer length
convertMultiForString:
push {r1-r5,fp,lr} @ save des registres
sub sp,sp,#multi128_end @ reserve place to stack
mov fp,sp @ init address to quotient
mov r5,r1 @ save address buffer
mov r3,#0 @ init indice
1:
ldr r4,[r0,r3,lsl #2] @ load one part of number
str r4,[fp,r3,lsl #2] @ copy part on stack
add r3,#1
cmp r3,#5
blt 1b
2:
mov r0,#0
strb r0,[r5,r2] @ store final 0 in buffer
sub r4,r2,#1 @ end number storage
3:
mov r0,fp
mov r1,#10
bl calculerModuloMultiEntier @ compute modulo 10
add r0,r0,#0x30 @ convert result to character
strb r0,[r5,r4] @ store character on buffer
subs r4,r4,#1 @
blt 99f @ buffer too low
ldr r0,[fp,#multi128_N1] @ test if quotient = zero
cmp r0,#0
bne 3b
ldr r0,[fp,#multi128_N2]
cmp r0,#0
bne 3b
ldr r0,[fp,#multi128_N3]
cmp r0,#0
bne 3b
ldr r0,[fp,#multi128_N4]
cmp r0,#0
bne 3b
ldr r0,[fp,#multi128_N5]
cmp r0,#0
bne 3b
 
add r0,r5,r4 @ return begin number in buffer
add r0,r0,#1
b 100f
99: @ display error if buffer est toop low
adr r0,szMessErrBuffer
bl affichageMess
mov r0,#-1
100:
add sp,sp,#multi128_end @ stack alignement
pop {r1-r5,fp,pc} @ restaur registers
szMessErrBuffer: .asciz "\033[31mBuffer de conversion trop petit !!\033[0m \n"
.align 4
/***************************************************/
/* modulo compute unsigned */
/***************************************************/
// r0 contains address multi128
// r1 contains modulo (positive)
// r0 return modulo
// ATTENTION : le multientier origine est modifié et contient le quotient
calculerModuloMultiEntier: @ INFO: calculerModuloMultiEntier
push {r1-r5,lr} @ save des registres
cmp r1,#0
ble 99f
mov r4,r1 @ save modulo
mov r3,#4
mov r5,r0 @ multi128 address
ldr r0,[r5,r3,lsl #2] @ load last part of number in low part of 64 bits
mov r1,#0 @ init higt part 64 bits
1:
cmp r3,#0 @ end part ?
ble 2f
mov r2,r4 @ modulo
bl division32R @ divide r0,r1 by r2 in r0,r1 and remainder in r2
str r0,[r5,r3,lsl #2] @ store result part low
sub r3,r3,#1 @ other part ?
ldr r0,[r5,r3,lsl #2] @ load prev part
mov r1,r2 @ store remainder un high part of 64 bits
b 1b
2:
mov r2,r4 @ modulo
bl division32R
str r0,[r5] @ stockage dans le 1er chunk
mov r0,r2 @ return remainder
b 100f
99:
adr r0,szMessNegatif
bl affichageMess
mov r0,#-1
100: @ fin standard de la fonction
pop {r1-r5,pc} @ restaur des registres
szMessNegatif: .asciz "\033[31mLe diviseur doit être positif !\033[0m\n"
.align 4
/***************************************************/
/* division 64 bits number in 2 registers by 32 bits number */
/***************************************************/
/* r0 contains dividende low part */
/* r1 contains dividende high part */
/* r2 contains divisor */
/* r0 return quotient low part */
/* r1 return quotient high part */
/* r2 return remainder */
division32R:
push {r3-r7,lr} @ save registers
mov r6,#0 @ init high high part of remainder !!
@ r1 = high part of number in high part of remainder
mov r7,r0 @ low part of number in low part of remainder
mov r3,#0 @ init high part quotient
mov r4,#0 @ init low part quotient
mov r5,#32
1: @ begin loop
lsl r6,#1 @ left shift high high part of remainder
lsls r1,#1 @ left shift high part of remainder
orrcs r6,#1 @ add left bit high part on high high part
lsls r7,#1 @ left shift low part of remainder
orrcs r1,#1 @ add left bit low part on high part
lsls r4,#1 @ left shift low part quotient
lsl r3,#1 @ left shift high part quotient
orrcs r3,#1 @ add left bit low part on high part
@ sub divisor to high part remainder
subs r1,r2
sbcs r6,#0 @ sub restraint (retenue in french)
bmi 2f @ result negative ?
@ positive or equal
orr r4,#1 @ right bit quotient to 1
b 3f
2: @ negative
orr r4,#0 @ right bit quotient to 0
adds r1,r2 @ and restaure the remainder to precedent value
adc r6,#0 @ and restraint
3:
subs r5,#1 @ decrement indice
bgt 1b @ and loop
mov r0,r4 @ low part quotient
mov r2,r1 @ remainder
mov r1,r3 @ high part quotient
100: @
pop {r3-r7,pc} @ restaur registers
/***************************************************/
/* ROUTINES INCLUDE */
/***************************************************/
.include "../affichage.inc"
 
</syntaxhighlight>
{{Out}}
<pre>
Program 32 bits start.
Factor = 18446744073709551616
Result = 340282366920938463463374607431768211456
</pre>
 
=={{header|Arturo}}==
{{trans|ATS}}
 
The program is written to operate on strings containing digits and spaces.
 
<syntaxhighlight lang="arturo">
; The following two functions assume the 7-bit encoding is ASCII.
char2BCD: function [c] [
return (and (to :integer c) 15) % 10
]
BCD2char: function [i] [
return (to :char (or i 48))
]
 
multiplyBCD: function [u v] [
m: size u
n: size v
w: array.of: (m + n) `0`
 
predm: m - 1
predn: n - 1
predszw: (size w) - 1
 
; Long multiplication. See Algorithm 4.3.1M in Volume 2 of Knuth,
; ‘The Art of Computer Programming’. Here b = 10. Only the less
; significant nibble of a character is considered. Thus zero can be
; represented by either `0` or ` `, and other digits by their
; respective ASCII characters.
loop 0..predn 'j [
vj: char2BCD v\[predn - j]
if? vj = 0 [
set w (predn - j) `0`
] else [
carry: 0
loop 0..predm 'i [
ui: char2BCD u\[predm - i]
wij: char2BCD w\[predszw - (i + j)]
t: (ui * vj) + wij + carry
[carry digit]: divmod t 10
set w (predszw - (i + j)) (BCD2char digit)
]
set w (predn - j) (BCD2char carry)
]
]
 
return join w
]
 
twoRaised64: "18446744073709551616"
twoRaised128: multiplyBCD twoRaised64 twoRaised64
 
print twoRaised128
</syntaxhighlight>
 
{{out}}
 
<pre>0340282366920938463463374607431768211456</pre>
 
=={{header|ATS}}==
 
I perform both binary long multiplication (designed for efficiency) and decimal arithmetic.
 
The example numbers, though fine for testing decimal arithmetic, are ''very'' bad for testing binary multiplication. For example, they never require a carry. So I have added (for binary multiplication) the example 79 228 162 514 264 337 593 543 950 335 squared equals 6 277 101 735 386 680 763 835 789 423 049 210 091 073 826 769 276 946 612 225. The first number is 96 one-bits.
 
<syntaxhighlight lang="ats">
(* This is Algorithm 4.3.1M in Volume 2 of Knuth, ‘The Art of Computer
Programming’. *)
 
#include "share/atspre_staload.hats"
 
#define NIL list_nil ()
#define :: list_cons
 
(********************** FOR BINARY ARITHMETIC ***********************)
 
(* We need to choose a radix for the multiplication, small enough that
intermediate results can be represented, but big for efficiency. To
stay within the POSIX types, I choose 2**32 as my radix. Thus
‘digits’ are stored in uint32 and intermediate results are stored
in uint64.
 
A number is stored as an array of uint32, with the least
significant uint32 first. *)
 
extern fn
long_multiplication (* Multiply u and v, giving w. *)
{m, n : int}
(m : size_t m,
n : size_t n,
u : &array (uint32, m),
v : &array (uint32, n),
w : &array (uint32?, m + n) >> array (uint32, m + n))
:<!refwrt> void
 
%{^
#include <stdint.h>
%}
extern castfn i2u32 : int -<> uint32
extern castfn u32_2i : uint32 -<> int
extern castfn i2u64 : int -<> uint64
extern castfn u32u64 : uint32 -<> uint64
extern castfn u64u32 : uint64 -<> uint32
macdef zero32 = i2u32 0
macdef zero64 = i2u64 0
macdef one32 = i2u32 1
macdef ten32 = i2u32 10
macdef mask32 = $extval (uint32, "UINT32_C (0xFFFFFFFF)")
 
(* The following implementation is precisely the algorithm suggested
by Knuth, although specialized for b=2**32 and for unsigned
integers of precisely 32 bits. *)
implement
long_multiplication {m, n} (m, n, u, v, w) =
let
(* Establish that the arrays have non-negative lengths. *)
prval () = lemma_array_param u
prval () = lemma_array_param v
 
(* Knuth initializes only part of the w array. However, if we
initialize ALL of w now, then we will not have to deal with
complicated array views later. *)
val () = array_initize_elt<uint32> (w, m + n, zero32)
 
(* The following function includes proof of termination. *)
fun
jloop {j : nat | j <= n} .<n - j>.
(u : &array (uint32, m),
v : &array (uint32, n),
w : &array (uint32, m + n),
j : size_t j)
:<!refwrt> void =
if j = n then
()
else if v[j] = zero32 then (* This branch is optional. *)
begin
w[j + m] := zero32;
jloop (u, v, w, succ j)
end
else
let
fun
iloop {i : nat | i <= m} .<m - i>.
(u : &array (uint32, m),
v : &array (uint32, n),
w : &array (uint32, m + n),
i : size_t i,
k : uint64) (* carry *)
:<!refwrt> void =
if i = m then
w[j + m] := u64u32 k
else
let
val t = (u32u64 u[i] * u32u64 v[j])
+ u32u64 w[i + j] + k
in
(* The mask here is not actually needed, if uint32
really is treated by the C compiler as 32 bits. *)
w[i + j] := (u64u32 t) land mask32;
 
iloop (u, v, w, succ i, t >> 32)
end
in
iloop (u, v, w, i2sz 0, zero64);
jloop (u, v, w, succ j)
end
in
jloop (u, v, w, i2sz 0)
end
 
fn
big_integer_iseqz (* Is a big integer equal to zero? *)
{m : int}
(m : size_t m,
u : &array (uint32, m))
:<!ref> bool =
let
prval () = lemma_array_param u
fun
loop {n : nat | n <= m} .<n>.
(u : &array (uint32, m),
n : size_t n)
:<!ref> bool =
if n = i2sz 0 then
true
else if u[pred n] = zero32 then
loop (u, pred n)
else
false
in
loop (u, m)
end
 
(* To print the number in decimal, we need division by 10. So here is
‘short division’: Exercise 4.3.1.16 in Volume 2 of Knuth. *)
fn
short_division
{m : int}
(m : size_t m,
u : &array (uint32, m),
v : uint32,
q : &array (uint32?, m) >> array (uint32, m),
r : &uint32? >> uint32)
:<!refwrt> void =
let
prval () = lemma_array_param u
val () = array_initize_elt<uint32> (q, m, zero32)
val () = r := zero32
fun
loop {i1 : nat | i1 <= m} .<i1>.
(u : &array (uint32, m),
q : &array (uint32, m),
i1 : size_t i1,
r : &uint32)
:<!refwrt> void =
if i1 <> i2sz 0 then
let
val i = pred i1
val tmp = (u32u64 r << 32) lor (u32u64 u[i])
val tmp_q = tmp / u32u64 v and tmp_r = tmp mod (u32u64 v)
in
q[i] := u64u32 tmp_q;
r := u64u32 tmp_r;
loop (u, q, i, r)
end
in
loop (u, q, m, r)
end
 
fn
fprint_big_integer
{m : int}
(f : FILEref,
m : size_t m,
u : &array (uint32, m))
: void =
let
fun
loop1 (v : &array (uint32, m),
q : &array (uint32, m),
lst : List0 char,
i : uint)
: List0 char =
let
var r : uint32
val () = short_division (m, v, ten32, q, r)
val r = g1ofg0 (u32_2i r)
val () = assertloc ((0 <= r) * (r <= 9))
val digit = int2digit r
in
if big_integer_iseqz (m, q) then
digit :: lst
else if i = 2U then
(* Insert UTF-8 for narrow no-break space U+202F *)
loop1 (q, v, '\xE2' :: '\x80' :: '\xAF' :: digit :: lst, 0U)
else
loop1 (q, v, digit :: lst, succ i)
end
fun
loop2 {n : nat} .<n>.
(lst : list (char, n))
: void =
case+ lst of
| NIL => ()
| hd :: tl => (fprint! (f, hd); loop2 tl)
in
if big_integer_iseqz (m, u) then
fprint! (f, "0")
else
let
val @(pf, pfgc | p) = array_ptr_alloc<uint32> m
val @(qf, qfgc | q) = array_ptr_alloc<uint32> m
val () = array_copy<uint32> (!p, u, m)
val () = array_initize_elt<uint32> (!q, m, zero32)
val () = loop2 (loop1 (!p, !q, NIL, 0U))
val () = array_ptr_free (pf, pfgc | p)
val () = array_ptr_free (qf, qfgc | q)
in
end
end
 
fn
example_binary (f : FILEref) : void =
let
var u = @[uint32][3] (zero32, zero32, one32)
var v = @[uint32][3] (zero32, zero32, one32)
var w : @[uint32][6]
in
long_multiplication (i2sz 3, i2sz 3, u, v, w);
fprint! (f, "\nBinary long multiplication (b = 2³²)\n\n");
fprint! (f, "u = ");
fprint_big_integer (f, i2sz 3, u);
fprint! (f, "\nv = ");
fprint_big_integer (f, i2sz 3, v);
fprint! (f, "\nu × v = ");
fprint_big_integer (f, i2sz 6, w);
fprint! (f, "\n")
end
 
fn
test_binary (f : FILEref) : void =
let
var u = @[uint32][3] (mask32, mask32, mask32)
var v = @[uint32][3] (mask32, mask32, mask32)
var w : @[uint32][6]
in
long_multiplication (i2sz 3, i2sz 3, u, v, w);
fprint! (f, "\nThe example numbers specified in the task\n",
"are actually VERY bad for testing binary\n",
"multiplication, because they never need a carry.\n",
"So here is a multiplication full of carries,\n",
"with b = 2³²\n\n");
fprint! (f, "u = ");
fprint_big_integer (f, i2sz 3, u);
fprint! (f, "\nv = ");
fprint_big_integer (f, i2sz 3, v);
fprint! (f, "\nu × v = ");
fprint_big_integer (f, i2sz 6, w);
fprint! (f, "\n")
end
 
(************** FOR BINARY CODED DECIMAL ARITHMETIC *****************)
 
(* The following will operate on arrays of BCD digits, with the most
significant digit first. Only the least four bits of a byte will be
considered. This has at least two benefits: any ASCII digit is
treated as its BCD equivalent, and SPACE is treated as zero. *)
 
extern fn
bcd_multiplication (* Multiply u and v, giving w. *)
{m, n : int}
(m : size_t m,
n : size_t n,
u : &array (char, m),
v : &array (char, n),
w : &array (char?, m + n) >> array (char, m + n))
:<!refwrt> void
 
fn {}
char2bcd (c : char) :<> intBtwe (0, 9) =
let
val c = char2uchar1 (g1ofg0 c)
val i = g1uint_of_uchar1 c
val i = i mod 16U
val i = i mod 10U (* Guarantees the digit be BCD. *)
in
u2i i
end
 
extern castfn bcd2char (i : intBtwe (0, 9)) :<> char
 
(* The following implementation is precisely the algorithm suggested
by Knuth, specialized for b=10. *)
implement
bcd_multiplication {m, n} (m, n, u, v, w) =
let
(* Establish that the arrays have non-negative lengths. *)
prval () = lemma_array_param u
prval () = lemma_array_param v
 
(* Knuth initializes only part of the w array. However, if we
initialize ALL of w now, then we will not have to deal with
complicated array views later. *)
val () = array_initize_elt<char> (w, m + n, '\0')
 
(* The following function includes proof of termination. *)
fun
jloop {j : nat | j <= n} .<n - j>.
(u : &array (char, m),
v : &array (char, n),
w : &array (char, m + n),
j : size_t j)
:<!refwrt> void =
if j = n then
()
else if char2bcd v[pred n - j] = 0 then (* Optional branch. *)
begin
w[pred n - j] := '\0';
jloop (u, v, w, succ j)
end
else
let
fun
iloop {i : nat | i <= m} .<m - i>.
(u : &array (char, m),
v : &array (char, n),
w : &array (char, m + n),
i : size_t i,
k : intBtwe (0, 9)) (* carry *)
:<!refwrt> void =
if i = m then
w[pred n - j] := bcd2char k
else
let
val ui = char2bcd u[pred m - i]
and vj = char2bcd v[pred n - j]
and wij = char2bcd w[pred (m + n) - (i + j)]
 
val t = (ui * vj) + wij + k
 
(* This will prove that 0 <= t *)
prval [ui : int] EQINT () = eqint_make_gint ui
prval [vj : int] EQINT () = eqint_make_gint vj
prval [t : int] EQINT () = eqint_make_gint t
prval () = mul_gte_gte_gte {ui, vj} ()
prval () = prop_verify {0 <= t} ()
 
(* But I do not feel like proving that t / 10 <= 9. *)
val t_div_10 = t \ndiv 10 and t_mod_10 = t \nmod 10
val () = $effmask_exn assertloc (t_div_10 <= 9)
in
w[pred (m + n) - (i + j)] := bcd2char t_mod_10;
iloop (u, v, w, succ i, t_div_10)
end
in
iloop (u, v, w, i2sz 0, 0);
jloop (u, v, w, succ j)
end
in
jloop (u, v, w, i2sz 0)
end
 
fn
fprint_bcd {m : int}
(f : FILEref,
m : size_t m,
u : &array (char, m))
: void =
let
prval () = lemma_array_param u
 
fun
skip_zeros {i : nat | i <= m} .<m - i>.
(u : &array (char, m),
i : size_t i)
:<!ref> [i : nat | i <= m] size_t i =
if i = m then
i
else if char2bcd u[i] = 0 then
skip_zeros (u, succ i)
else
i
 
val [i : int] i = skip_zeros (u, i2sz 0)
 
fun
loop {j : int | i <= j; j <= m} .<m - j>.
(u : &array (char, m),
j : size_t j)
: void =
if j <> m then
begin
if j <> i && (m - j) mod (i2sz 3) = i2sz 0 then
(* Print UTF-8 for narrow no-break space U+202F *)
fprint! (f, "\xE2\x80\xAF");
fprint! (f, int2digit (char2bcd u[j]));
loop (u, succ j)
end
in
if i = m then
fprint! (f, "0")
else
loop (u, i)
end
 
fn
string2bcd {n : int}
(s : string n)
: [p : agz]
@(array_v (char, p, n), mfree_gc_v p | ptr p) =
let
val n = strlen s
val @(pf, pfgc | p) = array_ptr_alloc<char> n
implement
array_initize$init<char> (i, x) =
let
val i = g1ofg0 i
prval () = lemma_g1uint_param i
val () = assertloc (i < n)
in
x := s[i]
end
val () = array_initize<char> (!p, n)
in
@(pf, pfgc | p)
end
 
fn
example_bcd (f : FILEref) : void =
let
val s = g1ofg0 "18446744073709551616"
 
val m = strlen s
 
val @(pf_u, pfgc_u | p_u) = string2bcd s
val @(pf_v, pfgc_v | p_v) = string2bcd s
val @(pf_w, pfgc_w | p_w) = array_ptr_alloc<char> (m + m)
macdef u = !p_u
macdef v = !p_v
macdef w = !p_w
in
bcd_multiplication (m, m, u, v, w);
fprint! (f, "\nDecimal long multiplication (b = 10)\n\n");
fprint! (f, "u = ");
fprint_bcd (f, m, u);
fprint! (f, "\nv = ");
fprint_bcd (f, m, v);
fprint! (f, "\nu × v = ");
fprint_bcd (f, m + m, w);
fprint! (f, "\n");
array_ptr_free (pf_u, pfgc_u | p_u);
array_ptr_free (pf_v, pfgc_v | p_v);
array_ptr_free (pf_w, pfgc_w | p_w)
end
 
(********************************************************************)
 
implement
main () =
begin
example_binary (stdout_ref);
println! ();
example_bcd (stdout_ref);
println! ();
test_binary (stdout_ref);
println! ();
0
end
</syntaxhighlight>
 
{{out}}
<pre>$ patscc -std=gnu2x -g -O2 -DATS_MEMALLOC_LIBC long_mult_task.dats && ./a.out
 
Binary long multiplication (b = 2³²)
 
u = 18 446 744 073 709 551 616
v = 18 446 744 073 709 551 616
u × v = 340 282 366 920 938 463 463 374 607 431 768 211 456
 
 
Decimal long multiplication (b = 10)
 
u = 18 446 744 073 709 551 616
v = 18 446 744 073 709 551 616
u × v = 340 282 366 920 938 463 463 374 607 431 768 211 456
 
 
The example numbers specified in the task
are actually VERY bad for testing binary
multiplication, because they never need a carry.
So here is a multiplication full of carries,
with b = 2³²
 
u = 79 228 162 514 264 337 593 543 950 335
v = 79 228 162 514 264 337 593 543 950 335
u × v = 6 277 101 735 386 680 763 835 789 423 049 210 091 073 826 769 276 946 612 225
</pre>
 
=={{header|AutoHotkey}}==
ahk [http://www.autohotkey.com/forum/viewtopic.php?t=44657&postdays=0&postorder=asc&start=149 discussion]
<langsyntaxhighlight lang="autohotkey">MsgBox % x := mul(256,256)
MsgBox % x := mul(x,x)
MsgBox % x := mul(x,x) ; 18446744073709551616
Line 1,011 ⟶ 2,405:
}
Return cy ? a : SubStr(a,2)
}</langsyntaxhighlight>
 
=={{header|AWK}}==
Line 1,017 ⟶ 2,411:
{{works with|nawk|20100523}}
{{trans|Tcl}}
<langsyntaxhighlight lang="awk">BEGIN {
DEBUG = 0
n = 2^64
Line 1,104 ⟶ 2,498:
print "===="
}
}</langsyntaxhighlight>
outputs:
<pre>2^64 * 2^64 = 340282366920938463463374607431768211456
Line 1,113 ⟶ 2,507:
 
===Version 1===
<langsyntaxhighlight lang="qbasic">'PROGRAM : BIG MULTIPLICATION VER #1
'LRCVS 01.01.2010
'THIS PROGRAM SIMPLY MAKES A MULTIPLICATION
Line 1,259 ⟶ 2,653:
CLS
PRINT "THE SOLUTION IN THE FILE: R"
END SUB</langsyntaxhighlight>
 
===Version 2===
<!-- I'm not sure what the difference is; don't feel like reading through them, I was just making sure they work and bughunting. -->
<langsyntaxhighlight lang="qbasic">'PROGRAM: BIG MULTIPLICATION VER # 2
'LRCVS 01/01/2010
'THIS PROGRAM SIMPLY MAKES A BIG MULTIPLICATION
Line 1,369 ⟶ 2,763:
NEXT N
PRINT "END"
PRINT "THE SOLUTION IN THE FILE: R.MLT"</langsyntaxhighlight>
 
==={{header|Applesoft BASIC}}===
<langsyntaxhighlight ApplesoftBasiclang="applesoftbasic"> 100 A$ = "18446744073709551616"
110 B$ = A$
120 GOSUB 400
Line 1,404 ⟶ 2,798:
680 NEXT J
700 IF E THEN V = VAL ( MID$ (D$,E,1)) + C:C = V > 9:V = V - 10 * C:E$ = STR$ (V) + E$:E = E - 1: GOTO 700
720 RETURN</langsyntaxhighlight>
 
=={{header|BASIC256}}==
{{trans|Liberty BASIC}}
<syntaxhighlight lang="freebasic">print "2^64"
a$ = "1"
for i = 1 to 64
a$ = multByD$(a$, 2)
next
print a$
print "(check with native BASIC-256)"
print 2^64
print "(looks OK)"
 
#now let's do b$*a$ stuff
print
print "2^64*2^64"
print longMult$(a$, a$)
print "(check with native BASIC-256)"
print 2^64*2^64
print "(looks OK)"
end
 
function max(a, b)
if a > b then
return a
else
return b
end if
end function
 
function longMult$(a$, b$)
signA = 1
if left(a$,1) = "-" then
a$ = mid(a$,2,1)
signA = -1
end if
signB = 1
if left(b$,1) = "-" then
b$ = mid(b$,2,1)
signB = -1
end if
 
c$ = ""
t$ = ""
shift$ = ""
for i = length(a$) to 1 step -1
d = fromradix((mid(a$,i,1)),10)
t$ = multByD$(b$, d)
c$ = addLong$(c$, t$+shift$)
shift$ += "0"
next
if signA * signB < 0 then c$ = "-" + c$
return c$
end function
 
function multByD$(a$, d)
#multiply a$ by digit d
c$ = ""
carry = 0
for i = length(a$) to 1 step -1
a = fromradix((mid(a$,i,1)),10)
c = a * d + carry
carry = int(c/10)
c = c mod 10
c$ = string(c) + c$
next
if carry > 0 then c$ = string(carry) + c$
return c$
end function
 
function addLong$(a$, b$)
#add a$ + b$, for now only positive
l = max(length(a$), length(b$))
a$ = pad$(a$,l)
b$ = pad$(b$,l)
c$ = "" #result
carry = 0
for i = l to 1 step -1
a = fromradix((mid(a$,i,1)),10)
b = fromradix((mid(b$,i,1)),10)
c = a + b + carry
carry = int(c/10)
c = c mod 10
c$ = string(c) + c$
next
if carry > 0 then c$ = string(carry) + c$
return c$
end function
 
function pad$(a$,n) #pad$ from right with 0 to length n
pad$ = a$
while length(pad$) < n
pad$ = "0" + pad$
end while
end function
</syntaxhighlight>
{{out}}
<pre>2^64
18446744073709551616
(check with native BASIC-256)
1.84467440737e+19
(looks OK)
 
2^64*2^64
340282366920938463463374607431768211456
(check with native BASIC-256)
3.40282366921e+38
(looks OK)</pre>
 
=={{header|Batch File}}==
Based on the JavaScript iterative code.
<langsyntaxhighlight lang="dos">::Long Multiplication Task from Rosetta Code
::Batch File Implementation
 
Line 1,465 ⟶ 2,967:
for /l %%F in (0,1,%length%) do set "prod=!digit%%F!!prod!"
endlocal & set "%3=%prod%"
goto :eof</langsyntaxhighlight>
{{Out}}
<pre>340282366920938463463374607431768211456</pre>
Line 1,472 ⟶ 2,974:
{{works with|BBC BASIC for Windows}}
Library method:
<langsyntaxhighlight lang="bbcbasic"> INSTALL @lib$+"BB4WMAPMLIB"
MAPM_DllPath$ = @lib$+"BB4WMAPM.DLL"
PROCMAPM_Init
twoto64$ = "18446744073709551616"
PRINT "2^64 * 2^64 = " ; FNMAPM_Multiply(twoto64$, twoto64$)</langsyntaxhighlight>
Explicit method:
<langsyntaxhighlight lang="bbcbasic"> twoto64$ = "18446744073709551616"
PRINT "2^64 * 2^64 = " ; FNlongmult(twoto64$, twoto64$)
END
Line 1,506 ⟶ 3,008:
num3&(S%) = 0
IF num3&(0) = &30 THEN = $$^num3&(1)
= $$^num3&(0)</langsyntaxhighlight>
 
=={{header|C}}==
Doing it as if by hand.
<langsyntaxhighlight lang="c">#include <stdio.h>
#include <string.h>
 
Line 1,564 ⟶ 3,066:
 
return 0;
}</langsyntaxhighlight>output<syntaxhighlight lang="text">340282366920938463463374607431768211456</langsyntaxhighlight>
 
=={{header|C sharp|C#}}==
{{works with|C sharp|C#|4+}}If you strip out the ''BigInteger'' checking, it will work with lesser versions.<br/><br/>This uses the '''decimal''' type, (which has a '''MaxValue''' of 79,228,162,514,264,337,593,543,950,335). By limiting it to '''10^28''', it allows 28 decimal digits for the ''hi'' part, and 28 decimal digits for the ''lo'' part, '''56 decimal digits''' total. A side computation of ''BigInteger'' assures that the results are accurate.
<langsyntaxhighlight lang="csharp">using System;
using static System.Console;
using BI = System.Numerics.BigInteger;
Line 1,607 ⟶ 3,109:
BS.ToString() == toStr(y) ? "does" : "fails to"); } }
 
}</langsyntaxhighlight>
{{out}}
<pre>The square of (2^64): 18,446,744,073,709,551,616
Line 1,617 ⟶ 3,119:
=={{header|C++}}==
===Version 1===
<langsyntaxhighlight lang="cpp">
#include <iostream>
#include <sstream>
Line 1,698 ⟶ 3,200:
}
//--------------------------------------------------------------------------------------------------
</syntaxhighlight>
</lang>
{{out}}
<pre>340282366920938463463374607431768211456
Line 1,709 ⟶ 3,211:
 
===Version 2===
<langsyntaxhighlight lang="cpp">
#include <iostream>
#include <vector>
Line 1,776 ⟶ 3,278:
}
return 0;
}</langsyntaxhighlight>
 
<pre>
Line 1,789 ⟶ 3,291:
 
=={{header|Ceylon}}==
<langsyntaxhighlight Ceylonlang="ceylon">"run() is the main function of this module."
 
shared void run() {
Line 1,846 ⟶ 3,348:
print("The actual result is ``result``");
print("Do they match? ``expectedResult == result then "Yes!" else "No!"``");
}</langsyntaxhighlight>
 
=={{header|COBOL}}==
<syntaxhighlight lang="cobol">
<lang COBOL>
identification division.
program-id. long-mul.
Line 1,938 ⟶ 3,440:
 
end program long-mul.
</syntaxhighlight>
</lang>
 
<pre>
Line 1,947 ⟶ 3,449:
 
=={{header|CoffeeScript}}==
<langsyntaxhighlight lang="coffeescript">
# This very limited BCD-based collection of functions
# allows for long multiplication. It works for positive
Line 2,012 ⟶ 3,514:
square = BcdInteger.product x, x
console.log BcdInteger.to_string square # 340282366920938463463374607431768211456
</syntaxhighlight>
</lang>
 
=={{header|Common Lisp}}==
<langsyntaxhighlight lang="lisp">(defun number->digits (number)
(do ((digits '())) ((zerop number) digits)
(multiple-value-bind (quotient remainder) (floor number 10)
Line 2,054 ⟶ 3,556:
(let* ((bi (pop b))
(row (mapcar #'(lambda (ai) (* ai bi)) a)))
(push (append prefix row) rows)))))</langsyntaxhighlight>
 
> (long-multiply (expt 2 64) (expt 2 64))
Line 2,061 ⟶ 3,563:
=={{header|Crystal}}==
 
<langsyntaxhighlight lang="ruby">require "big"
 
a = 2.to_big_i ** 64
 
puts "#{a} * #{a} = #{a*a}"
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 2,073 ⟶ 3,575:
=={{header|D}}==
Using the standard library:
<langsyntaxhighlight lang="d">void main() {
import std.stdio, std.bigint;
 
writeln(2.BigInt ^^ 64 * 2.BigInt ^^ 64);
}</langsyntaxhighlight>
{{out}}
<pre>340282366920938463463374607431768211456</pre>
Long multiplication, same output:
{{trans|JavaScript}}
<langsyntaxhighlight lang="d">import std.stdio, std.algorithm, std.range, std.ascii, std.string;
 
auto longMult(in string x1, in string x2) pure nothrow @safe {
Line 2,112 ⟶ 3,614:
immutable two64 = "18446744073709551616";
longMult(two64, two64).writeln;
}</langsyntaxhighlight>
 
=={{header|Dc}}==
{{incorrect|Dc|Code does not explicitly implement long multiplication}}
Since Dc has arbitrary precision built-in, the task is no different than a normal multiplication:
<langsyntaxhighlight Dclang="dc">2 64^ 2 64^ *p</langsyntaxhighlight>
{{incorrect|Dc|A Dc solution might be: Represent bignums as numerical strings and implement arithmetic functions on them.}}
=={{header|Delphi}}==
{{libheader| System.SysUtils}}
{{Trans|Go}}
Copy of core Go answer.
<syntaxhighlight lang="delphi">
program Long_multiplication;
 
{$APPTYPE CONSOLE}
 
uses
System.SysUtils;
 
type
TLongMul = record
private
function Add(x, y: TArray<byte>): TArray<byte>;
function ByteToString(b: TArray<byte>): Ansistring;
function d(b: byte): Byte;
function mulDigit(x: TArray<byte>; y: byte): TArray<byte>;
function mul(x1, y1: AnsiString): AnsiString;
public
value: string;
class operator Multiply(a, b: TLongMul): TLongMul;
class operator Implicit(a: TLongMul): string;
class operator Implicit(a: string): TLongMul;
end;
 
function TLongMul.d(b: byte): Byte;
begin
if (b < ord('0')) or (b > ord('9')) then
raise Exception.Create('digit 0-9 expected: ' + ord(b).ToString);
Result := ord(b) - ord('0');
end;
 
class operator TLongMul.Implicit(a: string): TLongMul;
begin
Result.value := a;
end;
 
class operator TLongMul.Implicit(a: TLongMul): string;
begin
Result := a.value;
end;
 
function TLongMul.Add(x, y: TArray<byte>): TArray<byte>;
begin
if length(x) < Length(y) then
begin
var tmp := y;
y := x;
x := tmp;
end;
 
var b: TArray<byte>;
SetLength(b, length(x) + 1);
var c: byte := 0;
for var i := 1 to Length(x) do
begin
if i <= Length(y) then
c := c + d(y[Length(y) - i]);
var s := d(x[Length(x) - i]) + c;
c := s div 10;
b[length(b) - i] := (s mod 10) + ord('0');
end;
if c = 0 then
begin
Result := b;
Delete(Result, 0, 1);
exit;
end;
 
b[0] := c + ord('0');
Result := b;
end;
 
function TLongMul.mulDigit(x: TArray<byte>; y: byte): TArray<byte>;
begin
if y = ord('0') then
begin
SetLength(result, 1);
Result[0] := y;
exit
end;
 
y := d(y);
var b: TArray<byte>;
SetLength(b, length(x) + 1);
var c: byte := 0;
for var i := 1 to Length(x) do
begin
var s := d(x[Length(x) - i]) * y + c;
c := s div 10;
b[length(b) - i] := (s mod 10) + ord('0');
end;
 
if c = 0 then
begin
Result := b;
Delete(Result, 0, 1);
exit;
end;
 
b[0] := c + ord('0');
Result := b;
end;
 
class operator TLongMul.Multiply(a, b: TLongMul): TLongMul;
begin
Result.value := a.mul(a, b);
end;
 
function TLongMul.ByteToString(b: TArray<byte>): Ansistring;
begin
SetLength(Result, length(b));
move(b[0], Result[1], length(b));
end;
 
function TLongMul.mul(x1, y1: AnsiString): AnsiString;
var
x, y: TArray<byte>;
res: TArray<byte>;
begin
SetLength(x, length(x1));
move(x1[1], x[0], length(x1));
 
SetLength(y, length(y1));
move(y1[1], y[0], length(y1));
 
res := mulDigit(x, y[length(y) - 1]);
 
var zeros: TArray<byte> := [];
 
for var i := 2 to Length(y) do
begin
SetLength(zeros, Length(zeros) + 1);
zeros[High(zeros)] := ord('0');
 
res := add(res, Concat(mulDigit(x, y[Length(y) - i]), zeros));
end;
 
Result := ByteToString(res);
end;
 
const
validate = '340282366920938463463374607431768211456';
 
var
num: TLongMul;
 
begin
num.value := '18446744073709551616';
 
Writeln((num * num).value);
Writeln(validate);
Readln;
end.</syntaxhighlight>
{{out}}
<pre>340282366920938463463374607431768211456
340282366920938463463374607431768211456</pre>
 
=={{header|EasyLang}}==
<syntaxhighlight lang="easylang">
func$ mult a$ b$ .
a[] = number strchars a$
b[] = number strchars b$
len r[] len a[] + len b[]
for ib = len b[] downto 1
h = 0
for ia = len a[] downto 1
h += r[ia + ib] + b[ib] * a[ia]
r[ia + ib] = h mod 10
h = h div 10
.
r[ib] += h
.
r$ = ""
for i = 1 to len r[]
if r$ <> "" or r[i] <> 0 or i = len r[]
r$ &= r[i]
.
.
return r$
.
print mult "18446744073709551616" "18446744073709551616"
</syntaxhighlight>
 
=={{header|EchoLisp}}==
We implement long multiplication by multiplying polynomials, knowing that the number 1234 is the polynomial x^3 +2x^2 +3x +4 at x=10. As we assume no bigint library is present, long-mul operates on strings.
<langsyntaxhighlight lang="lisp">
(lib 'math) ;; for poly multiplication
 
Line 2,164 ⟶ 3,851:
 
 
</syntaxhighlight>
</lang>
 
=={{header|Euphoria}}==
<langsyntaxhighlight lang="euphoria">constant base = 1000000000
 
function atom_to_long(atom a)
Line 2,224 ⟶ 3,911:
 
c = long_mult(b,b)
printf(1,"a*a*a*a is %s\n",{long_to_str(c)})</langsyntaxhighlight>
 
Output:
Line 2,235 ⟶ 3,922:
{{incorrect|F#|The problem is to implement long multiplication, not to demonstrate bignum support.}}
 
<langsyntaxhighlight Flang="f#">> let X = 2I ** 64 * 2I ** 64 ;;
 
val X : System.Numerics.BigInteger = 340282366920938463463374607431768211456
</syntaxhighlight>
</lang>
 
=={{header|Factor}}==
<langsyntaxhighlight lang="factor">USING: kernel math sequences ;
 
: longmult-seq ( xs ys -- zs )
Line 2,252 ⟶ 3,939:
: digits->integer ( xs -- x ) 0 [ swap 10 * + ] reduce ;
 
: longmult ( x y -- z ) [ integer->digits ] bi@ longmult-seq digits->integer ;</langsyntaxhighlight>
<langsyntaxhighlight lang="factor">( scratchpad ) 2 64 ^ dup longmult .
340282366920938463463374607431768211456
( scratchpad ) 2 64 ^ dup * .
340282366920938463463374607431768211456</langsyntaxhighlight>
 
=={{header|Fortran}}==
{{works with|Fortran|95 and later}}
<langsyntaxhighlight lang="fortran">module LongMoltiplication
implicit none
 
Line 2,334 ⟶ 4,021:
end subroutine longmolt_print
 
end module LongMoltiplication</langsyntaxhighlight>
 
<langsyntaxhighlight lang="fortran">program Test
use LongMoltiplication
 
Line 2,348 ⟶ 4,035:
write(*,*)
 
end program Test</langsyntaxhighlight>
 
=={{header|FreeBASIC}}==
<langsyntaxhighlight lang="freebasic">' version 08-01-2017
' compile with: fbc -s console
 
Line 2,445 ⟶ 4,132:
Print : Print "hit any key to end program"
Sleep
End</langsyntaxhighlight>
{{out}}
<pre>2 ^ 2 = 4
Line 2,460 ⟶ 4,147:
 
=={{header|Go}}==
<langsyntaxhighlight lang="go">// 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
Line 2,538 ⟶ 4,225:
func main() {
fmt.Println(mul(n, n))
}</langsyntaxhighlight>
Output:
<pre>
Line 2,545 ⟶ 4,232:
 
=={{header|Haskell}}==
<langsyntaxhighlight lang="haskell">import Data.List (transpose, inits)
import Data.Char (digitToInt)
 
Line 2,564 ⟶ 4,251:
 
main :: IO ()
main = print $ (2 ^ 64) `longmult` (2 ^ 64)</langsyntaxhighlight>
{{out}}
<pre>340282366920938463463374607431768211456</pre>
 
=={{header|Icon}} and {{header|Unicon}}==
{{Incorrect|Icon|Task is "Implement long multiplication" not "Multiply two numbers using native operators"}}
Large integers are native to Icon and Unicon. Neither libraries nor special programming is required.
<langsyntaxhighlight Iconlang="icon">procedure main()
write(2^64*2^64)
end</langsyntaxhighlight>
{{output}}<pre>340282366920938463463374607431768211456</pre>
 
=={{header|J}}==
'''Solution:'''
<langsyntaxhighlight lang="j"> digits =: ,.&.":
polymult =: +//.@(*/)
buildDecimal=: 10x&#.
 
longmult=: buildDecimal@polymult&digits</langsyntaxhighlight>
'''Example:'''
<langsyntaxhighlight lang="j"> longmult~ 2x^64
340282366920938463463374607431768211456</langsyntaxhighlight>
 
'''Alternatives:'''<br>
<code>longmult</code> could have been defined concisely:
<langsyntaxhighlight lang="j">longmult=: 10x&#.@(+//.@(*/)&(,.&.":))</langsyntaxhighlight>
Or, of course, the task may be accomplished without the verb definitions:
<langsyntaxhighlight lang="j"> 10x&#.@(+//.@(*/)&(,.&.":))~2x^64
340282366920938463463374607431768211456</langsyntaxhighlight>
Or using the code <code>(+ 10x&*)/@|.</code> instead of <code>#.</code>:
<langsyntaxhighlight lang="j"> (+ 10x&*)/@|.@(+//.@(*/)&(,.&.":))~2x^64
340282366920938463463374607431768211456</langsyntaxhighlight>
Or you could use the built-in language support for arbitrary precision multiplication:
<langsyntaxhighlight lang="j"> (2x^64)*(2x^64)
340282366920938463463374607431768211456</langsyntaxhighlight>
 
'''Explaining the component verbs:'''
* <code>digits</code> translates a number to a corresponding list of digits;
<langsyntaxhighlight lang="j"> ,.&.": 123
1 2 3</langsyntaxhighlight>
* <code>polymult</code> (multiplies polynomials): '''ref.''' [http://www.jsoftware.com/help/dictionary/samp23.htm]
<langsyntaxhighlight lang="j"> 1 2 3 (+//.@(*/)) 1 2 3
1 4 10 12 9</langsyntaxhighlight>
* <code>buildDecimal</code> (translates a list of decimal digits - possibly including "carry" - to the corresponding extended precision number):
<langsyntaxhighlight lang="j"> (+ 10x&*)/|. 1 4 10 12 9
15129</langsyntaxhighlight>
or
<syntaxhighlight lang="j"> 10 #. 1 4 10 12 9
15129</syntaxhighlight>
 
=={{header|Java}}==
Line 2,616 ⟶ 4,307:
This version of the code keeps the data in base ten. By doing this, we can avoid converting the whole number to binary and we can keep things simple, but the runtime will be suboptimal.
 
<langsyntaxhighlight lang="java">public class LongMult {
 
private static byte[] stringToDigits(String num) {
Line 2,667 ⟶ 4,358:
}
}
</syntaxhighlight>
</lang>
 
===Binary version===
Line 2,673 ⟶ 4,364:
This version tries to be as efficient as possible, so it converts numbers into binary before doing any calculations. The complexity is higher because of the need to convert to and from base ten, which requires the implementation of some additional arithmetic operations beyond long multiplication itself.
 
<langsyntaxhighlight lang="java">import java.util.Arrays;
 
public class LongMultBinary {
Line 2,878 ⟶ 4,569:
 
}
</syntaxhighlight>
</lang>
 
=={{header|JavaScript}}==
Line 2,892 ⟶ 4,583:
This means that to handle larger inputs, the multiplication function needs to have string parameters:
 
<langsyntaxhighlight lang="javascript">function mult(strNum1,strNum2){
 
var a1 = strNum1.split("").reverse();
Line 2,913 ⟶ 4,604:
 
 
mult('18446744073709551616', '18446744073709551616')</langsyntaxhighlight>
 
{{Out}}
Line 2,924 ⟶ 4,615:
For the same reason, the output always takes the form of an arbitrary precision integer string, rather than a native integer data type. (See the '''largeIntegerString()''' helper function below)
 
<langsyntaxhighlight JavaScriptlang="javascript">(function () {
'use strict';
 
Line 3,013 ⟶ 4,704:
)
};
})();</langsyntaxhighlight>
{{Out}}
<pre>{"fromIntegerStrings":"340282366920938463463374607431768211456",
Line 3,021 ⟶ 4,712:
{{Works with|jq|1.4}}
Since the task description mentions 2^64, the following includes "long_power(i)" for computing n^i.
<langsyntaxhighlight lang="jq"># multiply two decimal strings, which may be signed (+ or -)
def long_multiply(num1; num2):
 
Line 3,066 ⟶ 4,757:
elif $a2[1] == "1" then $a1[1]|adjustsign( $a1[0] * $a2[0] )
else mult($a1[1]; $a2[1]) | adjustsign( $a1[0] * $a2[0] )
end;</langsyntaxhighlight>
<langsyntaxhighlight lang="jq"># Emit (input)^i where input and i are non-negative decimal integers,
# represented as numbers and/or strings.
def long_power(i):
Line 3,084 ⟶ 4,775:
| ($i - $j*$j) as $k
| long_multiply( power($j) | power($j) ; power($k) )
end ;</langsyntaxhighlight>
'''Example''':
<langsyntaxhighlight lang="jq"> 2 | long_power(64) | long_multiply(.;.)</langsyntaxhighlight>
{{Out}}
$ jq -n -f Long_multiplication.jq
Line 3,096 ⟶ 4,787:
 
'''Module''':
<langsyntaxhighlight lang="julia">module LongMultiplication
 
using Compat
Line 3,140 ⟶ 4,831:
end
 
end # module LongMultiplication</langsyntaxhighlight>
 
'''Main''':
<langsyntaxhighlight lang="julia">@show LongMultiplication.longmult(big(2) ^ 64, big(2) ^ 64)
@show LongMultiplication.longmult("18446744073709551616", "18446744073709551616")</langsyntaxhighlight>
 
{{out}}
Line 3,152 ⟶ 4,843:
=={{header|Kotlin}}==
{{trans|Java}}
<langsyntaxhighlight lang="scala">fun String.toDigits() = mapIndexed { i, c ->
if (!c.isDigit())
throw IllegalArgumentException("Invalid digit $c found at position $i")
Line 3,187 ⟶ 4,878:
fun main(args: Array<out String>) {
println("18446744073709551616" * "18446744073709551616")
}</langsyntaxhighlight>
 
=={{header|Lambdatalk}}==
 
<langsyntaxhighlight lang="scheme">
Natural positive numbers are defined as strings, for instance 123 -> "123".
{lambda talk} has a small set of primitives working on strings, [equal?, empty?, chars, charAt, substring]
Line 3,269 ⟶ 4,960:
 
This can be tested in http://lambdaway.free.fr/lambdaspeech/?view=numbers8
</syntaxhighlight>
</lang>
 
=={{header|Liberty BASIC}}==
{{works with|Just BASIC}}
 
{{works with|Run BASIC}}
<lang lb>
<syntaxhighlight lang="lb">
'[RC] long multiplication
 
Line 3,364 ⟶ 5,056:
 
</syntaxhighlight>
</lang>
 
=={{header|Lobster}}==
{{trans|Java}} Translation of Java binary version, but with base 1000000000
<langsyntaxhighlight Lobsterlang="lobster">import std
 
// Very basic arbitrary-precision integers
Line 3,481 ⟶ 5,173:
var pro = one.bign_multiply(two)
print(bign2str(pro))
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 3,488 ⟶ 5,180:
 
=={{header|Maple}}==
<syntaxhighlight lang="maple">
<lang Maple>
longmult := proc(a::integer,b::integer)
local A,B,m,n,i,j;
Line 3,501 ⟶ 5,193:
> longmult( 2^64, 2^64 );
340282366920938463463374607431768211456
</syntaxhighlight>
</lang>
 
=={{header|Mathematica}}/{{header|Wolfram Language}}==
We define the long multiplication function:
<langsyntaxhighlight Mathematicalang="mathematica"> LongMultiplication[a_,b_]:=Module[{d1,d2},
d1=IntegerDigits[a]//Reverse;
d2=IntegerDigits[b]//Reverse;
Sum[d1[[i]]d2[[j]]*10^(i+j-2),{i,1,Length[d1]},{j,1,Length[d2]}]
]</langsyntaxhighlight>
 
Example:
<langsyntaxhighlight Mathematicalang="mathematica"> n1 = 2^64;
n2 = 2^64;
LongMultiplication[n1, n2]</langsyntaxhighlight>
 
gives back:
<syntaxhighlight lang Mathematica="mathematica"> 340282366920938463463374607431768211456</langsyntaxhighlight>
 
To check the speed difference between built-in multiplication (which is already arbitrary precision) we multiply two big numbers (2^8000 has '''2409''' digits!) and divide their timings:
<langsyntaxhighlight Mathematicalang="mathematica"> n1=2^8000;
n2=2^8000;
Timing[LongMultiplication[n1,n2]][[1]]
Timing[n1 n2][[1]]
Floor[%%/%]</langsyntaxhighlight>
 
gives back:
<langsyntaxhighlight Mathematicalang="mathematica"> 72.9686
7.*10^-6
10424088</langsyntaxhighlight>
 
So our custom function takes about 73 second, the built-in function a couple of millionths of a second, so the long multiplication is about 10.5 million times slower! Mathematica uses Karatsuba multiplication for large integers, which is several magnitudes faster for really big numbers. Making it able to multiply <math>3^{(10^7)}\times3^{(10^7)}</math> in about a second; the final result has 9542426 digits; result omitted for obvious reasons.
Line 3,536 ⟶ 5,228:
{{trans|REXX}}
A reworking of the example at Rexx Version 2.
<langsyntaxhighlight NetRexxlang="netrexx">/* NetRexx */
options replace format comments java crossref symbols nobinary
 
Line 3,617 ⟶ 5,309:
 
return
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 3,647 ⟶ 5,339:
 
{{trans|C}}
<langsyntaxhighlight lang="nim">import strutils
 
proc ti(a: char): int = ord(a) - ord('0')
 
proc longmulti(a, b: string): string =
var
i, j, n, carry, la, lb = 0
k = false
 
Line 3,672 ⟶ 5,364:
return
 
result = repeatCharrepeat('0', a.len + b.len, '0')
 
for i in countdown(a.high, 0):
Line 3,687 ⟶ 5,379:
result[0..result.high-1] = result[1..result.high]
 
echo longmulti("-18446744073709551616", "-18446744073709551616")</langsyntaxhighlight>
Output:
<pre>3402823669209384634633746074317682114566</pre>
Line 3,709 ⟶ 5,401:
Just multiplication is implemented here.
 
<langsyntaxhighlight Oforthlang="oforth">Number Class new: Natural(v)
Natural method: initialize := v ;
Line 3,736 ⟶ 5,428:
| i |
@v last <<
@v size 1 - loop: i [ @v at(@v size i -) <<wjp(0, JUSTIFY_RIGHT, 8) ] ;</langsyntaxhighlight>
 
{{out}}
Line 3,760 ⟶ 5,452:
Ol already supports long numbers "out-of-the-box".
 
<langsyntaxhighlight lang="scheme">
(define x (* 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2)) ; 2^64
 
(print (* x x))
</syntaxhighlight>
</lang>
<pre>
340282366920938463463374607431768211456
Line 3,770 ⟶ 5,462:
 
=={{header|PARI/GP}}==
<langsyntaxhighlight lang="parigp">long(a,b)={
a=eval(Vec(a));
b=eval(Vec(b));
Line 3,789 ⟶ 5,481:
"0"
};
long("18446744073709551616","18446744073709551616")</langsyntaxhighlight>
Output:
<pre>%1 = "340282366920938463463374607431768211456"</pre>
Line 3,795 ⟶ 5,487:
=={{header|Pascal}}==
Extracted from a programme to calculate and factor the number (two versions) in Frederick Pohl's book ''The Gold at the Starbow's End'', and compute Godel encodings of text. Compiles with the Free Pascal Compiler. The original would compile with Turbo Pascal (and used pointers to allow access to the "heap" storage scheme) except that does not allow functions to return a "big number" data aggregate, and it is so much nicer to be able to write X:=BigMult(A,B); The original has a special "square" calculation but this task is to exhibit long multiplication. However, raising to a power by iteration is painful, so a special routine for that.
<syntaxhighlight lang="pascal">
<lang Pascal>
Program TwoUp; Uses DOS, crt;
{Concocted by R.N.McLean (whom God preserve), Victoria university, NZ.}
Line 3,933 ⟶ 5,625:
Write ('x*x = ');BigShow(X); {Can't have Write('x*x = ',BigShow(BigMult(X,X))), after all. Oh well.}
END.
</syntaxhighlight>
</lang>
 
Output:
Line 3,941 ⟶ 5,633:
 
=={{header|Perl}}==
<langsyntaxhighlight lang="perl">#!/usr/bin/perl -w
use strict;
 
Line 3,995 ⟶ 5,687:
 
my $onetwentyeight = &longhand_multiplication($sixtyfour, $sixtyfour);
print "$onetwentyeight\n";</langsyntaxhighlight>
 
=={{header|Phix}}==
Line 4,003 ⟶ 5,695:
If bcd1 is a number split into digits 0..9, bcd9 is a number split into "digits" 000,000,000..999,999,999, which fit in an integer.<br>
They are held lsb-style mainly so that trimming a trailing 0 does not alter their value.
<!--<syntaxhighlight lang="phix">(phixonline)-->
<lang Phix>constant base = 1_000_000_000
<span style="color: #008080;">constant</span> <span style="color: #000000;">base</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1_000_000_000</span>
function bcd9_mult(sequence a, sequence b)
<span style="color: #008080;">function</span> <span style="color: #000000;">bcd9_mult</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">a</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">sequence</span> <span style="color: #000000;">b</span><span style="color: #0000FF;">)</span>
 
sequence c = repeat(0,length(a)+length(b))
<span style="color: #004080;">sequence</span> <span style="color: #000000;">c</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a</span><span style="color: #0000FF;">)+</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">b</span><span style="color: #0000FF;">))</span>
for i=1 to length(a) do
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
integer j = i+length(b)-1
<span style="color: #004080;">integer</span> <span style="color: #000000;">j</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">+</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">b</span><span style="color: #0000FF;">)-</span><span style="color: #000000;">1</span>
c[i..j] = sq_add(c[i..j],sq_mul(a[i],b))
<span style="color: #000000;">c</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">..</span><span style="color: #000000;">j</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">sq_add</span><span style="color: #0000FF;">(</span><span style="color: #000000;">c</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">..</span><span style="color: #000000;">j</span><span style="color: #0000FF;">],</span><span style="color: #7060A8;">sq_mul</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">],</span><span style="color: #000000;">b</span><span style="color: #0000FF;">))</span>
end for
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
for i=1 to length(c) do
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">c</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
atom ci = c[i]
<span style="color: #004080;">atom</span> <span style="color: #000000;">ci</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">c</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span>
if ci>base then
<span style="color: #008080;">if</span> <span style="color: #000000;">ci</span><span style="color: #0000FF;">></span><span style="color: #000000;">base</span> <span style="color: #008080;">then</span>
c[i+1] += floor(ci/base) -- carry
<span style="color: #000000;">c</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">+=</span> <span style="color: #7060A8;">floor</span><span style="color: #0000FF;">(</span><span style="color: #000000;">ci</span><span style="color: #0000FF;">/</span><span style="color: #000000;">base</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- carry</span>
c[i] = remainder(ci,base)
<span style="color: #000000;">c</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">remainder</span><span style="color: #0000FF;">(</span><span style="color: #000000;">ci</span><span style="color: #0000FF;">,</span><span style="color: #000000;">base</span><span style="color: #0000FF;">)</span>
end if
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
end for
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
if c[$]=0 then
<span style="color: #008080;">if</span> <span style="color: #000000;">c</span><span style="color: #0000FF;">[$]=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span>
c = c[1..$-1]
<span style="color: #000000;">c</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">c</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">..$-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span>
end if
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
return c
<span style="color: #008080;">return</span> <span style="color: #000000;">c</span>
end function
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
function atom_to_bcd9(atom a)
<span style="color: #008080;">function</span> <span style="color: #000000;">atom_to_bcd9</span><span style="color: #0000FF;">(</span><span style="color: #004080;">atom</span> <span style="color: #000000;">a</span><span style="color: #0000FF;">)</span>
sequence s = {}
<span style="color: #004080;">sequence</span> <span style="color: #000000;">s</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{}</span>
while a>0 do
<span style="color: #008080;">while</span> <span style="color: #000000;">a</span><span style="color: #0000FF;">></span><span style="color: #000000;">0</span> <span style="color: #008080;">do</span>
s = append(s,remainder(a,base))
<span style="color: #000000;">s</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">append</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">remainder</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a</span><span style="color: #0000FF;">,</span><span style="color: #000000;">base</span><span style="color: #0000FF;">))</span>
a = floor(a/base)
<span style="color: #000000;">a</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">floor</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a</span><span style="color: #0000FF;">/</span><span style="color: #000000;">base</span><span style="color: #0000FF;">)</span>
end while
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
return s
<span style="color: #008080;">return</span> <span style="color: #000000;">s</span>
end function
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
 
function bcd9_to_str(sequence a)
<span style="color: #008080;">function</span> <span style="color: #000000;">bcd9_to_str</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">a</span><span style="color: #0000FF;">)</span>
string s = sprintf("%d",a[$])
<span style="color: #004080;">string</span> <span style="color: #000000;">s</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">sprintf</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"%d"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">a</span><span style="color: #0000FF;">[$])</span>
for i=length(a)-1 to 1 by -1 do
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a</span><span style="color: #0000FF;">)-</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">1</span> <span style="color: #008080;">by</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">1</span> <span style="color: #008080;">do</span>
s &= sprintf("%09d",a[i])
<span style="color: #000000;">s</span> <span style="color: #0000FF;">&=</span> <span style="color: #7060A8;">sprintf</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"%09d"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">a</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">])</span>
end for
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
-- (might want to trim leading 0s here)
<span style="color: #000080;font-style:italic;">-- (might want to trim leading 0s here)</span>
return s
<span style="color: #008080;">return</span> <span style="color: #000000;">s</span>
end function
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
sequence a, b, c
<span style="color: #004080;">sequence</span> <span style="color: #000000;">a</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">b</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">c</span>
a = atom_to_bcd9(power(2,32))
<span style="color: #000000;">a</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">atom_to_bcd9</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">power</span><span style="color: #0000FF;">(</span><span style="color: #000000;">2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">32</span><span style="color: #0000FF;">))</span>
printf(1,"a is %s\n",{bcd9_to_str(a)})
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"a is %s\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">bcd9_to_str</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a</span><span style="color: #0000FF;">)})</span>
b = bcd9_mult(a,a)
<span style="color: #000000;">b</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">bcd9_mult</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a</span><span style="color: #0000FF;">,</span><span style="color: #000000;">a</span><span style="color: #0000FF;">)</span>
printf(1,"a*a is %s\n",{bcd9_to_str(b)})
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"a*a is %s\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">bcd9_to_str</span><span style="color: #0000FF;">(</span><span style="color: #000000;">b</span><span style="color: #0000FF;">)})</span>
c = bcd9_mult(b,b)
<span style="color: #000000;">c</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">bcd9_mult</span><span style="color: #0000FF;">(</span><span style="color: #000000;">b</span><span style="color: #0000FF;">,</span><span style="color: #000000;">b</span><span style="color: #0000FF;">)</span>
printf(1,"a*a*a*a is %s\n",{bcd9_to_str(c)})</lang>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"a*a*a*a is %s\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">bcd9_to_str</span><span style="color: #0000FF;">(</span><span style="color: #000000;">c</span><span style="color: #0000FF;">)})</span>
<!--</syntaxhighlight>-->
{{out}}
<pre>
Line 4,063 ⟶ 5,757:
 
=== string ===
<!--<syntaxhighlight lang="phix">(phixonline)-->
<lang Phix>function mul(string a, b)
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
bool bSign = false
<span style="color: #008080;">function</span> <span style="color: #000000;">mul</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">a</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">b</span><span style="color: #0000FF;">)</span>
if a[1]='-' then {bSign,a} = {not bSign, a[2..$]} end if
<span style="color: #004080;">bool</span> <span style="color: #000000;">bSign</span> <span style="color: #0000FF;">=</span> <span style="color: #004600;">false</span>
if b[1]='-' then {bSign,b} = {not bSign, b[2..$]} end if
<span style="color: #008080;">if</span> <span style="color: #000000;">a</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]=</span><span style="color: #008000;">'-'</span> <span style="color: #008080;">then</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">bSign</span><span style="color: #0000FF;">,</span><span style="color: #000000;">a</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #008080;">not</span> <span style="color: #000000;">bSign</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">a</span><span style="color: #0000FF;">[</span><span style="color: #000000;">2</span><span style="color: #0000FF;">..$]}</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
string res = repeat('0',length(a)+length(b))
<span style="color: #008080;">if</span> <span style="color: #000000;">b</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]=</span><span style="color: #008000;">'-'</span> <span style="color: #008080;">then</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">bSign</span><span style="color: #0000FF;">,</span><span style="color: #000000;">b</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #008080;">not</span> <span style="color: #000000;">bSign</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">b</span><span style="color: #0000FF;">[</span><span style="color: #000000;">2</span><span style="color: #0000FF;">..$]}</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
--
<span style="color: #004080;">string</span> <span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #008000;">'0'</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a</span><span style="color: #0000FF;">)+</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">b</span><span style="color: #0000FF;">))</span>
-- Note that i,j,k are used as negative indexes, working
<span style="color: #000080;font-style:italic;">--
-- from the right hand least significant digit leftwards.
-- Note that i,j,k are used as negative indexes, working
--
-- from the right hand least significant digit leftwards.
for i=1 to length(a) do
--</span>
integer j=1, k=i, c=0
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
while j<=length(b) or c do
<span style="color: #004080;">integer</span> <span style="color: #000000;">j</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">k</span><span style="color: #0000FF;">=</span><span style="color: #000000;">i</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">c</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span>
c += res[-k]-'0'
<span style="color: #008080;">while</span> <span style="color: #000000;">j</span><span style="color: #0000FF;"><=</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">b</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">or</span> <span style="color: #000000;">c</span> <span style="color: #008080;">do</span>
if j<=length(b) then
<span style="color: #000000;">c</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">res</span><span style="color: #0000FF;">[-</span><span style="color: #000000;">k</span><span style="color: #0000FF;">]-</span><span style="color: #008000;">'0'</span>
c += (a[-i]-'0')*(b[-j]-'0')
<span style="color: #008080;">if</span> <span style="color: #000000;">j</span><span style="color: #0000FF;"><=</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">b</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span>
j += 1
<span style="color: #000000;">c</span> <span style="color: #0000FF;">+=</span> <span style="color: #0000FF;">(</span><span style="color: #000000;">a</span><span style="color: #0000FF;">[-</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]-</span><span style="color: #008000;">'0'</span><span style="color: #0000FF;">)*(</span><span style="color: #000000;">b</span><span style="color: #0000FF;">[-</span><span style="color: #000000;">j</span><span style="color: #0000FF;">]-</span><span style="color: #008000;">'0'</span><span style="color: #0000FF;">)</span>
end if
<span style="color: #000000;">j</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span>
res[-k] = remainder(c,10)+'0'
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
c = floor(c/10)
<span style="color: #000000;">res</span><span style="color: #0000FF;">[-</span><span style="color: #000000;">k</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">remainder</span><span style="color: #0000FF;">(</span><span style="color: #000000;">c</span><span style="color: #0000FF;">,</span><span style="color: #000000;">10</span><span style="color: #0000FF;">)+</span><span style="color: #008000;">'0'</span>
k += 1
<span style="color: #000000;">c</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">floor</span><span style="color: #0000FF;">(</span><span style="color: #000000;">c</span><span style="color: #0000FF;">/</span><span style="color: #000000;">10</span><span style="color: #0000FF;">)</span>
end while
<span style="color: #000000;">k</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span>
end for
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
res = trim_head(res,"0")
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
if bSign then res = '-'&res end if
<span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">trim_head</span><span style="color: #0000FF;">(</span><span style="color: #000000;">res</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"0"</span><span style="color: #0000FF;">)</span>
return res
<span style="color: #008080;">if</span> <span style="color: #000000;">bSign</span> <span style="color: #008080;">then</span> <span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">'-'</span><span style="color: #0000FF;">&</span><span style="color: #000000;">res</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
end function
<span style="color: #008080;">return</span> <span style="color: #000000;">res</span>
?mul("18446744073709551616","18446744073709551616")</lang>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #0000FF;">?</span><span style="color: #000000;">mul</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"18446744073709551616"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"18446744073709551616"</span><span style="color: #0000FF;">)</span>
<!--</syntaxhighlight>-->
{{out}}
<pre>
Line 4,096 ⟶ 5,793:
 
=== builtin ===
{{libheader|Phix/mpfr}}
(same output as immediately above)
<!--<syntaxhighlight lang="phix">(phixonline)-->
<lang Phix>include mpfr.e
<span style="color: #008080;">include</span> <span style="color: #004080;">mpfr</span><span style="color: #0000FF;">.</span><span style="color: #000000;">e</span>
mpz a = mpz_init("18446744073709551616") -- or:
<span style="color: #004080;">mpz</span> <span style="color: #000000;">a</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">mpz_init</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"18446744073709551616"</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- or:
--mpz a = mpz_init(); mpz_ui_pow_ui(a,2,64)
--mpz a = mpz_init(); mpz_ui_pow_ui(a,2,64)</span>
mpz_mul(a,a,a)
<span style="color: #7060A8;">mpz_mul</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a</span><span style="color: #0000FF;">,</span><span style="color: #000000;">a</span><span style="color: #0000FF;">,</span><span style="color: #000000;">a</span><span style="color: #0000FF;">)</span>
?mpz_get_str(a)</lang>
<span style="color: #0000FF;">?</span><span style="color: #7060A8;">mpz_get_str</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a</span><span style="color: #0000FF;">)</span>
<!--</syntaxhighlight>-->
 
=={{header|PHP}}==
 
<langsyntaxhighlight PHPlang="php"><?php
function longMult($a, $b)
{
Line 4,169 ⟶ 5,869:
}; // 2^64 * 2^64
 
</syntaxhighlight>
</Lang>
 
=={{header|PicoLisp}}==
<syntaxhighlight lang="picolisp">
<lang PicoLisp>
(de multi (A B)
(setq A (format A) B (reverse (chop B)))
Line 4,178 ⟶ 5,878:
(for (I . X) B
(setq Result (+ Result (* (format X) A (** 10 (dec I)))))) ) )
</syntaxhighlight>
</lang>
 
=={{header|PL/I}}==
<langsyntaxhighlight PL/Ilang="pli">/* Multiply a by b, giving c. */
multiply: procedure (a, b, c);
declare (a, b, c) (*) fixed decimal (1);
Line 4,227 ⟶ 5,927:
a(i) = s;
end;
end complement;</langsyntaxhighlight>
Calling sequence:
<langsyntaxhighlight PL/Ilang="pli"> a = 0; b = 0; c = 0;
a(60) = 1;
do i = 1 to 64; /* Generate 2**64 */
Line 4,239 ⟶ 5,939:
call multiply (a, b, c);
put skip;
call output (c);</langsyntaxhighlight>
Final output:
<pre>
Line 4,247 ⟶ 5,947:
 
=={{header|PL/M}}==
{{Trans|ALGOLBased on the Algol W}} sample, Uses bytes instead of integers to hold the digits. Ony handles positive numbers.
<syntaxhighlight lang="pli">100H: /* LONG MULTIPLICATION OF LARGE INTEGERS */
Tested using a PLM286 to C converter and a simple I/O library.
/* LARGE INTEGERS ARE REPRESENTED BY ARRAYS OF BYTES WHOSE VALUES ARE */
<lang plm>LONGMULT: DO;
/* longA SINGLE DECIMAL DIGIT OF multiplicationTHE ofNUMBER large integers */
/* THE LEAST SIGNIFICANT DIGIT OF THE LARGE INTEGER IS IN ELEMENT 1 */
/* large integers are represented by arrays of bytes whose values are */
/* a single decimal digit of the number ELEMENT 0 CONTAINS THE NUMBER OF DIGITS THE NUMBER HAS */
BDOS: PROCEDURE( FN, ARG ); /* CP/M BDOS SYSTEM CALL */
/* the least significant digits of the large integer are in element 1 */
DECLARE FN BYTE, ARG ADDRESS;
/* element 0 should contain 0 if the number is positive, 1 if negative */
GOTO 5;
/* External I/O routines */
END BDOS;
WRITE$STRING: PROCEDURE( S ) EXTERNAL; DECLARE S POINTER; END WRITE$STRING;
WRITEPRINT$CHAR: PROCEDURE( C ) EXTERNAL; DECLARE C BYTE; ENDCALL WRITE$CHARBDOS( 2, C ); END;
WRITEPRINT$NLSTRING: PROCEDURE( S ); DECLARE S EXTERNALADDRESS; CALL BDOS( 9, S ); END WRITE$NL;
DECLARE PRINT$NL LITERALLY 'PRINT$STRING( .( 0DH, 0AH, ''$'' ) )';
/* End external routines */
 
DECLARE DIGIT$BASE LITERALLY '10';
DECLARE DIGITLONG$COUNT INTEGER LITERALLY '49(201)BYTE'; /* allows up to 48 digits */
DECLARE DIGIT$BASE LITERALLY '10';
/* - enough for the task */
 
DECLARE LARGE$INTEGER LITERALLY '(49)BYTE';
/* PRINTS A LONG INTEGER */
/* returns the position of the highest non-zero digit of the large */
PRINT$LONG$INTEGER: PROCEDURE( N$PTR );
/* integer a with n digits */
DECLARE N$PTR ADDRESS;
HIGHEST$NONZERO$DIGIT$POSITION: PROCEDURE( A$PTR, N ) BYTE;
DECLARE N DECLAREBASED AN$PTR POINTERLONG$INTEGER;
DECLARE N( D, F ) BYTE;
F = DECLAREN( A0 BASED A$PTR LARGE$INTEGER);
DO D DECLARE= AMAX1 BYTETO N( 0 );
AMAX CALL =PRINT$CHAR( N( F ) + '0' );
DO WHILEF AMAX >= 1 AND A( AMAX ) = 0; AMAX = AMAXF - 1; END;
RETURN AMAXEND;
END HIGHESTPRINT$NONZEROLONG$DIGIT$POSITION INTEGER;
/* multipliesIMPLEMENTS LONG MULTIPLICATION, C IS SET TO A * B the large integer in b by the integer a, the result */
/* is added toC c,CAN startingBE fromTHE startSAME LONG$INTEGER AS A OR B */
LONG$MULTIPLY: PROCEDURE( A$PTR, B$PTR, C$PTR );
/* overflow is ignored */
MULTIPLY$ELEMENT: PROCEDURE DECLARE ( A$PTR, B$PTR, C$PTR, START ) ADDRESS;
DECLARE ( A BASED A$PTR, B BASED B$PTR, C BASED C$PTR ) POINTERLONG$INTEGER;
DECLARE ( A, START ) MRESULT BYTELONG$INTEGER;
DECLARE ( B BASED B$PTR, C BASEDRPOS C$PTR ) LARGE$INTEGERBYTE;
 
DECLARE ( CDIGIT, CARRY, BPOS, CPOS ) BYTE;
/* MULTIPLIES THE LONG INTEGER IN B BY THE INTEGER A, THE RESULT */
CARRY = 0;
/* IS ADDED TO C, STARTING FROM DIGIT START */
CPOS = START;
/* OVERFLOW IS IGNORED */
DO BPOS = 1 TO HIGHEST$NONZERO$DIGIT$POSITION( B$PTR, DIGIT$COUNT - START );
MULTIPLY$ELEMENT: PROCEDURE( A, B$PTR, C$PTR, START );
CDIGIT = C( CPOS ) + ( A * B( BPOS ) ) + CARRY;
DECLARE ( B$PTR, C$PTR ) IF CDIGIT < DIGIT$BASE THEN CARRY = 0ADDRESS;
DECLARE ( A, START ) BYTE;
DECLARE ( B BASED B$PTR, C BASED C$PTR ) LONG$INTEGER;
DECLARE ( CDIGIT, D$CARRY, BPOS, CPOS ) BYTE;
D$CARRY = 0;
CPOS = START;
DO BPOS = 1 TO B( 0 );
CDIGIT = C( CPOS ) + ( A * B( BPOS ) ) + D$CARRY;
IF CDIGIT < DIGIT$BASE THEN D$CARRY = 0;
ELSE DO;
/* haveHAVE DIGITS digitsTO toCARRY carry */
D$CARRY = CDIGIT / DIGIT$BASE;
CDIGIT = CDIGIT MOD DIGIT$BASE;
END;
C( CPOS ) = CDIGIT;
CPOS = CPOS + 1;
END;
IF CPOS <= ( DIGIT$COUNT - 1 ) THEN C( CPOS ) = D$CARRY;
/* REMOVE LEADING ZEROS BUT IF THE NUMBER IS 0, KEEP THE FINAL 0 */
END MULTIPLY$ELEMENT ;
/* implements long multiplication, c isDO setWHILE( toCPOS a> *1 bAND C( CPOS ) = 0 */);
CPOS = CPOS - 1;
/* c can be the same array as a or b */
END;
LONG$MULTIPLY: PROCEDURE( A$PTR, B$PTR, C$PTR );
DECLARE C( A$PTR, B$PTR, C$PTR0 ) = POINTERCPOS;
END MULTIPLY$ELEMENT ;
DECLARE ( A BASED A$PTR
 
, B BASED B$PTR
/* THE RESULT WILL BE COMPUTED IN MRESULT, ALLOWING A ,OR CB BASEDTO BE C$PTR */
DO RPOS = 1 TO LAST( MRESULT ); MRESULT( RPOS ) = 0; LARGE$INTEGEREND;
/* MULTIPLY DECLAREBY MRESULTEACH DIGIT AND ADD TO THE RESULT LARGE$INTEGER; */
DECLAREDO RPOS = 1 TO A( 0 BYTE);
/* theIF resultA( willRPOS be) computed<> in0 mResult,THEN allowing a or b to be c */DO;
DO RPOS = 1 TOCALL DIGITMULTIPLY$COUNTELEMENT( - 1; MRESULTA( RPOS ), =B$PTR, 0;.MRESULT, ENDRPOS );
END;
/* multiply and add each digit to the result */
END;
DO RPOS = 1 TO HIGHEST$NONZERO$DIGIT$POSITION( A$PTR, DIGIT$COUNT - 1 );
/* RETURN THE RESULT IN C */
IF A( RPOS ) <> 0 THEN DO;
DO RPOS = 0 TO MRESULT( 0 ); CALL MULTIPLY$ELEMENT( AC( RPOS ), B$PTR,= @MRESULT,( RPOS ); END;
END;
 
END;
/* returnCALCULATE theAND resultOUTPUT in2^128 c */
DECLARE ( TWO$TO$64, TWO$TO$128 ) LONG$INTEGER;
DO RPOS = 1 TO DIGIT$COUNT - 1; C( RPOS ) = MRESULT( RPOS ); END;
DECLARE ( PWR, TPOS ) BYTE;
C( 0 ) = A( 0 ) XOR B( 0 ); /* handle the sign */
/* CONSTRUCT 2^64 IN TWO$TO$64 */
END;
DO TPOS = 0 TO LAST( TWO$TO$64 ); TWO$TO$64( TPOS ) = 0; END;
/* writes the decimal value of a large integer a with n digits */
WRITETWO$LARGETO$INTEGER: PROCEDURE64( A$PTR0 ) = 1;
DECLARE ATWO$PTR TO$64( 1 ) = POINTER2;
PWR DECLARE A BASED A$PTR LARGE$INTEGER= 1;
DO WHILE PWR < 64;
DECLARE ( AMAX, APOS ) BYTE;
CALL LONG$MULTIPLY( .TWO$TO$64, .TWO$TO$64, .TWO$TO$64 );
AMAX = HIGHEST$NONZERO$DIGIT$POSITION( A$PTR, DIGIT$COUNT - 1 );
PWR IF= AMAXPWR <+ 1 THEN CALL WRITE$CHAR( '0' )PWR;
ELSE DOEND;
/* CONSTRUCT 2^128 /* the large integer is non-zero */
TWO$TO$128( 0 ) = 1;
IF A( 0 ) <> 0 THEN CALL WRITE$CHAR( '-' );
TWO$TO$128( 1 APOS) = AMAX0;
CALL LONG$MULTIPLY( .TWO$TO$64, .TWO$TO$64, .TWO$TO$128 );
CALL WRITE$CHAR( A( APOS ) + '0' ); /* highest digit */
CALL PRINT$STRING( .( '2', 05EH, '128: $' ) ); /* 05EH = "^" IN ASCII */
DO WHILE APOS > 1;
CALL PRINT$LONG$INTEGER( .TWO$TO$128 );
APOS = APOS - 1;
CALL PRINT$NL;
CALL WRITE$CHAR( A( APOS ) + '0' );
EOF</syntaxhighlight>
END;
END;
END WRITE$LARGE$INTEGER ;
/* calculate and output 2^128 */
MAIN: PROCEDURE;
DECLARE ( TWOTO64, TWOTO128 ) LARGE$INTEGER;
DECLARE ( PWR, TPOS ) BYTE;
/* construct 2^64 in twoTo64 */
DO TPOS = 0 TO DIGIT$COUNT - 1; TWOTO64( TPOS ) = 0; END;
TWOTO64( 1 ) = 2;
PWR = 1;
DO WHILE PWR < 64;
CALL LONG$MULTIPLY( @TWOTO64, @TWOTO64, @TWOTO64 );
PWR = PWR + PWR;
END;
/* construct 2^128 */
CALL LONG$MULTIPLY( @TWOTO64, @TWOTO64, @TWOTO128 );
CALL WRITE$STRING( @( '2^128: ', 0 ) );
CALL WRITE$LARGE$INTEGER( @TWOTO128 );
CALL WRITE$NL();
END MAIN;
END LONGMULT;</lang>
{{out}}
<pre>
Line 4,364 ⟶ 6,051:
=={{header|PowerShell}}==
===Implementation===
<syntaxhighlight lang="powershell">
<lang PowerShell>
# LongAddition only supports Unsigned Integers represented as Strings/Character Arrays
Function LongAddition ( [Char[]] $lhs, [Char[]] $rhs )
Line 4,444 ⟶ 6,131:
}
 
LongMultiplication "18446744073709551616" "18446744073709551616"</langsyntaxhighlight>
===Library Method===
{{works with|PowerShell|4.0}}
<syntaxhighlight lang="powershell">
<lang PowerShell>
[BigInt]$n = [Math]::Pow(2,64)
[BigInt]::Multiply($n,$n)
</syntaxhighlight>
</lang>
<b>Output:</b>
<pre>
Line 4,458 ⟶ 6,145:
=={{header|Prolog}}==
Arbitrary precision arithmetic is native in most Prolog implementations.
<langsyntaxhighlight Prologlang="prolog"> ?- X is 2**64 * 2**64.
X = 340282366920938463463374607431768211456.</langsyntaxhighlight>
 
=={{header|PureBasic}}==
===Explicit Implementation===
<langsyntaxhighlight lang="purebasic">Structure decDigitFmt ;decimal digit format
Array Digit.b(0) ;contains each digit of number, right-most digit is index 0
digitCount.i ;zero based
Line 4,651 ⟶ 6,338:
Print(#crlf$ + #crlf$ + "Press ENTER to exit"): Input()
CloseConsole()
EndIf</langsyntaxhighlight>
Output:
<pre>The result of 2^64 * 2^64 is 340282366920938463463374607431768211456</pre>
Line 4,659 ⟶ 6,346:
 
Using [http://www.purebasic.fr/english/viewtopic.php?p=309763#p309763 Decimal.pbi] by Stargåte allows for calculation with long numbers, this is useful since version 4.41 of PureBasic mostly only supporter data types native to x86/x64/PPC etc processors.
<langsyntaxhighlight PureBasiclang="purebasic">XIncludeFile "decimal.pbi"
 
Define.Decimal *a, *b
Line 4,665 ⟶ 6,352:
*b=TimesDecimal(*a,*a,#NoDecimal)
 
Print("2^64*2^64 = "+DecimalToString(*b))</langsyntaxhighlight>
 
'''Outputs
Line 4,673 ⟶ 6,360:
(Note that Python comes with arbitrary length integers).
 
<langsyntaxhighlight lang="python">#!/usr/bin/env python
print 2**64*2**64</langsyntaxhighlight>
 
{{works with|Python|3.0}}
{{trans|Perl}}
<langsyntaxhighlight lang="python">#!/usr/bin/env python
 
def add_with_carry(result, addend, addendpos):
Line 4,710 ⟶ 6,397:
 
onetwentyeight = longhand_multiplication(sixtyfour, sixtyfour)
print(onetwentyeight)</langsyntaxhighlight>
 
Shorter version:
{{trans|Haskell}}
{{Works with|Python|3.7}}
<langsyntaxhighlight lang="python">'''Long multiplication'''
 
from functools import reduce
Line 4,757 ⟶ 6,444:
print(
longmult(2 ** 64, 2 ** 64)
)</langsyntaxhighlight>
 
 
Line 4,768 ⟶ 6,455:
In addition to the specified task, we were always encouraged to show our workings.
 
<syntaxhighlight lang="quackery">( ------------- preamble to task, some i/o related words ------------- )
<lang Quackery> [ [] swap witheach
 
[ [] swap witheach
[ char 0 -
swap join ] ] is $->long ( $ --> L )
Line 4,776 ⟶ 6,465:
[ reverse behead
swap witheach
[ swap 10 * + ] ] is long->num ( L --> n )
 
[ reverse
witheach echo ] is echolong ( L --> )
 
( ------------------------- task starts here ------------------------- )
[ over size
over size -
dup dip
[ 0 < if swap ]
abs times
[ 0 join ] ] is zeropad ( L L --> L L )
 
[ [ table
Line 4,803 ⟶ 6,487:
[ dip add add dip [ add nip ] swap ] is addc ( n n c --> n c )
 
[ zeropadover size
0over tempsize put-
[]dup unrot witheachdip
[ dip0 behead< if swap ]
abs times
[ 0 join ] ] is zeropad ( L L --> L L )
 
[ zeropad ( when adding two numbers of different lengths )
0 temp put ( leading zeroes are added to make the lengths )
[] unrot witheach ( equal. This is implicit when the calculation )
[ dip behead ( done by hand, and performed by zeropad here. )
temp take
addc
Line 4,842 ⟶ 6,533:
iff join else drop ] is shortmult ( L n --> L )
 
[ ' [dup 0 ] overlong != iff
[ 0 swap join ] ] is timesten ( L --> L )
 
Line 4,853 ⟶ 6,544:
timesten ]
drop ] is longmult ( L L --> L )
 
 
( ------------------------ additional to task ------------------------ )
Line 4,865 ⟶ 6,555:
[ linelength share
over size - times sp
echolong cr ] is showlong ( L --> )
 
[ over size
Line 4,880 ⟶ 6,570:
rot longadd swap
timesten ]
separatordrop
separator
swap showlong
separatorshowlong
separator
drop linelength release ] is workings ( L L --> )
linelength release ] is workings ( L L --> )
 
( --------------------------- demonstration -------------------------- )
 
say "Using long multiplication: "
Line 4,899 ⟶ 6,591:
cr cr
say "(Show your workings.)" cr cr
2 64 ** long dup workings cr</langsyntaxhighlight>
 
{{out}}
Line 4,940 ⟶ 6,632:
===Using GMP===
{{libheader|gmp}}
<langsyntaxhighlight Rlang="r">library(gmp)
a <- as.bigz("18446744073709551616")
mul.bigz(a,a)</langsyntaxhighlight>
"340282366920938463463374607431768211456"
===A native implementation===
This code is more verbose than necessary, for ease of understanding.
<langsyntaxhighlight Rlang="r">longmult <- function(xstr, ystr)
{
#get the number described in each string
Line 5,011 ⟶ 6,703:
 
a <- "18446744073709551616"
longmult(a, a)</langsyntaxhighlight>
<pre>
"340282366920938463463374607431768211456"
Line 5,017 ⟶ 6,709:
 
=={{header|Racket}}==
<syntaxhighlight lang="racket">
<lang Racket>
#lang racket
 
Line 5,054 ⟶ 6,746:
;; 340282366920938463463374607431768211456
;; 340282366920938463463374607431768211456
</syntaxhighlight>
</lang>
 
=={{header|Raku}}==
Line 5,060 ⟶ 6,752:
{{works with|rakudo|2015-09-17}}
For efficiency (and novelty), this program explicitly implements long multiplication, but in base 10000. That base was chosen because multiplying two 5-digit numbers can overflow a 32-bit integer, but two 4-digit numbers cannot.
<syntaxhighlight lang="raku" perl6line>sub num_to_groups ( $num ) { $num.flip.comb(/.**1..4/)».flip };
sub groups_to_num ( @g ) { [~] flat @g.pop, @g.reverse».fmt('%04d') };
 
Line 5,082 ⟶ 6,774:
 
# cross-check with native implementation
say +$str * +$str;</langsyntaxhighlight>
 
{{out}}
Line 5,098 ⟶ 6,790:
 
Programming note: &nbsp; <big>&&</big> &nbsp; is REXX's &nbsp; '''exclusive or''' &nbsp; operand.
<langsyntaxhighlight lang="rexx">/*REXX program performs long multiplication on two numbers (without the "E"). */
numeric digits 300 /*be able to handle gihugeic input #s. */
parse arg x y . /*obtain optional arguments from the CL*/
if x=='' | x=="," then x= 2**64 /*Not specified? Then use the default.*/
if y=='' | y=="," then y=x x /* " " " " " " */
if x<0 && y<0 then sign= '-' /*there only a single negative number? */
else sign= /*no, then result sign must be positive*/
xx=x; x=strip(x, 'T', .); x1= left(x, 1) /*remove any trailing decimal points. */
yy=y; y=strip(y, 'T', .); y1= left(y, 1) /* " " " " " */
if x1=='-' | x1=="+" then x= substr(x, 2) /*remove a leading ± sign. */
if y1=='-' | y1=="+" then y= substr(y, 2) /* " " " " " */
parse var x '.' xf; parse var y "." yf /*obtain the fractional part of X and Y*/
#= length(xf || yf) /*#: digits past the decimal points (.)*/
x= space( translate( x, , .), 0) /*remove decimal point if there is any.*/
y= space( translate( y, , .), 0) /* " " " " " " " */
Lx= length(x); Ly=length(y) /*get the lengths of the new X and Y. */
numeric digits max(digits(), Lx + Ly) /*use a new decimal digits precision.*/
$=0 0 /*$: is the product (so far). */
do j=Ly by -1 for Ly /*almost like REXX does it, ··· but no.*/
$= $ + ((x*substr(y, j, 1))copies(0, Ly-j) )
end /*j*/
f= length($) - # /*does product has enough decimal digs?*/
if f<0 then $=copies(0, abs(f) + 1)$ /*Negative? Add leading 0s for INSERT.*/
say 'long mult:' xx "*" yy '──►' sign || strip( insert(., $, length($) - #), 'T', .)
say ' built─in:' xx "*" yy '──►' xx*yy /*stick a fork in it, we're all done. */</langsyntaxhighlight>
'''{{out|output''' |text=&nbsp; when using the default inputs:}}
<pre>
long mult: 18446744073709551616 * 18446744073709551616 ──► 340282366920938463463374607431768211456
built─in: 18446744073709551616 * 18446744073709551616 ──► 340282366920938463463374607431768211456
</pre>
'''{{out|output''' |text=&nbsp; when using the inputsinput of: &nbsp; &nbsp; <tt> 123 &nbsp; -456789000 </tt>}}
<pre>
long mult: 123 * -456789000 ──► -56185047000
built─in: 123 * -456789000 ──► -56185047000
</pre>
'''{{out|output''' |text=&nbsp; when using the inputsinput of: &nbsp; &nbsp; <tt> -123.678 &nbsp; +456789000 </tt>}}
<pre>
long mult: -123.678 * +456789000 ──► -56494749942.000
Line 5,140 ⟶ 6,832:
 
===version 2===
<langsyntaxhighlight lang="rexx">/* REXX **************************************************************
* While REXX can multiply arbitrary large integers
* here is the algorithm asked for by the task description
Line 5,218 ⟶ 6,910:
ol=ol||value(name'.z')
End
Return ol</langsyntaxhighlight>
Output:
<pre>soll = 15129
Line 5,235 ⟶ 6,927:
=={{header|Ring}}==
{{Incorrect|Ring|Task is "Implement long multiplication" not "Multiply two numbers using native operators"}}
<langsyntaxhighlight lang="ring">
decimals(0)
see pow(2,64)*pow(2,64) + nl
</syntaxhighlight>
</lang>
Output:
<pre>
340282366920938463463374607431768211456
</pre>
 
=={{header|RPL}}==
To solve the task, we need to develop part of a BigInt library to handle very long integers as strings. Addition has been optimized with a 10-digit batch size, but multiplication is long (and slow), as required.
{| class="wikitable"
! RPL code
! Comment
|-
|
≪ → a
≪ 1 '''WHILE''' a OVER DUP SUB "0" == '''REPEAT''' 1 + '''END'''
a SWAP OVER SIZE SUB
≫ ≫ ‘<span style="color:blue">NoZero’</span> STO
≪ '''WHILE''' DUP '''REPEAT''' "0" ROT + SWAP 1 - '''END''' DROP
≫ ‘<span style="color:blue">ZeroFill</span>' STO
≪ DUP2 SIZE SWAP SIZE → sb sa
≪ '''IF''' sa sb < '''THEN''' SWAP '''END'''
sa sb - ABS
≫ ≫ '<span style="color:blue">Swap→Zero</span>' STO
≪ <span style="color:blue">Swap→Zero ZeroFill</span> → a b
≪ "" 1 CF
a SIZE 1 '''FOR''' j
1 FS?C
a j 9 - j SUB STR→ + b j 9 - j SUB STR→ +
'''IF''' DUP 1E10 ≥ '''THEN''' 1E10 - 1 SF '''END'''
→STR 10 OVER SIZE - <span style="color:blue">ZeroFill</span> SWAP +
-10 '''STEP'''
1 FS? →STR SWAP + <span style="color:blue">NoZero </span>
≫ ≫ ‘<span style="color:blue">ADDbig</span>’ STO
≪ → a d
≪ "" 0
a SIZE 1 '''FOR''' j
a j DUP SUB STR→ d * +
10 MOD LAST / IP
SWAP →STR ROT + SWAP
-1 '''STEP'''
'''IF THEN''' LAST →STR SWAP + '''END'''
≫ ≫ ‘<span style="color:blue">DigitMul</span>’ STO
≪ <span style="color:blue">Swap→Zero</span> DROP → a b
≪ "0" b SIZE 1 '''FOR''' j
a b j DUP SUB STR→ <span style="color:blue">DigitMul</span>
"" b SIZE j - <span style="color:blue">ZeroFill</span> + <span style="color:blue">ADDbig</span>
-1 '''STEP'''
≫ ≫ ‘<span style="color:blue">MULbig’ STO
|
<span style="color:blue">NoZero</span> ''( "0..0xyz" → "xyz" ) ''
count leading zeros
keep the rest
<span style="color:blue">ZeroFill</span> ''( "xyz" n → "0..0xyz" ) ''
<span style="color:blue">Swap→Zero</span> ''( a b → a b Δlength ) ''
swap a and b if length(a) < length(b)
return length difference
<span style="color:blue">ADDbig</span> ''( "a" "b" → "a+b" ) ''
res = "" ; carry = 0
for j = length(a) downto 1 step 10
digits = carry
digits += a[j-9..j] + b[j-9..j]
if b > 1E10 then digits -= 1E10 ; carry = 1
convert digits to 10-char string with leading zeros
next j
prepend carry and remove leading zeros
<span style="color:blue">DigitMul</span> ''( "a" d → "a*d" ) ''
res = "" ; carry = 0
for j = length(a) downto 1
digit = a[j]*d
carry = digit // 10
digit %= 10
next j
prepend carry
<span style="color:blue">MULbig</span> ''( "a" "b" → "a*b" ) ''
sum = "0" ; for j = length(b) downto 1
tmp = a * b[j]
shift left tmp length(b)-j times, then add to sum
next j
|}
"18446744073709551616" DUP <span style="color:blue">MULbig</span>
{{out}}
<pre>
1: "340282366920938463463374607431768211456"
</pre>
 
=={{header|Ruby}}==
{{trans|Tcl}}
<langsyntaxhighlight lang="ruby">def longmult(x,y)
result = [0]
j = 0
Line 5,268 ⟶ 7,055:
n=2**64
printf " %d * %d = %d\n", n, n, n*n
printf "longmult(%d, %d) = %d\n", n, n, longmult(n,n)</langsyntaxhighlight>
<pre> 18446744073709551616 * 18446744073709551616 = 340282366920938463463374607431768211456
longmult(18446744073709551616, 18446744073709551616) = 340282366920938463463374607431768211456</pre>
 
=={{header|Run BASIC}}==
{{works with|Just BASIC}}
{{works with|Liberty BASIC}}
<syntaxhighlight lang="lb">' Same code and result as in Liberty BASIC</syntaxhighlight>
{{out}}
<pre>Same as iberty BASIC entry.</pre>
 
=={{header|Scala}}==
Line 5,276 ⟶ 7,070:
are ever multiplied or added, and all partial results are kept as string.
 
<langsyntaxhighlight lang="scala">def addNums(x: String, y: String) = {
val padSize = x.length max y.length
val paddedX = "0" * (padSize - x.length) + x
Line 5,298 ⟶ 7,092:
 
def mult(x: String, y: String) =
y.foldLeft("")((acc, digit) => addNums(acc + "0", multByDigit(x, digit.asDigit)))</langsyntaxhighlight>
 
Sample:
Line 5,310 ⟶ 7,104:
Scala 2.8 introduces `scanLeft` and `scanRight` which can be used to simplify this further:
 
<langsyntaxhighlight lang="scala">def adjustResult(result: IndexedSeq[Int]) = (
result
.map(_ % 10) // remove carry from each digit
Line 5,332 ⟶ 7,126:
def mult(x: String, y: String) =
y.foldLeft("")((acc, digit) => addNums(acc + "0", multByDigit(x, digit.asDigit)))
</syntaxhighlight>
</lang>
 
=={{header|Scheme}}==
Since Scheme already supports arbitrary precision arithmetic, build it out of church numerals. Don't try converting these to native integers. You will die waiting for the answer.
 
<langsyntaxhighlight lang="scheme">(define one (lambda (f) (lambda (x) (f x))))
(define (add a b) (lambda (f) (lambda (x) ((a f) ((b f) x)))))
(define (mult a b) (lambda (f) (lambda (x) ((a (b f)) x))))
Line 5,344 ⟶ 7,138:
(define six (add two (add two two)))
(define sixty-four (expo two six))
(display (mult (expo two sixty-four) (expo two sixty-four)))</langsyntaxhighlight>
{{out}}
<small>(as run on Chicken Scheme on tio)</small>
Line 5,359 ⟶ 7,153:
[http://seed7.sourceforge.net/libraries/bigint.htm#%28in_bigInteger%29*%28in_bigInteger%29 *]:
 
<langsyntaxhighlight lang="seed7">$ include "seed7_05.s7i";
include "bigint.s7i";
 
Line 5,365 ⟶ 7,159:
begin
writeln(2_**64 * 2_**64);
end func;</langsyntaxhighlight>
 
Output:
Line 5,379 ⟶ 7,173:
The multiplication example below uses the requested inferior implementation:
 
<langsyntaxhighlight lang="seed7">$ include "seed7_05.s7i";
 
const func string: (in string: a) * (in string: b) is func
Line 5,420 ⟶ 7,214:
begin
writeln("-18446744073709551616" * "-18446744073709551616");
end func;</langsyntaxhighlight>
 
The output is the same as with the superior solution.
Line 5,426 ⟶ 7,220:
=={{header|Sidef}}==
(Note that arbitrary precision arithmetic is native in Sidef).
<langsyntaxhighlight lang="ruby">say (2**64 * 2**64);</langsyntaxhighlight>
{{trans|Python}}
<langsyntaxhighlight lang="ruby">func add_with_carry(result, addend, addendpos) {
loop {
while (result.len < addendpos+1) {
Line 5,464 ⟶ 7,258:
}
 
say longhand_multiplication('18446744073709551616', '18446744073709551616')</langsyntaxhighlight>
 
{{out}}
Line 5,472 ⟶ 7,266:
 
=={{header|Slate}}==
<langsyntaxhighlight lang="slate">(2 raisedTo: 64) * (2 raisedTo: 64).</langsyntaxhighlight>
 
=={{header|Smalltalk}}==
Note that arbitrary precision arithmetic is native in Smalltalk, and no-one would reinvent the wheel.
<langsyntaxhighlight lang="smalltalk">(2 raisedTo: 64) * (2 raisedTo: 64).</langsyntaxhighlight>
or, to display it:
<langsyntaxhighlight lang="smalltalk">Transcript showCR:(2 raisedTo: 64) * (2 raisedTo: 64).
"if ** is defined as alias: " Transcript showCR:(2 ** 64) * (2 ** 64).</langsyntaxhighlight>
{{out}}
340282366920938463463374607431768211456
Line 5,491 ⟶ 7,285:
(not that I know of any Smalltalk ever ported to a Zuse 1 :-)
 
<langsyntaxhighlight Smalltalklang="smalltalk">"/ mhmh hard to avoid largeInteger arithmetic,
"/ as the language does not specify, how many bits are used to represent
"/ SmallIntegers, and when the VM uses LargeInts.
Line 5,628 ⟶ 7,422:
"/ verify...
printedString := String streamContents:[:s | printOn value:rslt value:s].
self assert:(printedString = (2**64) squared printString)</langsyntaxhighlight>
{{out}}
3402823669293846346337467431768211456
Line 5,634 ⟶ 7,428:
The above code does not really integrate into the Smalltalk class library. For example, it will not allow mixed mode arithmetic between regular integers and ''Rosetta integers''.
Here is a full example in portable chunk file format which makes mixed mode arithmetic completely transparent (I implemented only addition and multiplication):
<langsyntaxhighlight lang="smalltalk">Integer
subclass: #RosettaInteger
instanceVariableNames:'digitArray'
Line 5,844 ⟶ 7,638:
Transcript show:'once again: '.
result := (2 asRosettaInteger raisedTo:64) squared.
Transcript showCR:result.</langsyntaxhighlight>
{{out}}
<pre>a is: 124 (RosettaInteger)
Line 5,860 ⟶ 7,654:
{{works with|Tcl|8.5}}
Tcl 8.5 supports arbitrary-precision integers, which improves math operations on large integers. It is easy to define our own by following rules for long multiplication; we can then check this against the built-in's result:
<langsyntaxhighlight lang="tcl">package require Tcl 8.5
 
proc longmult {x y} {
Line 5,887 ⟶ 7,681:
puts [set n [expr {2**64}]]
puts [longmult $n $n]
puts [expr {$n * $n}]</langsyntaxhighlight>
outputs
<pre>18446744073709551616
340282366920938463463374607431768211456
340282366920938463463374607431768211456</pre>
 
=={{header|uBasic/4tH}}==
{{Trans|Liberty BASIC}}
<syntaxhighlight lang="basic">' now, count 2^64
Print "2^64"
a := "1"
For i = 1 To 64
a = FUNC(_multByD (a, 2))
Next
 
Print Show (a)
Print "(check with known value)"
Print "18446744073709551616"
Print "(looks OK)"
 
' now let's do b*a stuff
Print
Print "2^64*2^64"
Print Show (FUNC (_longMult (a, a)))
Print "(check with known value)"
Print "340282366920938463463374607431768211456"
Print "(looks OK)"
 
End
 
' ---------------------------------------
_longMult
Param (2)
Local (7)
 
c@ = 1
If Peek (a@, 0) = Ord ("-") Then a@ = Chop (a@, 1) : c@ = -1
d@ = 1
If Peek (b@, 0) = Ord ("-") Then b@ = Chop (b@, 1) : d@ = -1
 
e@ := ""
f@ := ""
g@ := ""
For h@ = Len(a@)-1 To 0 Step -1
i@ = Peek (a@, h@) - Ord ("0")
f@ = FUNC(_multByD (b@, i@))
e@ = FUNC(_addLong (e@, Join (f@, g@)))
g@ = Join (g@, "0")
Next ' print i@, f@, e@
' print e@
If c@*d@ < 0 Then e@ = Join ("-", e@)
Return (e@)
 
_multByD
Param (2) ' multiply a@ by digit b@
Local (5)
c@ := ""
d@ = 0
 
For e@ = Len (a@)-1 To 0 Step -1
f@ = Peek (a@, e@) - Ord ("0")
g@ = f@*b@ + d@
d@ = g@ / 10)
g@ = g@ % 10
' print f@, g@
c@ = Join (Str (g@), c@)
Next
 
If d@ > 0 Then c@ = Join (Str (d@), c@)
Return (c@) ' print c@
 
_addLong ' add a@ + b@, for now only positive
Param (2)
Local (7)
 
c@ = Max (Len(a@), Len(b@))
a@ = FUNC(_Pad (a@, c@))
b@ = FUNC(_Pad (b@, c@))
d@ := "" ' result
e@ = 0
For f@ = c@-1 To 0 Step -1
g@ = Peek (a@, f@) - Ord ("0")
h@ = Peek (b@, f@) - Ord ("0")
i@ = g@ + h@ + e@
e@ = i@ / 10
i@ = i@ % 10
' print g@, h@, i@
d@ = Join (Str (i@), d@)
Next
' print d@
If e@ > 0 Then d@ = Join (Str (e@), d@)
Return (d@)
 
_Pad ' pad from right with 0 to length n
Param (2)
 
Do While Len (a@) < b@
a@ = Join("0", a@)
Loop
Return (a@)</syntaxhighlight>
{{Out}}
<pre>2^64
18446744073709551616
(check with known value)
18446744073709551616
(looks OK)
 
2^64*2^64
340282366920938463463374607431768211456
(check with known value)
340282366920938463463374607431768211456
(looks OK)
 
0 OK, 0:478</pre>
 
=={{header|UNIX Shell}}==
Line 5,897 ⟶ 7,802:
In real shell scripts, I would use either `bc` or `dc` for this:
 
<langsyntaxhighlight lang="sh">multiply() { echo "$1 $2 * p" | dc; }</langsyntaxhighlight>
 
But you can also do it with bash's built-in arithmetic:
 
<langsyntaxhighlight lang="bash">add() { # arbitrary-precision addition
local a="$1" b="$2" sum= carry=0
if (( ${#a} < ${#b} )); then
Line 5,943 ⟶ 7,848:
done
echo "$product"
}</langsyntaxhighlight>
 
Output is the same either way:<pre>$ multiply 18446744073709551616 18446744073709551616
Line 5,959 ⟶ 7,864:
them in decimal.
 
<langsyntaxhighlight Ursalalang="ursala">successor = ~&a^?\1! ~&ah?/~&NfatPRC ~&NNXatPC
 
sum = ~&B^?a\~&Y@a ~&B?abh/successor@alh2fabt2RC ~&Yabh2Ofabt2RC
Line 5,969 ⟶ 7,874:
#show+
 
y = %nP product@iiX x</langsyntaxhighlight>
output:
<pre>340282366920938463463374607431768211456</pre>
Line 5,975 ⟶ 7,880:
=={{header|Vedit macro language}}==
This example multiplies the value on current line with the value on next line and stores result on the 3rd line.
<langsyntaxhighlight lang="vedit">BOL
#11 = EOL_Pos-Cur_Pos
#12 = EOL_Pos-1
Line 5,999 ⟶ 7,904:
}
}
} </langsyntaxhighlight>
Sample input and output:
<pre>
Line 6,010 ⟶ 7,915:
{{trans|C#}}<br/>
This uses the '''decimal''' type, (which has a '''MaxValue''' of 79,228,162,514,264,337,593,543,950,335). By limiting it to '''10^28''', it allows 28 decimal digits for the ''hi'' part, and 28 decimal digits for the ''lo'' part, '''56 decimal digits''' total. A side computation of ''BigInteger'' assures that the results are accurate.
<langsyntaxhighlight lang="vbnet">Imports System
Imports System.Console
Imports BI = System.Numerics.BigInteger
Line 6,056 ⟶ 7,961:
End Sub
 
End Module</langsyntaxhighlight>
{{out}}Shown are the prescribed output and the maximum power of two that can be squared by this '''''bd''''' structure without overflowing.
<pre>The square of (2^64): 18,446,744,073,709,551,616
Line 6,067 ⟶ 7,972:
{{trans|Go}}
{{libheader|Wren-fmt}}
<langsyntaxhighlight ecmascriptlang="wren">import "./fmt" for Fmt
 
// argument validation
Line 6,130 ⟶ 8,035:
 
var n = "18446744073709551616"
Fmt.print("$,s", mul.call(n, n))</langsyntaxhighlight>
 
{{out}}
Line 6,138 ⟶ 8,043:
 
=={{header|XPL0}}==
<langsyntaxhighlight XPL0lang="xpl0">include c:\cxpl\stdlib;
char Two64, Product(40);
[Two64:= "18446744073709551616";
Line 6,144 ⟶ 8,049:
Product(39):= Product(39)!$80; \terminate string
Text(0, Product+1); \skip leading zero
]</langsyntaxhighlight>
 
Output:
Line 6,153 ⟶ 8,058:
=={{header|zkl}}==
[gnu] BigNums are supported via an extension library
<langsyntaxhighlight lang="zkl">var BN=Import("zklBigNum");
BN(2).pow(64) * BN(2).pow(64)
340282366920938463463374607431768211456
Line 6,162 ⟶ 8,067:
//42!, also BN(42).factorial()
[2..42].reduce(fcn(p,n){p*n},BN(1)) : "%,d".fmt(_)
1,405,006,117,752,879,898,543,142,606,244,511,569,936,384,000,000,000</langsyntaxhighlight>
 
{{omit from|Erlang|Erlang has this built in}}
9,476

edits