3

能否用你所熟悉的开发语言,实现基础四则运算?

 11 months ago
source link: https://www.v2ex.com/t/947774
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

V2EX  ›  程序员

能否用你所熟悉的开发语言,实现基础四则运算?

  ellermister · 3 小时 24 分钟前 · 481 次点击

突然想到,这种有没有好的思路实现啊 ?

10 条回复    2023-06-11 20:43:46 +08:00

fengjianxinghun      3 小时 0 分钟前   1

eval("1+2")

Mohanson      2 小时 46 分钟前

先实现半加器, 再使用半加器实现全加器, 这样你就实现了加法.有了加法就有了减法.有了加法就有了乘法.有了加, 减, 乘就能实现除法.

2113ic      2 小时 1 分钟前

@ellermister new function('exp', 'return exp')😂

vituralfuture      1 小时 21 分钟前

转补码,用逻辑运算实现一个全加器,然后级联做成 32 位全加器,这样就有了做加减法的能力,乘除法同理,计算出的结果可以转回原码再求出真值

不过如何实现真值到原码到补码?很简单,利用按位逻辑运算,比如 C++中,一条语句`x=1;`,那么 x 就对应内存中一个存储位置,可以用按位逻辑运算取出每一位,然而非常巧的是,内存中的数值是以补码形式存储的,所以就能够取出补码每一位,也就是说不需要求补码,补码已经躺在内存里了

我写了一个程序来简单说明,只有循环用到了加法`i++`,但是所有循环的次数都是确定的,也就是说**循环可以展开,替换成循环体重复 32 次,相当于没有使用加法**
```
#include <iostream>

using namespace std;


void getComplementCode(bool arr[32], int num) {
int mask = 1;
for (int i = 0; i < 32; i++) {
arr[i] = num & mask;
num = num >> 1;
}
}

int getTrueValue(const bool arr[32]){
int s = 0;
for (int i = 0; i < 32; i++) {
s = s | (arr[i] << i);
}
return s;
}

void add1(bool a, bool b, bool &s, bool c0, bool &c1) {
s = a ^ b ^ c0;
c1 = (a && b) || ((a ^ b) && c0);
}

void add32(bool a[32], bool b[32], bool s[32], bool c = false) {
bool carray[32];
add1(a[0], b[0], s[0], c, carray[0]);
for (int i = 1; i < 32; i++) {
add1(a[i], b[i], s[i], carray[i-1], carray[i]);
}
}

void getTwoComplement(bool arr[32]){
for(int i=0;i<32;i++){
arr[i] = ! arr[i];
}
bool temp[32];
bool one[32];
one[0] = true;
for(int i=1;i<32;i++){
one[i] = false;
}
add32(arr, one, temp);
for(int i=0;i<32;i++){
arr[i] = temp[i];
}
}

int add(int a, int b){
bool A[32], B[32], S[32];
getComplementCode(A, a);
getComplementCode(B, b);
add32(A, B, S);
return getTrueValue(S);
}

int sub(int a, int b){
bool A[32], B[32], S[32];
getComplementCode(A, a);
getComplementCode(B, b);
getTwoComplement(B);
add32(A, B, S);
return getTrueValue(S);
}


int main() {
cout << add(10, 5) << endl;
return 0;
}
```

乘法的话,32 位加 32 位结果是 64 位的,按照这个方式也能够实现

我写的了一个测试用例如下
```
BOOST_AUTO_TEST_CASE(addTest1){
const int times = 10000;
int a = (int)random();
int b = (int)random();
BOOST_TEST(a + b == add(a, b));
}
```
测试通过

LCdHZww.png



除法和浮点数运算,计组课上没讲,不知道具体怎么做,不过道理都是相同的,模拟机器运算,把 C++写成 verilog


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK