算法学习(6)----不用 + - × ÷ 做加法运算

  今天网上看到一个神算法,惊异不已,遂摘录于下:

原文地址:http://blog.csdn.net/sanniao/article/details/47106713

第一步不考虑进位,对每一位相加。0加0与 1加1的结果都0,0加1与1加0的结果都是1。我们可以注意到,这和异或的结果是一样的。对异或而言,0和0、1和1异或的结果是0,而0和1、1和0的异或结果是1。接着考虑第二步进位,对0加0、0加1、1加0而言,都不会产生进位,只有1加1时,会向前产生一个进位。此时我们可以想象成是两个数先做位与运算,然后再向左移动一位。只有两个数都是1的时候,位与得到的结果是1,其余都是0。第三步把前两个步骤的结果相加。如果我们定义一个函数AddWithoutArithmetic,第三步就相当于输入前两步骤的结果来递归调用自己。

有了这些分析之后,就不难写出如下的代码了:

int AddWithoutArithmetic(int num1, int num2)

{

if(num2 == 0)

return num1;

int sum = num1 ^ num2;

int carry = (num1 & num2) << 1;

return AddWithoutArithmetic(sum, carry);

}

后面网友给出了另外一种巧妙方法,利用地址偏移实现加法,代码如下:

int add(int a,int b){
    char * c;
    c = (char *) a;
    return &c[b];
}

着实令我感叹的是第二个算法,解析如下:

  对于一个数组 int arrInt[], arrInt[i]等同于 *(arrInt+i); 因为一个 int 型变量占用4个字节,所以 arrInt+i 在数值上等同于 arrInt+4*i;因此,为了达到实际想要的 arrInt+i 的效果,可以使用 char 型数组 char arrChar[], 这样 arrChar[i] 就等同于 *(arrChar+i) ,而且 arrChar+i 就是 arrChar+i。

  这个巧妙算法正是利用了这种思想,先把 int 型的 a 强制转换为 char 型指针 c, 那么 c[b] 就等同于 *(c+b) ,也就是*(a+b),然后用取地址运算符 & 去掉 * 的作用,所以 &c[b] 就等同于 (c+b),也就是 a+b 了。

时间: 2024-10-11 01:38:09

算法学习(6)----不用 + - × ÷ 做加法运算的相关文章

图解算法:单向链表做加法运算

问:给出两个非空的链表,来表示两个非负的整数.其中,它们各自的位数是按照逆序的方式存储的,并且每个结点只能存储一位数字.将这两个链表相加起来,返回一个新的链表,表示他们之和. 例如:342 + 465 = 807 两数相加这道题,处理的就是最简单的数学加法运算,只是它是建立在链表的基础之上,所以难度在于对链表的处理. 加法运算,除了每一位的加法之外,还需要考虑进位的情况.针对这道题来说,链表的每一个结点存储一位数字,并且是基于自然数字逆序存储,也就是链头到链尾保持低到高位的顺序,这样就等于,进位

如果系统要使用超大整数(超过long长度范围),请你设计一个数据结构来存储这种超大型数字以及设计一种算法来实现超大整数加法运算

package interview_10_10; import org.junit.Test; public class T1 { /** * 如果系统要使用超大整数(超过long长度范围),请你设计一个数据结构来存储这种超大型数字以及设计一种算法来实现超大整数加法运算). */ @Test public void test1() { String number1 = "4324328732789"; String number2 = "2383244324324325898

通过按钮做加法运算

1 package su; 2 3 import java.awt.GridLayout; 4 import java.awt.event.ActionEvent; 5 import java.awt.event.ActionListener; 6 7 import javax.swing.JButton; 8 import javax.swing.JFrame; 9 import javax.swing.JLabel; 10 import javax.swing.JPanel; 11 impo

(笔试题)只用逻辑运算实现加法运算

题目: 如题所示 思路: 逻辑运算,即二进制运算,无外乎与&.或|.非~.异或^以及移位>>,<<等操作: 而加法运算,在十进制中,只有按位相加以及进位两个操作. 从二进制角度也一样,就是bit位相加,加上相应的进位. 1.bit位相加,通过逻辑运算的异或操作可以实现,如0+1=1,1+0=1,0+0=0: 2.进位运算,通过逻辑运算的与操作可以实现,如1+1=1,因为进位是往高位+1,因此需要将进位结果左移一位. 将上述两个操作再做加法运算,就是加法运算的结果,这是一个递

【 c语言中无符号和有符号的加法运算】【深入理解】--【sky原创】

原文:[ c语言中无符号和有符号的加法运算][深入理解]--[sky原创] 第一题 #include<stdio.h> int main() { unsigned int a=6; int b=-20; printf("%d\n",a+b); (a+b)>6? puts(">6"):puts("<=6"); return 0; } 答案是:>6 第二题 #include<stdio.h> int m

【Simple Java】面试问题-使用Java线程做数学运算

这是一个展示如何使用join()方法的例子. 问题: 使用Java多线程计算表达式1*2/(1+2)的值. 解决方案: 使用一个线程做加法运算,另一个线程做乘法运算,还有一个主线程main做除法运算.由于线程之间不需要通讯,所以我们只需要考虑线程的执行顺序. 在main线程中,我们让加法运算线程和乘法运算线程join到主线程,join()方法的作用是使main方法等待,直到调用join的线程执行完毕.在这个例子中,我们希望加法运算线程和乘法运算线程先结束,然后在计算除法运算. package s

编程算法 - 不用加减乘除做加法 代码(C)

不用加减乘除做加法 代码(C) 本文地址: http://blog.csdn.net/caroline_wendy 题目: 写一个函数, 求两个整数之和, 要求在函数体内不得使用+, -, *, /四则运算符号. 不能使用运算符号, 使用位运算, 第一步异或运算选位, 第二步与运算进位. 代码: /* * main.cpp * * Created on: 2014.7.13 * Author: Spike */ #include <iostream> #include <list>

一道算法题-不用加减乘除做加法

题目: 写一个函数,求两个整数之和,要求在函数体内不得使用+.-.*./四则运算符号. 解析①: 首先看十进制是如何做的: 5+7=12,三步走 第一步:相加各位的值,不算进位,得到2. 第二步:计算进位值,得到10. 如果这一步的进位值为0,那么第一步得到的值就是最终结果. 第三步:重复上述两步,只是相加的值变成上述两步的得到的结果2和10,得到12. 同样我们可以用三步走的方式计算二进制值相加: 5-101,7-111 第一步:相加各位的值,不算进位,得到010,二进制每位相加就相当于各位做

不用+、-、&#215;、&#247;数字运算符做加法

1)使用位运算,sum1=a^b 相当于不进位的加法,因为0+1=1.1+0=1.1+1=0(因为不进位)0+0=0 正好是或运算 2)sum2=(a&b)<<1,相当于算进位的数,因为只有1+1时进位 3)结果就是sum1+sum2,当然如果这个加法还需要进位就执行第四步 4)重复上面的过程一直到进位数(a&b)<<1为零,也就是不需要进位为止 #include<iostream> #include<stdio.h> using names