位运算求解两个数的平均值

1. 给定两个数x和y,朴素算法求解两个数的平均值是(x+y)/2,但是这种方法有个问题就是当x和y的和溢出的时候得到的平均值是错误的,我们可以采用位运算来解决这个问题。

    一般对于x和y不大的时候,利用(x+y) >> 1可以得到两个数的平均值

    对于一个数a,a << n表示的是a*2^n;a >> n表示的是a/2^n

2. x和y的平均值可以用以下公式求:(x&y)+((x^y)>>1)

   (x&y)表示的是取出x和y二进制中都为1的数,例如两个数的二进制都为110010&011010,则结果为010010。因为要求平均值则两个位都是1则只要加一个1即可

   (x^y)表示的是x和y表示的异或值,只有两个不同的时候才为1,例如110010^011010为101000。因为要求两个数平均值则这边还要除2直接右移一位即可,即为(x^y)>>1

   

例如

int x = 2147483647;

int y = 2147483647;

cout <<((x+y)>>1)<<endl; //输出的结果为-1

cout<<(x&y)+((x^y)>>1)<<endl; //输出的结果为2147483647

解释一下产生(x+y)>> 1产生-1的情况

(1)int的范围是[-2147483648, 2147483647],当x为最大值的时候,x+1直接到-2147483648 

         则x+y则等于-2

(2)x+y = -2除以2的结果是-1

(3)利用位运算则不存在溢出的情况

时间: 2024-10-25 06:34:13

位运算求解两个数的平均值的相关文章

编程语言-c#实现两个相差一千位以内的整数相加,写出这样一个方法并测试两个相差一百位以上的两个数,输出结果。

问题描述 c#实现两个相差一千位以内的整数相加,写出这样一个方法并测试两个相差一百位以上的两个数,输出结果. (如:111111111111111111111111111110 + 8 ) 解决方案 如果是.NET 4.0(VS2010),不需要写什么方法,直接调用BigIntegerhttps://msdn.microsoft.com/zh-cn/library/system.numerics.biginteger.aspx 解决方案二: 2000位的整数也不在话下,加减乘除都能做.

编程-通过位运算把一个数的最高位设成所有位怎么做?

问题描述 通过位运算把一个数的最高位设成所有位怎么做? copyMSB - set all bits of result to most significant bit of x. Examples: copyMSB(0x80000000) = 0xFFFFFFFF copyMSB(0x70000000) = 0x00000000 Legal ops: ! ~ & ^ | + << >> Max ops: 5 不能用if-else. 解决方案 unsigned int co

位运算求解一个整数的二进制中1的个数

法一: #include<iostream> #include<algorithm> using namespace std; int Count(int x){ int ans = 0; while(x != 0){ ++ans; x = x&(x-1); } return ans; } int main(){ cout<<Count(9999)<<endl; return 0; } 输出结果:8 分析如下: 1. Count函数用来计算某个数x的

C语言学习教程第八章-枚举、位运算(3)

位运算 前面介绍的各种运算都是以字节作为最基本位进行的. 但在很多系统程序中常要求在位(bit)一级进行运算或处理.C语言提供了位运算的功能, 这使得C语言也能像汇编语言一样用来编写系统程序.一.位运算符C语言提供了六种位运算符:& 按位与| 按位或^ 按位异或~ 取反<< 左移>> 右移 1. 按位与运算 按位与运算符"&"是双目运算符.其功能是参与运算的两数各对应的二进位相与.只有对应的两个二进位均为1时,结果位才为1 ,否则为0.参与运算的

Java I/O : Bit Operation 位运算

一.Bit与二进制 什么是Bit(位)呢?位是CPU处理或者数据存储最小的单元.类似于很小很小的开关,一开一关,表示为1或者0.所以,这就是计算机处理任何数据的"细胞",要谨记. 而二进制,只是计算界一种规范和约定,准确的说是一种数制.念叨着"逢二进一",这其实是一种算法.如图 二.位运算 说完了前面两点,泥瓦匠带你走向位运算的概念.数在内存中以二进制存储.位运算,也就是二进制运算,其实就是对数在内存的二进制直接操作的过程.这里有人发问了, Q:都是1+1,位运算不

C位运算

C位运算 在很多系统程序中常要求在位(bit)一级进行运算或处理.C语言提供了位运算的功能,这使得C语言也能像汇编语言一样用来编写系统程序. 12.1       位运算符C语言提供了六种位运算符:     &          按位与     |          按位或     ^          按位异或     ~          取反     <<         左移     >>         右移 12.1.1            按位与运算    

c语言中用位运算实现加法技巧介绍_C 语言

用位运算实现加法也就是计算机用二进制进行运算,32位的CPU只能表示32位内的数,这里先用1位数的加法来进行,在不考虑进位的基础上,如下 复制代码 代码如下: 1 + 1 = 0 1 + 0 = 1 0 + 1 = 1 0 + 0 = 0 很明显这几个表达式可以用位运算的"^"来代替,如下 复制代码 代码如下: 1 ^ 1 = 0 1 ^ 0 = 1 0 ^ 1 = 1 0 ^ 0 = 0 这样我们就完成了简单的一位数加法,那么要进行二位的加法,这个方法可行不可行呢?肯定是不行的,矛盾

C语言 位运算详解及示例代码_C 语言

所谓位运算,就是对一个比特(Bit)位进行操作.在<二进制思想以及数据的存储>一节中讲到,比特(Bit)是一个电子元器件,8个比特构成一个字节(Byte),它已经是粒度最小的可操作单元了. C语言提供了六种位运算符: 运算符 & | ^ ~ << >> 说明 按位与 按位或 按位异或 取反 左移 右移 按位与运算(&) 一个比特(Bit)位只有 0 和 1 两个取值,只有参与&运算的两个位都为 1 时,结果才为 1,否则为 0.例如1&1

java中&amp;amp;和&amp;amp;&amp;amp;的区别 位运算

1.1. 逻辑与的运算符功能 1.1.1. 测试&& public static void main(String[] args) { int x=5; if (x==6 && saySpringok()) { } } private static boolean saySpringok() { System.out.println("saySpringok"); return false; } 没有输出:因为用的&& 第一个不满足条件则