Ethiopian multiplication: Difference between revisions

m
 
(20 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}}
{{out}}
17 34
<pre> 17 34
8
4
2
1 544
= 578</pre>
 
==={{header|BASIC256}}===
<syntaxhighlight lang="basic256vbnet">outP = 0
x = 17
y = 34
Line 859 ⟶ 1,134:
DEF FNhalve(A%) = A% DIV 2
DEF FNeven(A%) = ((A% AND 1) = 0)</syntaxhighlight>{{out}}
{{out}}
17 34
<pre> 17 34
8 ---
4 ---
Line 866 ⟶ 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 957 ⟶ 1,263:
Sleep
</syntaxhighlight>note: algorithm uses strings instead of integers
{{out}}
{{out}}<pre>Half Double * marks those accumulated
<pre>Half Double * marks those accumulated
Biggest Smallest
 
Line 1,026 ⟶ 1,333:
doubleInt = Int(num * 2)
End Function</syntaxhighlight>
 
 
==={{header|Microsoft Small Basic}}===
<syntaxhighlight lang="microsoftsmallbasic">x = 17
x = 17
y = 34
tot = 0
Line 1,047 ⟶ 1,352:
TextWindow.Write("=")
TextWindow.CursorLeft = 10
TextWindow.WriteLine(tot)</syntaxhighlight>
</syntaxhighlight>
 
==={{header|Minimal BASIC}}===
<syntaxhighlight lang="gwbasic">10 REM Ethiopian multiplication
10 REM Ethiopian multiplication
20 DEF FND(A) = 2*A
30 DEF FNH(A) = INT(A/2)
Line 1,070 ⟶ 1,373:
170 PRINT "------------"
180 PRINT "= "; TAB(9); T; "(sum of kept second vals)"
190 END</syntaxhighlight>
 
</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
10 REM Ethiopian multiplication
20 DEF FND(A)=2*A
30 DEF FNH(A)=INT(A/2)
Line 1,097 ⟶ 1,402:
1000 S$=STR$(NR)
1010 PRINT SPC(9-LEN(S$));S$;
1020 RETURN</syntaxhighlight>
</syntaxhighlight>
{{out}}
<pre> 17 34
17 34
8
4
2
1 544
= 578</pre>
</pre>
 
==={{header|PureBasic}}===
Line 1,185 ⟶ 1,487:
EndIf</syntaxhighlight>
{{out}}
<pre> Ethiopian multiplication of 17 and 34 ... equals 578
Ethiopian multiplication of -17 and 34 ... equals -578
Ethiopian multiplication of -17 and -34 ... equals 578</pre>
 
==={{header|QB64}}===
Line 1,216 ⟶ 1,518:
END FUNCTION</syntaxhighlight>
{{out}}
<pre>578</pre>
578
</pre>
 
==={{header|Sinclair ZX81 BASIC}}===
Line 1,309 ⟶ 1,609:
REM A - param.; E - result (0 - false)
400 LET E=A-(A/2)*2
RETURN </syntaxhighlight>
</syntaxhighlight>
{{out}}
<pre>17, 34 (kept)
17, 34 (kept)
8, 68
4, 136
Line 1,319 ⟶ 1,617:
1, 544 (kept)
------------
= 578 (sum of kept second vals)</pre>
</pre>
 
==={{header|True BASIC}}===
A translation of BBC BASIC. True BASIC does not have Boolean operations built-in.
<syntaxhighlight lang="basic">!RosettaCode: Ethiopian Multiplication
!RosettaCode: Ethiopian Multiplication
! True BASIC v6.007
PROGRAM EthiopianMultiplication
Line 1,353 ⟶ 1,649:
DEF FNhalve(A) = INT(A / 2)
DEF FNeven(A) = MOD(A+1,2)
END</syntaxhighlight>
END
 
</syntaxhighlight>
 
==={{header|XBasic}}===
{{trans|Modula-2}}
{{works with|Windows XBasic}}
<syntaxhighlight lang="xbasic">' Ethiopian multiplication
' Ethiopian multiplication
PROGRAM "ethmult"
VERSION "0.0000"
Line 1,401 ⟶ 1,694:
RETURN a&& MOD 2 = 0
END FUNCTION
END PROGRAM</syntaxhighlight>
</syntaxhighlight>
{{out}}
<pre> 17 34
17 34
8
4
2
1 544
= 578</pre>
</pre>
 
==={{header|Yabasic}}===
<syntaxhighlight lang="yabasicvbnet">outP = 0
x = 17
y = 34
Line 1,938 ⟶ 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,100 ⟶ 2,394:
 
print "="
print t</syntaxhighlight>
{{out| Output}}<pre>17 34
 
8
end</syntaxhighlight>
4
2
1
1 544
=
578</pre>
 
=={{header|D}}==
Line 2,207 ⟶ 2,507:
 
=={{header|EasyLang}}==
<syntaxhighlight>
{{trans|Microsoft Small Basic}}
func mult x y .
<syntaxhighlight lang="text">
while x >= 171
if x mod 2 <> 0
y = 34
tot += 0y
.
while x >= 1
write x = x &div "\t"2
if (x + 1) mod 2y *= 02
tot += y.
return print ytot
else
print ""
.
x = x div 2
y = 2 * y
.
print "=\t"mult &17 tot34
</syntaxhighlight>
 
Line 2,573 ⟶ 2,868:
=={{header|Fōrmulæ}}==
 
{{FormulaeEntry|page=https://formulae.org/?script=examples/Ancient_Egyptian_multiplication}}
Fōrmulæ programs are not textual, visualization/edition of programs is done showing/manipulating structures but not text. Moreover, there can be multiple visual representations of the same program. Even though it is possible to have textual representation &mdash;i.e. XML, JSON&mdash; they are intended for storage and transfer purposes more than visualization and edition.
 
'''Solution'''
Programs in Fōrmulæ are created/edited online in its [https://formulae.org website], However they run on execution servers. By default remote servers are used, but they are limited in memory and processing power, since they are intended for demonstration and casual use. A local server can be downloaded and installed, it has no limitations (it runs in your own computer). Because of that, example programs can be fully visualized and edited, but some of them will not run if they require a moderate or heavy computation/memory resources, and no local server is being used.
 
[[File:Fōrmulæ - Ancient Egyptian multiplication 01.png]]
In '''[https://formulae.org/?example=Ancient_Egyptian_multiplication this]''' page you can see the program(s) related to this task and their results.
 
'''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,126 ⟶ 3,461:
 
=={{header|Kotlin}}==
 
<syntaxhighlight lang="scala">// version 1.1.2
 
Line 3,156 ⟶ 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,449 ⟶ 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,361 ⟶ 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,252 ⟶ 6,659:
 
=={{header|Wren}}==
<syntaxhighlight lang="ecmascriptwren">var halve = Fn.new { |n| (n/2).truncate }
 
var double = Fn.new { |n| n * 2 }
Line 6,499 ⟶ 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}}==
1,964

edits