Ethiopian multiplication: Difference between revisions
m
→{{header|EasyLang}}
No edit summary |
|||
(22 intermediate revisions by 11 users not shown) | |||
Line 51:
Use these functions to '''create a function that does Ethiopian multiplication'''.
;Related tasks:
* [[Egyptian_division|Egyptian division]]
;References:
Line 154 ⟶ 156:
{{out}}
<pre>578</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 multieth64.s */
/************************************/
/* Constantes */
/************************************/
.include "../includeConstantesARM64.inc"
/*********************************/
/* Initialized data */
/*********************************/
.data
szMessResult: .asciz "Result : "
szMessStart: .asciz "Program 64 bits start.\n"
szCarriageReturn: .asciz "\n"
szMessErreur: .asciz "Error overflow. \n"
/*********************************/
/* UnInitialized data */
/*********************************/
.bss
sZoneConv: .skip 24
/*********************************/
/* code section */
/*********************************/
.text
.global main
main: // entry of program
ldr x0,qAdrszMessStart
bl affichageMess
mov x0,#17
mov x1,#34
bl multEthiop
ldr x1,qAdrsZoneConv
bl conversion10 // decimal conversion
mov x0,#3 // number string to display
ldr x1,qAdrszMessResult
ldr x2,qAdrsZoneConv // insert conversion in message
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
qAdrszMessResult: .quad szMessResult
qAdrszMessErreur: .quad szMessErreur
qAdrszMessStart: .quad szMessStart
/******************************************************************/
/* Ethiopian multiplication unsigned */
/******************************************************************/
/* x0 first factor */
/* x1 2th factor */
/* x0 return résult */
multEthiop:
stp x1,lr,[sp,-16]! // save registers
stp x2,x3,[sp,-16]! // save registers
mov x2,#0 // init result
1: // loop
cmp x0,#1 // end ?
blt 3f
ands x3,x0,#1 //
add x3,x2,x1 // add factor2 to result
csel x2,x2,x3,eq
mov x3,1
lsr x0,x0,x3 // divide factor1 by 2
cmp x1,0 // overflow ? if bit 63 = 1 ie negative number
blt 2f
mov x4,1
lsl x1,x1,x4 // multiply factor2 by 2
b 1b // or loop
2: // error display
ldr x0,qAdrszMessErreur
bl affichageMess
mov x2,#0
3:
mov x0,x2 // return result
ldp x2,x3,[sp],16 // restaur registers
ldp x1,lr,[sp],16 // restaur registers
ret
/***************************************************/
/* display multi strings */
/***************************************************/
/* x0 contains number strings address */
/* x1 address string1 */
/* x2 address string2 */
/* x3 address string3 */
/* other address on the stack */
/* thinck to add number other address * 8 to add to the stack */
displayStrings: // INFO: displayStrings
stp x1,lr,[sp,-16]! // save registers
stp x2,x3,[sp,-16]! // save registers
stp x4,x5,[sp,-16]! // save registers
add fp,sp,#48 // save paraméters address (6 registers saved * 4 bytes)
mov x4,x0 // save strings number
cmp x4,#0 // 0 string -> end
ble 100f
mov x0,x1 // string 1
bl affichageMess
cmp x4,#1 // number > 1
ble 100f
mov x0,x2
bl affichageMess
cmp x4,#2
ble 100f
mov x0,x3
bl affichageMess
cmp x4,#3
ble 100f
mov x3,#3
sub x2,x4,#8
1: // loop extract address string on stack
ldr x0,[fp,x2,lsl #3]
bl affichageMess
subs x2,x2,#1
bge 1b
100:
ldp x4,x5,[sp],16 // restaur registers
ldp x2,x3,[sp],16 // restaur registers
ldp x1,lr,[sp],16 // restaur registers
ret
/***************************************************/
/* ROUTINES INCLUDE */
/***************************************************/
.include "../includeARM64.inc"
</syntaxhighlight>
{{Out}}
<pre>
Program 64 bits start.
Result : 578
</pre>
=={{header|ACL2}}==
<syntaxhighlight lang="lisp">(include-book "arithmetic-3/top" :dir :system)
Line 569 ⟶ 708:
<pre>{578, "RhindRhindRhindRhindRhindRhindRhindRhindRhind"}</pre>
=={{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 multieth.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 */
/* for constantes see task include a file in arm assembly */
/************************************/
/* Constantes */
/************************************/
.include "../constantes.inc"
/*********************************/
/* Initialized data */
/*********************************/
.data
szMessResult: .asciz "Result : "
szMessStart: .asciz "Program 32 bits start.\n"
szCarriageReturn: .asciz "\n"
szMessErreur: .asciz "Error overflow. \n"
/*********************************/
/* UnInitialized data */
/*********************************/
.bss
sZoneConv: .skip 24
/*********************************/
/* code section */
/*********************************/
.text
.global main
main: @ entry of program
ldr r0,iAdrszMessStart
bl affichageMess
mov r0,#17
mov r1,#34
bl multEthiop
ldr r1,iAdrsZoneConv
bl conversion10 @ decimal conversion
mov r0,#3 @ number string to display
ldr r1,iAdrszMessResult
ldr r2,iAdrsZoneConv @ insert conversion in message
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
iAdrszMessResult: .int szMessResult
iAdrszMessErreur: .int szMessErreur
iAdrszMessStart: .int szMessStart
/******************************************************************/
/* Ethiopian multiplication */
/******************************************************************/
/* r0 first factor */
/* r1 2th factor */
/* r0 return résult */
multEthiop:
push {r1-r3,lr} @ save registers
mov r2,#0 @ init result
1: @ loop
cmp r0,#1 @ end ?
blt 3f
ands r3,r0,#1 @
addne r2,r1 @ add factor2 to result
lsr r0,#1 @ divide factor1 by 2
lsls r1,#1 @ multiply factor2 by 2
bcs 2f @ overflow ?
b 1b @ or loop
2: @ error display
ldr r0,iAdrszMessErreur
bl affichageMess
mov r2,#0
3:
mov r0,r2 @ return result
pop {r1-r3,pc}
/***************************************************/
/* 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}
/***************************************************/
/* ROUTINES INCLUDE */
/***************************************************/
.include "../affichage.inc"
</syntaxhighlight>
{{Out}}
<pre>
Program 32 bits start.
Result : 578
</pre>
=={{header|Arturo}}==
Line 705 ⟶ 977:
=={{header|BASIC}}==
==={{header|Applesoft BASIC}}===
Same code as [[#Nascom_BASIC|Nascom BASIC]]
==={{header|ASIC}}===
Line 797 ⟶ 1,071:
FUNCTION isEven% (a AS INTEGER)
isEven% = (a MOD 2) - 1
END FUNCTION</syntaxhighlight>
{{out}}
<pre> 17 34
8
4
2
1 544
= 578</pre>
==={{header|BASIC256}}===
<syntaxhighlight lang="vbnet">outP = 0
x = 17
y = 34
while True
print x + chr(09);
if not (isEven(x)) then
outP += y
print y
else
print
end if
if x < 2 then exit while
x = half(x)
y = doub(y)
end while
print "=" + chr(09); outP
end
function doub (a)
return a * 2
end function
function half (a)
return a \ 2
end function
function isEven (a)
return (a mod 2) - 1
end function</syntaxhighlight>
==={{header|BBC BASIC}}===
Line 827 ⟶ 1,134:
DEF FNhalve(A%) = A% DIV 2
DEF FNeven(A%) = ((A% AND 1) = 0)</syntaxhighlight>
{{out}}
<pre> 17 34
8 ---
4 ---
Line 834 ⟶ 1,142:
1 544
===
578</pre>
==={{header|Chipmunk Basic}}===
{{trans|BASIC256}}
{{works with|Chipmunk Basic|3.6.4}}
<syntaxhighlight lang="vbnet">100 sub doub(a)
110 doub = a*2
120 end sub
130 sub half(a)
140 half = int(a/2)
150 end sub
160 sub iseven(a)
170 iseven = (a mod 2)-1
180 end sub
190 outp = 0
200 x = 17
210 y = 34
220 while 1
230 print x;chr$(9);
240 if not (iseven(x)) then
250 outp = outp - y
260 print y
270 else
280 print
290 endif
300 if x < 2 then exit while
310 x = half(x)
320 y = doub(y)
330 wend
340 print "=";chr$(9);outp
350 end</syntaxhighlight>
==={{header|FreeBASIC}}===
Line 925 ⟶ 1,263:
Sleep
</syntaxhighlight>note: algorithm uses strings instead of integers
{{out}}
<pre>Half Double * marks those accumulated
Biggest Smallest
Line 994 ⟶ 1,333:
doubleInt = Int(num * 2)
End Function</syntaxhighlight>
==={{header|Microsoft Small Basic}}===
<syntaxhighlight lang="microsoftsmallbasic">x = 17
y = 34
tot = 0
Line 1,015 ⟶ 1,352:
TextWindow.Write("=")
TextWindow.CursorLeft = 10
TextWindow.WriteLine(tot)</syntaxhighlight>
==={{header|Minimal BASIC}}===
<syntaxhighlight lang="gwbasic">10 REM Ethiopian multiplication
20 DEF FND(A) = 2*A
30 DEF FNH(A) = INT(A/2)
Line 1,038 ⟶ 1,373:
170 PRINT "------------"
180 PRINT "= "; TAB(9); T; "(sum of kept second vals)"
190 END</syntaxhighlight>
==={{header|MSX Basic}}===
{{works with|MSX BASIC|any}}
Same code as [[#Nascom_BASIC|Nascom BASIC]]
==={{header|Nascom BASIC}}===
{{trans|Modula-2}}
{{works with|Nascom ROM BASIC|4.7}}
<syntaxhighlight lang="basic">10 REM Ethiopian multiplication
20 DEF FND(A)=2*A
30 DEF FNH(A)=INT(A/2)
Line 1,065 ⟶ 1,402:
1000 S$=STR$(NR)
1010 PRINT SPC(9-LEN(S$));S$;
1020 RETURN</syntaxhighlight>
{{out}}
<pre> 17 34
8
4
2
1 544
= 578</pre>
==={{header|PureBasic}}===
Line 1,153 ⟶ 1,487:
EndIf</syntaxhighlight>
{{out}}
Ethiopian multiplication of -17 and 34 ... equals -578
Ethiopian multiplication of -17 and -34 ... equals 578</pre>
==={{header|QB64}}===
Line 1,184 ⟶ 1,518:
END FUNCTION</syntaxhighlight>
{{out}}
<pre>578</pre>
==={{header|Sinclair ZX81 BASIC}}===
Line 1,277 ⟶ 1,609:
REM A - param.; E - result (0 - false)
400 LET E=A-(A/2)*2
RETURN
{{out}}
<pre>17, 34 (kept)
8, 68
4, 136
Line 1,287 ⟶ 1,617:
1, 544 (kept)
------------
= 578 (sum of kept second vals)</pre>
==={{header|True BASIC}}===
A translation of BBC BASIC. True BASIC does not have Boolean operations built-in.
<syntaxhighlight lang="basic">!RosettaCode: Ethiopian Multiplication
! True BASIC v6.007
PROGRAM EthiopianMultiplication
Line 1,321 ⟶ 1,649:
DEF FNhalve(A) = INT(A / 2)
DEF FNeven(A) = MOD(A+1,2)
END</syntaxhighlight>
==={{header|XBasic}}===
{{trans|Modula-2}}
{{works with|Windows XBasic}}
<syntaxhighlight lang="xbasic">' Ethiopian multiplication
PROGRAM "ethmult"
VERSION "0.0000"
Line 1,369 ⟶ 1,694:
RETURN a&& MOD 2 = 0
END FUNCTION
END PROGRAM</syntaxhighlight>
{{out}}
<pre> 17 34
8
4
2
1 544
= 578</pre>
==={{header|Yabasic}}===
<syntaxhighlight lang="vbnet">outP = 0
x = 17
y = 34
do
print x, chr$(09);
if not (isEven(x)) then
outP = outP + y
print y
else
print
fi
if x < 2 break
x = half(x)
y = doub(y)
loop
print "=", chr$(09), outP
end
sub doub (a)
return a * 2
end sub
sub half (a)
return int(a / 2)
end sub
sub isEven (a)
return mod(a, 2) - 1
end sub</syntaxhighlight>
=={{header|Batch File}}==
Line 1,874 ⟶ 2,228:
throw Error("broken for #{i} * #{j}") if multiply(i,j) != i * j
</syntaxhighlight>
=== CoffeeScript "One-liner" ===
ethiopian = (a, b, r=0) -> if a <= 0 then r else ethiopian a // 2, b * 2, if a % 2 then r + b else r
=={{header|ColdFusion}}==
Line 2,027 ⟶ 2,385:
let a = x
let a = int
let x = a
let a = y
Line 2,036 ⟶ 2,394:
print "="
print t</syntaxhighlight>
{{out| Output}}<pre>17 34
8
4
2
1
1 544
=
578</pre>
=={{header|D}}==
Line 2,143 ⟶ 2,507:
=={{header|EasyLang}}==
<syntaxhighlight>
func mult x y .
while x >=
if x mod 2 <> 0
tot +=
.
return
.
print
</syntaxhighlight>
Line 2,509 ⟶ 2,868:
=={{header|Fōrmulæ}}==
{{FormulaeEntry|page=https://formulae.org/?script=examples/Ancient_Egyptian_multiplication}}
'''Solution'''
[[File:Fōrmulæ - Ancient Egyptian multiplication 01.png]]
'''Test case'''
[[File:Fōrmulæ - Ancient Egyptian multiplication 02.png]]
[[File:Fōrmulæ - Ancient Egyptian multiplication 03.png]]
Because the required functions are either simple or intrinsic, the solution can be much simpler:
[[File:Fōrmulæ - Ancient Egyptian multiplication 04.png]]
=={{header|FutureBasic}}==
<syntaxhighlight lang="futurebasic">
local fn Doubled( n as long ) : end fn = n * 2
local fn Halved( n as long ) : end fn = int( n / 2 )
local fn IsEven( n as long ) : end fn = ( n mod 2 ) - 1
local fn EthiopianMultiply( x as long, y as long )
long sum = 0, sign = x
printf @"Ethiopian multiplication of %3ld x %3ld = \b", x, y
do
if not ( fn IsEven( x ) ) then sum += y
x = fn Halved( x ) : y = fn Doubled( y )
until ( x == 0 )
if sign < 0 then sum *= - 1
printf @"%4ld", sum
end fn
fn EthiopianMultiply( 17, 34 )
fn EthiopianMultiply( -17, 34 )
fn EthiopianMultiply( -17, -34 )
HandleEvents
</syntaxhighlight>
{{output}}
<pre>
Ethiopian multiplication of 17 x 34 = 578
Ethiopian multiplication of -17 x 34 = -578
Ethiopian multiplication of -17 x -34 = 578
</pre>
=={{header|Go}}==
Line 3,062 ⟶ 3,461:
=={{header|Kotlin}}==
<syntaxhighlight lang="scala">// version 1.1.2
Line 3,092 ⟶ 3,492:
99 x 99 = 9801
</pre>
=== Literally follow the algorithm using generateSequence() ===
<syntaxhighlight lang="kotlin">
fun Int.halve() = this shr 1
fun Int.double() = this shl 1
fun Int.isOdd() = this and 1 == 1
fun ethiopianMultiply(n: Int, m: Int): Int =
generateSequence(Pair(n, m)) { p -> Pair(p.first.halve(), p.second.double()) }
.takeWhile { it.first >= 1 }.filter { it.first.isOdd() }.sumOf { it.second }
fun main() {
ethiopianMultiply(17, 34).also { println(it) } // 578
ethiopianMultiply(99, 99).also { println(it) } // 9801
ethiopianMultiply(4, 8).also { println(it) } // 32
}
</syntaxhighlight>
=={{header|Lambdatalk}}==
Line 3,385 ⟶ 3,803:
578
</syntaxhighlight>
=={{header|Maxima}}==
<syntaxhighlight lang="maxima">
/* Function to halve */
halve(n):=floor(n/2)$
/* Function to double */
double(n):=2*n$
/* Predicate function to check wether an integer is even */
my_evenp(n):=if mod(n,2)=0 then true$
/* Function that implements ethiopian function using the three previously defined functions */
ethiopian(n1,n2):=block(cn1:n1,cn2:n2,list_w:[],
while cn1>0 do (list_w:endcons(cn1,list_w),cn1:halve(cn1)),
n2_list:append([cn2],makelist(cn2:double(cn2),length(list_w)-1)),
sublist_indices(list_w,lambda([x],not my_evenp(x))),
makelist(n2_list[i],i,%%),
apply("+",%%))$
</syntaxhighlight>
Line 5,297 ⟶ 5,735:
578
</pre>
=={{header|RPL}}==
Calculations are here made on binary integers, on which built-in instructions <code>SL</code> and <code>SR</code> perform resp. doubling and halving.
{{works with|Halcyon Calc|4.2.7}}
{| class="wikitable"
! RPL code
! Comment
|-
|
≪ # 1d AND # 0d ==
≫ ''''EVEN?'''' STO
≪
# 0d ROT R→B ROT R→B
'''WHILE''' OVER # 0d ≠ '''REPEAT'''
'''IF''' OVER '''EVEN?''' NOT
'''THEN''' ROT OVER + ROT ROT '''END '''
SL SWAP SR SWAP
'''END''' DROP2 B→R
≫ ''''ETMUL'''' STO
|
'''EVEN?''' ''( #n -- boolean ) ''
return 1 if n is even, 0 otherwise
'''ETMUL''' ''( a b -- a*b ) ''
put accumulator, a and b (converted to integers) in stack
while b > 0
if b is odd
add a to accumulator
double a, halve b
delete a and b and convert a*b to floating point
|}
=={{header|Ruby}}==
Line 6,188 ⟶ 6,659:
=={{header|Wren}}==
<syntaxhighlight lang="
var double = Fn.new { |n| n * 2 }
Line 6,435 ⟶ 6,906:
--------
7006652</pre>
=={{header|zig}}==
<syntaxhighlight lang="zig">
// programme multiplication ethiopienne
// Ethiopian multiplication
const std = @import("std");
const expect = std.testing.expect;
const print = @import("std").debug.print;
pub fn main() !void {
const Res = multiEth(17,34);
print("Resultat= {} \n", .{ Res });
}
test "Ethiopian multiplication" {
try expect(multiEth(20, 10) == 200);
try expect(multiEth(101, 101) == 10201);
try expect(multiEth(20, 0) == 0);
try expect(multiEth(0, 71) == 0);
}
//*****************************
// multiplication
//*****************************
fn multiEth(X: i64, Y: i64) i64 {
var X1=X;
var Y1=Y;
var sum: i64 = 0;
while (X1>=1) {
if ((@mod(X1,2)) == 1)
sum += Y1;
Y1= Y1 * 2;
X1 = @divFloor(X1,2);
}
return sum;
}
</syntaxhighlight>
{{Out}}
<pre>
Resultat= 578
</pre>
=={{header|zkl}}==
|