我们正在编写一个非常简单的程序,以便在我们为类构建的处理器上执行。它没有乘法或除法的能力。但是,我们支持循环控制的加法,减法和/或分支(如果您熟悉MIPS,则支持相等的分支)。我们认为运行它的一个简洁的程序将是某种x ^ n程序。当然,这些数字必须是硬编码的,但考虑到我们处理器的局限性,这是否现实?
是否只对指数进行了计算? 感谢。
答案 0 :(得分:7)
对于小整数,为什么不呢?
首先,使用重复添加实现乘法。然后,使用重复乘法实现pow()。它会很慢,但它会正常工作。
有一种更快的求幂算法,称为Exponentiation by Squaring。但是,鉴于您没有快速乘法,我不确定它是否值得 - 您可能希望首先尝试实现快速乘法算法。
答案 1 :(得分:6)
符合mazzoni在c风格语法中的回应:
int mulitply(int x, int y)
{
int product;
for (int i = 0; i<y; i++)
product += x;
return product;
}
int power(int x, int exponent)
{
int result = 1;
for (int i = 0; i < exponent; i++)
result = multiply(result, x);
return result;
}
答案 2 :(得分:2)
与Aequitarum的解决方案一样,但是使用重复的平方功率和重复倍增的倍数。大x,y:
应该更快int multiply(int x, int y) {
int product = 0;
int bitmask = 1;
while (y >= bitmask) {
if (y & bitmask) product += x;
x += x;
bitmask += bitmask;
}
return product;
}
int power(int x, int exponent)
{
int result = 1;
int bitmask = 1;
while (exponent >= bitmask) {
if (exponent & bitmask) result = multiply(result, x);
x = multiply(x, x);
bitmask += bitmask;
}
return result;
}
答案 3 :(得分:0)
这很现实。多年前,处理器没有可以进行乘法和除法等高级操作的ALU。
乘法通常使用移位和添加来完成。这是一些伪装配:
; multiply registers a and b
; use c as high b
mov c,#0
; use d as low result
mov d,#0
; use e as high result
mov e,#0
.nextbit:
; shift low bit out of a
shr a
; skip if zero
bcc .noadd
; add b to result
add d,b
adc e,c
.noadd:
; double b
shl b
rcl c
; test a
cmp a,#0
bne .nextbit
(注意,两个字节值相乘的结果是两个字节的值。)
一旦你有一个乘法,你就可以循环计算功率。
使用的说明:
mov x,y = move y into x
shr x = shift right one bit
shl x = shift left one bit
rcl x = rotate left one bit with carry inserted
add x,y = add y to x
adc x,y = add y to x with carry
cmp x,y = compare x to y
bcc = branch on carry clear
bne = branch on not equal
#0 = literal number zero (as opposed to 0, which would be the address zero)
答案 4 :(得分:0)
您可能会发现有关Multiplication ALU的维基百科文章。通过加法和按位运算(和和或),您可以每位一步实现乘法,而不必添加与较小运算符的幅度一样多的次数。
答案 5 :(得分:0)
指数n与k的幂:
exponent(n,k) {
for(x=1..n)
x = x + exponent(x,k-1)
}