avatar
e*s
2
int add(int x, int y) {
int carry = 0;
int result = 0;
int i;
for(i = 0; i < 32; ++i) {
int a = (x >> i) & 1;
int b = (y >> i) & 1;
result |= ((a ^ b) ^ carry) << i;
carry = (a & b) | (b & carry) | (carry & a);
}
return result;
}
avatar
f*e
3
赞楼上的代码!
avatar
y*g
4
++i不算arithmetic?

【在 e***s 的大作中提到】
: int add(int x, int y) {
: int carry = 0;
: int result = 0;
: int i;
: for(i = 0; i < 32; ++i) {
: int a = (x >> i) & 1;
: int b = (y >> i) & 1;
: result |= ((a ^ b) ^ carry) << i;
: carry = (a & b) | (b & carry) | (carry & a);
: }

avatar
f*e
5
照葫芦画瓢实现了个减法,调用加法,我觉得++不算算术运算符吧,除了+,-.*,/吧
int substract(int x, int y) {
int carry = 0;
int result = 0;
int t = ~y;
t = add(t,1); //t 是y 的相反数
for(int i = 0; i < 32; ++i) {
int a = (x >> i) & 1;
int b = (t >> i) & 1;
result |= ((a ^ b) ^ carry) << i;
carry = (a & b) | (b & carry) | (carry & a);
}
return result;
}
avatar
u*r
6
++i不算的话,你int x + int y直接用++x循环就完了。
avatar
c*p
7
慢。
O(n) VS O(logn)的区别。

【在 u**r 的大作中提到】
: ++i不算的话,你int x + int y直接用++x循环就完了。
avatar
g*i
8
这个复杂度偏高,careercup上有更快的,类似这样吧:
result=x^y;
carry=(x&y)<<1;
while(carry != 0){
temp=result^carry;
carry=(result&carry)<<1;
result=temp;
}

【在 e***s 的大作中提到】
: int add(int x, int y) {
: int carry = 0;
: int result = 0;
: int i;
: for(i = 0; i < 32; ++i) {
: int a = (x >> i) & 1;
: int b = (y >> i) & 1;
: result |= ((a ^ b) ^ carry) << i;
: carry = (a & b) | (b & carry) | (carry & a);
: }

avatar
u*r
9
我的意思是++i应该不能用。

【在 c****p 的大作中提到】
: 慢。
: O(n) VS O(logn)的区别。

avatar
f*e
10
这个更牛啊,长见识了

【在 g*****i 的大作中提到】
: 这个复杂度偏高,careercup上有更快的,类似这样吧:
: result=x^y;
: carry=(x&y)<<1;
: while(carry != 0){
: temp=result^carry;
: carry=(result&carry)<<1;
: result=temp;
: }

avatar
e*s
11
赞! 我的CODE可以歇一边去了

【在 g*****i 的大作中提到】
: 这个复杂度偏高,careercup上有更快的,类似这样吧:
: result=x^y;
: carry=(x&y)<<1;
: while(carry != 0){
: temp=result^carry;
: carry=(result&carry)<<1;
: result=temp;
: }

avatar
e*s
12
照葫芦画瓢,写了个减法的。 请教一下怎么验证result不能大于MAX_INT和小于MIN_
INT
public static int Subtract(int x, int y)
{
int result = x ^ y;
int borrow = (x ^ (x | y)) << 1;
int temp;
while (borrow != 0)
{
temp = result ^ borrow;
borrow = (result ^ (result | borrow)) << 1;
result = temp;
}
return result;
}
avatar
g*i
13
减法实现可以基于加法
sub(int a, int b){
return add(a, add(~b, 1));
}
avatar
e*w
14
我也发个加法:
#include
using namespace std;
int Add(int a, int b) {
return (b ? Add(a ^ b, (a & b) << 1) : a);
}
int main() {
cout << "Add(3, 4) = " << Add(3, 4) << endl;
cout << "Add(3, -8) = " << Add(3, -8) << endl;
cout << "Add(-8, 40) = " << Add(-8, 40) << endl;
}
avatar
e*w
15
加减乘,没用+-*/号。
#include
using namespace std;
int Add(int a, int b) {
return (b ? Add(a ^ b, (a & b) << 1) : a);
}
int Sub(int a, int b) {
return Add(a, Add(~b, 1));
}
int Mul(int a, int b) {
if (b == 0) return 0;
if (b < 0) return Mul(Sub(0, a), Sub(0, b));
return Add(a, Mul(a, Sub(b, 1)));
}
int main() {
cout << "Add(3, 4) = " << Add(3, 4) << endl;
cout << "Add(3, -8) = " << Add(3, -8) << endl;
cout << "Add(-8, 40) = " << Add(-8, 40) << endl;
cout << "Sub(3, 4) = " << Sub(3, 4) << endl;
cout << "Sub(3, -8) = " << Sub(3, -8) << endl;
cout << "Sub(-8, 40) = " << Sub(-8, 40) << endl;
cout << "Mul(3, 4) = " << Mul(3, 4) << endl;
cout << "Mul(3, -8) = " << Mul(3, -8) << endl;
cout << "Mul(-8, 40) = " << Mul(-8, 40) << endl;
}
$ ./a.out
Add(3, 4) = 7
Add(3, -8) = -5
Add(-8, 40) = 32
Sub(3, 4) = -1
Sub(3, -8) = 11
Sub(-8, 40) = -48
Mul(3, 4) = 12
Mul(3, -8) = -24
Mul(-8, 40) = -320
avatar
j*l
16
int Div(int a, int b) {
try{
if (b == 0) {
throw runtime_error("divisor is 0");
}
if( (a>0&&b<0) || (a>0&&b<0) ){
int sign = -1;
if(a<0){
a= Mul(-1,a);
}
if(b<0){
b= Mul(-1,b);
}
return Mul(sign, Div(a,b));
}
if(a<0){
a= Mul(-1,a);
}
if(b<0){
b= Mul(-1,b);
}
return (a}catch (runtime_error err){
cerr<return 0;
}
}
Div(6, 3) = 2
Div(6, -3) = -2
Div(-6, 3) = 2
Div(-6, -3) = 2
Div(0, -3) = 0
Div(0, 3) = 0
divisor is 0
Div(0, 0) = 0
Div(10, 3) = 3
Div(10, -3) = -3
Div(-10, 3) = 3
Div(-10, -3) = 3
avatar
e*s
17
学习了,赞~

【在 e*****w 的大作中提到】
: 加减乘,没用+-*/号。
: #include
: using namespace std;
: int Add(int a, int b) {
: return (b ? Add(a ^ b, (a & b) << 1) : a);
: }
: int Sub(int a, int b) {
: return Add(a, Add(~b, 1));
: }
: int Mul(int a, int b) {

avatar
g*i
18
*/的思路应该是位移运算,每次*2,比用+-快多了
avatar
w*s
19
How to implement + - * / without arithmetic operation?
avatar
e*s
20
int add(int x, int y) {
int carry = 0;
int result = 0;
int i;
for(i = 0; i < 32; ++i) {
int a = (x >> i) & 1;
int b = (y >> i) & 1;
result |= ((a ^ b) ^ carry) << i;
carry = (a & b) | (b & carry) | (carry & a);
}
return result;
}
avatar
f*e
21
赞楼上的代码!
avatar
y*g
22
++i不算arithmetic?

【在 e***s 的大作中提到】
: int add(int x, int y) {
: int carry = 0;
: int result = 0;
: int i;
: for(i = 0; i < 32; ++i) {
: int a = (x >> i) & 1;
: int b = (y >> i) & 1;
: result |= ((a ^ b) ^ carry) << i;
: carry = (a & b) | (b & carry) | (carry & a);
: }

avatar
f*e
23
照葫芦画瓢实现了个减法,调用加法,我觉得++不算算术运算符吧,除了+,-.*,/吧
int substract(int x, int y) {
int carry = 0;
int result = 0;
int t = ~y;
t = add(t,1); //t 是y 的相反数
for(int i = 0; i < 32; ++i) {
int a = (x >> i) & 1;
int b = (t >> i) & 1;
result |= ((a ^ b) ^ carry) << i;
carry = (a & b) | (b & carry) | (carry & a);
}
return result;
}
avatar
u*r
24
++i不算的话,你int x + int y直接用++x循环就完了。
avatar
c*p
25
慢。
O(n) VS O(logn)的区别。

【在 u**r 的大作中提到】
: ++i不算的话,你int x + int y直接用++x循环就完了。
avatar
g*i
26
这个复杂度偏高,careercup上有更快的,类似这样吧:
result=x^y;
carry=(x&y)<<1;
while(carry != 0){
temp=result^carry;
carry=(result&carry)<<1;
result=temp;
}

【在 e***s 的大作中提到】
: int add(int x, int y) {
: int carry = 0;
: int result = 0;
: int i;
: for(i = 0; i < 32; ++i) {
: int a = (x >> i) & 1;
: int b = (y >> i) & 1;
: result |= ((a ^ b) ^ carry) << i;
: carry = (a & b) | (b & carry) | (carry & a);
: }

avatar
u*r
27
我的意思是++i应该不能用。

【在 c****p 的大作中提到】
: 慢。
: O(n) VS O(logn)的区别。

avatar
f*e
28
这个更牛啊,长见识了

【在 g*****i 的大作中提到】
: 这个复杂度偏高,careercup上有更快的,类似这样吧:
: result=x^y;
: carry=(x&y)<<1;
: while(carry != 0){
: temp=result^carry;
: carry=(result&carry)<<1;
: result=temp;
: }

avatar
e*s
29
赞! 我的CODE可以歇一边去了

【在 g*****i 的大作中提到】
: 这个复杂度偏高,careercup上有更快的,类似这样吧:
: result=x^y;
: carry=(x&y)<<1;
: while(carry != 0){
: temp=result^carry;
: carry=(result&carry)<<1;
: result=temp;
: }

avatar
e*s
30
照葫芦画瓢,写了个减法的。 请教一下怎么验证result不能大于MAX_INT和小于MIN_
INT
public static int Subtract(int x, int y)
{
int result = x ^ y;
int borrow = (x ^ (x | y)) << 1;
int temp;
while (borrow != 0)
{
temp = result ^ borrow;
borrow = (result ^ (result | borrow)) << 1;
result = temp;
}
return result;
}
avatar
g*i
31
减法实现可以基于加法
sub(int a, int b){
return add(a, add(~b, 1));
}
avatar
e*w
32
我也发个加法:
#include
using namespace std;
int Add(int a, int b) {
return (b ? Add(a ^ b, (a & b) << 1) : a);
}
int main() {
cout << "Add(3, 4) = " << Add(3, 4) << endl;
cout << "Add(3, -8) = " << Add(3, -8) << endl;
cout << "Add(-8, 40) = " << Add(-8, 40) << endl;
}
avatar
e*w
33
加减乘,没用+-*/号。
#include
using namespace std;
int Add(int a, int b) {
return (b ? Add(a ^ b, (a & b) << 1) : a);
}
int Sub(int a, int b) {
return Add(a, Add(~b, 1));
}
int Mul(int a, int b) {
if (b == 0) return 0;
if (b < 0) return Mul(Sub(0, a), Sub(0, b));
return Add(a, Mul(a, Sub(b, 1)));
}
int main() {
cout << "Add(3, 4) = " << Add(3, 4) << endl;
cout << "Add(3, -8) = " << Add(3, -8) << endl;
cout << "Add(-8, 40) = " << Add(-8, 40) << endl;
cout << "Sub(3, 4) = " << Sub(3, 4) << endl;
cout << "Sub(3, -8) = " << Sub(3, -8) << endl;
cout << "Sub(-8, 40) = " << Sub(-8, 40) << endl;
cout << "Mul(3, 4) = " << Mul(3, 4) << endl;
cout << "Mul(3, -8) = " << Mul(3, -8) << endl;
cout << "Mul(-8, 40) = " << Mul(-8, 40) << endl;
}
$ ./a.out
Add(3, 4) = 7
Add(3, -8) = -5
Add(-8, 40) = 32
Sub(3, 4) = -1
Sub(3, -8) = 11
Sub(-8, 40) = -48
Mul(3, 4) = 12
Mul(3, -8) = -24
Mul(-8, 40) = -320
avatar
j*l
34
int Div(int a, int b) {
try{
if (b == 0) {
throw runtime_error("divisor is 0");
}
if( (a>0&&b<0) || (a>0&&b<0) ){
int sign = -1;
if(a<0){
a= Mul(-1,a);
}
if(b<0){
b= Mul(-1,b);
}
return Mul(sign, Div(a,b));
}
if(a<0){
a= Mul(-1,a);
}
if(b<0){
b= Mul(-1,b);
}
return (a}catch (runtime_error err){
cerr<return 0;
}
}
Div(6, 3) = 2
Div(6, -3) = -2
Div(-6, 3) = 2
Div(-6, -3) = 2
Div(0, -3) = 0
Div(0, 3) = 0
divisor is 0
Div(0, 0) = 0
Div(10, 3) = 3
Div(10, -3) = -3
Div(-10, 3) = 3
Div(-10, -3) = 3
avatar
e*s
35
学习了,赞~

【在 e*****w 的大作中提到】
: 加减乘,没用+-*/号。
: #include
: using namespace std;
: int Add(int a, int b) {
: return (b ? Add(a ^ b, (a & b) << 1) : a);
: }
: int Sub(int a, int b) {
: return Add(a, Add(~b, 1));
: }
: int Mul(int a, int b) {

avatar
g*i
36
*/的思路应该是位移运算,每次*2,比用+-快多了
avatar
e*s
37
按照guangyi的提示写了一个MUL的, 应该是比一个一个加起来快一点
public static int mul(int a, int b)
{
int result = 0;
bool neg = false;
if (b < 0)
{
neg = true;
b = add(~b, 1);
}
if (b == 0)
return 0;
while (b > 1)
{
if ((b & 1) == 1)
result = add(result, a);
b >>= 1;
a <<= 1;
}
result = add(result, a);
if (neg)
return result = add(~result, 1);
else
return result;
}

【在 g*****i 的大作中提到】
: */的思路应该是位移运算,每次*2,比用+-快多了
avatar
e*s
38
@guangyi, 请教DIV的移位方法的CODE。
相关阅读
logo
联系我们隐私协议©2024 redian.news
Redian新闻
Redian.news刊载任何文章,不代表同意其说法或描述,仅为提供更多信息,也不构成任何建议。文章信息的合法性及真实性由其作者负责,与Redian.news及其运营公司无关。欢迎投稿,如发现稿件侵权,或作者不愿在本网发表文章,请版权拥有者通知本网处理。