怎么用计算机二进制算法数表示53,求具体算法谢谢

小数的&span class='hot-word'&算法&/span&关于那个精确度是什么意思..算到怎样才可停止..谢谢..十转二和二转十都列出来谢谢..例如13.15转二进再转回
关于精确度,题目要求是n位,算到n+1位,结果舍入一位就行。
十进制转二进制:13.15(10),整数部分,用13除以2,商6(余1)再用6除以2,商3(余0),再用3除以2,商1(余1),整数部分的结果就是1101(用竖式除法从下面往上写,第一位是最后小于2的商,其他是每次的余数);小数部分,用0.15乘2,得0.3,再乘,得0.6,再乘,得1.2,用0.2乘2,得0.4,再乘,得0.8,再乘,得1.6,用0.6乘2得1.2,再用0.2乘2~~~小数部分的结果就是0.0010011(从0.3开始整数是0就记0,是1就记1,你用竖式乘法的话就是从上往下写),于是二进制结果就是.
再转回来很简单,整数1101,最高位1乘2的3次方,第二位1乘2的2次方,第三位0,第四位1乘2的0次方,整数部分就是8+4+1=13
小数部分也一样,1乘2的-3次方+1乘2的...
其他答案(共2个回答)
大师莱布尼兹发现
常用于计算机领域
十进制"即满十进一;"位值"则是同一个数位在不同的位置上所表示的数值也就不同,如三位数"111",右边的"1"在个位上表示1个一,中间的"1"在十位上就表示1个十,左边的"1"在百位上则表示1个百
将十进制数的纯小数(不包括乘后所得的整数部分)反复乘以2,直到乘积的小数部分为0或小数点后的位数达到精度要求为止。
所谓小数点后的位数达到精度要求,就是指小数部...
楼上各位说了二进制八进制十进制十六进制的定义.事实上人们日常生活工作中大量接触的是十进制,而计算机技术中使用的电子元件是以通或断来表示计算状态的,所以必须使用二...
二进制就有两个数字,一个是0一个是1
比如:11110
它有5个位,如果用十进制来表示,那就是个位,十位,百位,千位和万位!
但十进制的一个位,能代表前一个位的...
二进制数转换成十进制数
二进制的1101转化成十进制
1101(2)=1*2^0+0*2^1+1*2^2+1*2^3=1+0+4+8=13
二进制数转化为十进制数方法
用(2)表示二进制的数(实际应该是下标),二进制数转化为十进制数
0(2)=0 , 1(2)=1 ,10(2)=2 ,[左边是二进制...
答: 文网文去哪里申请?
答: 慢慢弄。
我最开始只会装游戏;
后来中国有了网络慢慢跟朋友上聊天室聊天;
后来出了OICQ(现在叫QQ),又用那东西聊;
然后上联众玩在线游戏(棋牌类);
答: 七十年代的计算机网络
X.25 分组交换网:各国的电信部门建设运行
各种专用的网络体系结构:SNA,DNA
Internet 的前身ARPANET进行实验运行
大家还关注
确定举报此问题
举报原因(必选):
广告或垃圾信息
激进时政或意识形态话题
不雅词句或人身攻击
侵犯他人隐私
其它违法和不良信息
报告,这不是个问题
报告原因(必选):
这不是个问题
这个问题分类似乎错了
这个不是我熟悉的地区(蟹老板Workshop)
(副刊游侠)
(蟹老板Workshop)
第三方登录:二进制数据的表示与运算(有符号、无符号数数学运算以及Q格式定点精度问题)
二进制数据的表示与运算(有符号、无符号数数学运算以及Q格式定点精度问题)
(转载fromhttp://houh-1984./blog/static//)
数字天地,信号天堂,嵌入式平台,多核技术
21:08:07| 分类:
|字号大中小 订阅
本文介绍了二进制binary数据在存储器的表示方式,C语言的位运算符号,有符号和无符号混合运算的规则,主要是乘法和除法规则不同。最后以IIR滤波器定点实现的例子来说明如何提高计算精度。
二进制数据与补码、原码和反码表示以及位运算
位运算是指二进制位的运算,在系统软件中,经常要处理一些二进制位的问题,如设置标志位,进行标志位的检测,通常见于状态寄存器和控制寄存器的访问,位运算的类型有相与,与非,相或,或非,异或,同或,取反等操作。
C语言的位运算
如果两个相应的二进制位都为1,则该位的结果值为1,否则为0
两个相应的二进制位中只要有一个为1,该位的结果值为1
若参加运算的两个二进制位值相同则为0,否则为1
一元运算符,用来对一个二进制数按位取反,即将0变1,将1变0
用来将一个数的各二进制位全部左移N位 ,右补0
将一个数的各二进制位右移N位,移到右端的低位被舍弃,对于无符号数,高位补0;对于有符号数据,逻辑右移则高位补零,算术右移则高位填充符号位;
二进制的存储表示方法
  计算机中的存储器就是由许多字节(byte)单元组成的。一般,内存的最小度量单位就叫做位(bit),也叫比特。而一个字节就是由8个二进制位组成,其中,最右边的一位叫做最低位LSB,最左边的一位叫做最高位MSB。所以,一个16位的整数将在内存中占据2个字节的存储空间,一个32位的整数类型占据4个字节的存储空间。数据有原码、反码、补码3种表示形式。
  原码是指将最高位作为符号位(0表示正,1表示负),其它数字位代表数值本身的绝对值的数字表示方式。以8比特的数据为例,原码0000
0110表示数字6,而原码1000
0110表示数字-6,其中的第一位为符号位,0表示正数,1表示负数。
  反码表示规则为:如果是正数,则表示方法和原码一样;如果是负数,则保留符号位1,然后将这个数字的原码按照每位取反,则得到这个数字的反码表示形式。同样以8位的系统为例,数字6的反码也就是它的原码:0000
0110,而数字-6的反码为,即为数字6与的按位异或的结果。
  补码  补码是计算机表示数据的一般方式,其规则为:如果是整数,则表示方法和原码一样;如果是负数,则将数字的反码加上1(相当于将原码数值位取反然后在最低位加1)。同样以8位的系统为例,数字6的补码也就是它的原码:0000
0110,而数字-6的补码为1111
1010;有符号数和无符号数运算
需要说明的是,计算机通常的处理都是按照补码数据进行的,以下的所有二进制数据的表示都是补码表示。通常的有符号和无符号数据的说法都源于高级语言如C语言的数据表示形式,对于在内存里的数据补码表示而言,对于同样的二进制码,如8比特的数据1111
1010,它可以是数字-6的补码,也可以是() 1111
1010即+250的补码形式。而把该内存区域的数据读到寄存器里,可以根据数据加载类型来决定是否进行符号扩展还是零扩展,即由具体的加载指令来区分内存数据的类型,当然除了数据加载,对于数据运算而言,也是存在两套的汇编指令来告诉具体的操作类型是有符号的还是无符号的运算,如TI
DSP中常见的ADD和ADDU,MPY和MPYU指令分别针对有符号数据和无符号数据运算的。而高级语言引入的有符号和无符号的表示都是为了引导编译器把代码汇编成正确的汇编指令。
一个引导编译器的C语言例子
str = "abcd";
= (x - strlen(str) ) / 2;
printf("%d/n",y);
结果应该是
-1 但是却得到:。为什么?因为strlen的返回值,类型是size_t,也就是unsigned int,与
int 混合计算时有符号类型被自动转换成了无符号类型,结果为无符号数据,观察编译后的代码,除法指令为
div,意味无符号除法。解决办法就是强制转换,变成 int y = (int)(x - strlen(str) ) / 2;
强制向有符号方向转换(编译器默认正好相反),这样一来,除法指令编译成 idiv 了。
C语言中有符号/无符号数混合运算
操作数全为有符号数,则计算过程中和计算结果全部按照有符号运算;
操作数全为无符号数,则计算过程中和计算结果全部按照无符号运算;
操作数混合了有符号数、无符号数,则操作数中存在至少一个无符号数,则所有操作数都被转化为无符号数,运算操作也采用相应的无符号操作符进行,计算完的结果也是一个无符号数;
(unsigned int)a / (signed int)b
会采用无符号除法进行,其实质相当于(unsigned int)a / (unsigned
int)b,计算结果也是一个无符号数。再进一步,对于运算-2 /
-1,如果采用有符号数运算,结果是1,采用无符号数运算,结果则是0。所以 (signed int)(-2) / (unsigned
int)(-1)的结果就是0了。
汇编有符号和无符号乘法差别
有符号乘法规则:数据的绝对值相乘,符号位异或,如果需要高位扩展符号位则扩展符号位;
无符号乘法规则,按位乘并累加。
以上面的8位的定点数据乘法为例,对于无符号乘法,即为250U*6U=1500U,而-6S*6S=-36S。
00U 01 1100S
IIR滤波器定点算法提高精度(以TI
的DSP为例)
对输入的数据norm后进行乘法,然后再计算乘法,然后累加,如果对于分阶段的,可以对若干个一起求出共同的norm值,然后计算乘法,累加完成后denorm回去。
中间累加结果为40bit,利用40位的累加器,同时还可以考虑SHRMB,SHLMB以及40-bit的SAT指令等;
Reference:
本文介绍了二进制binary数据在存储器的表示方式,C语言的位运算符号,有符号和无符号混合运算的规则,主要是乘法和除法规则不同。最后以IIR滤波器定点实现的例子来说明如何提高计算精度
已投稿到:
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。【转】输入一个整数,求该整数的二进制中有多少位1
我的图书馆
【转】输入一个整数,求该整数的二进制中有多少位1
题目:输入一个整数,求该整数的二进制表达中有多少个1。例如输入10,由于其二进制表示为1010,有两个1,因此输出2。
分析:这是一道很基本的考查位运算的面试题。包括微软在内的很多公司都曾采用过这道题。
一个很基本的想法是,我们先判断整数的最右边一位是不是1。接着把整数右移一位,原来处于右边第二位的数字现在被移到第一位了,再判断是不是1。这样每次移动一位,直到这个整数变成0为止。现在的问题变成怎样判断一个整数的最右边一位是不是1了。很简单,如果它和整数1作与运算。由于1除了最右边一位以外,其他所有位都为0。因此如果与运算的结果为1,表示整数的最右边一位是1,否则是0。
得到的代码如下:
///////////////////////////////////////////////////////////////////////// Get how many 1s in an integer's binary expression///////////////////////////////////////////////////////////////////////int NumberOf1_Solution1(int i){&&&&& int count = 0;&&&&& while(i)&&&&& {&&&&&&&&&&& if(i & 1)&&&&&&&&&&&&&&&&& count ++;&&&&&&&&&&& i = i && 1;&&&&& }&&&&& return}
可能有读者会问,整数右移一位在数学上是和除以2是等价的。那可不可以把上面的代码中的右移运算符换成除以2呢?答案是最好不要换成除法。因为除法的效率比移位运算要低的多,在实际编程中如果可以应尽可能地用移位运算符代替乘除法。
这个思路当输入i是正数时没有问题,但当输入的i是一个负数时,不但不能得到正确的1的个数,还将导致死循环。以负数0x为例,右移一位的时候,并不是简单地把最高位的1移到第二位变成0x,而是0xC0000000。这是因为移位前是个负数,仍然要保证移位后是个负数,因此移位后的最高位会设为1。如果一直做右移运算,最终这个数字就会变成0xFFFFFFFF而陷入死循环。
为了避免死循环,我们可以不右移输入的数字i。首先i和1做与运算,判断i的最低位是不是为1。接着把1左移一位得到2,再和i做与运算,就能判断i的次高位是不是1……这样反复左移,每次都能判断i的其中一位是不是1。基于此,我们得到如下代码:
///////////////////////////////////////////////////////////////////////// Get how many 1s in an integer's binary expression///////////////////////////////////////////////////////////////////////int NumberOf1_Solution2(int i){&&&&& int count = 0;&&&&& unsigned int flag = 1;&&&&& while(flag)&&&&& {&&&&&&&&&&& if(i & flag)&&&&&&&&&&&&&&&&& count ++;&&&&&&&&&&& flag = flag && 1;&&&&& }&&&&& return}
另外一种思路是如果一个整数不为0,那么这个整数至少有一位是1。如果我们把这个整数减去1,那么原来处在整数最右边的1就会变成0,原来在1后面的所有的0都会变成1。其余的所有位将不受到影响。举个例子:一个二进制数1100,从右边数起的第三位是处于最右边的一个1。减去1后,第三位变成0,它后面的两位0变成1,而前面的1保持不变,因此得到结果是1011。
我们发现减1的结果是把从最右边一个1开始的所有位都取反了。这个时候如果我们再把原来的整数和减去1之后的结果做与运算,从原来整数最右边一个1那一位开始所有位都会变成0。如00。也就是说,把一个整数减去1,再和原整数做与运算,会把该整数最右边一个1变成0。那么一个整数的二进制有多少个1,就可以进行多少次这样的操作。
这种思路对应的代码如下:
///////////////////////////////////////////////////////////////////////// Get how many 1s in an integer's binary expression///////////////////////////////////////////////////////////////////////int NumberOf1_Solution3(int i){&&&&& int count = 0;&&&&& while (i)&&&&& {&&&&&&&&&&& ++&&&&&&&&&&& i = (i - 1) &&&&&& }&&&&& return}
扩展:如何用一个语句判断一个整数是不是二的整数次幂?
PS:n&(n-1)==0;//二进制数只有一位位1,则该数是2的整数次幂.
简单查表,相对来说效率也不错。
int countBits(int value){&&&&&& int count=0;&&&&& int bits4[]={0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4};&&&&& while(value!=0){&&&&&&&&&&& count+=bits4[value&0xf];&&&&& value&&=4;&&&&& }&&&&& }
======================================================
这是一道《编程之美-微软技术面试心得》中的题目,问题描述如下:
对于一个字节(8bit)的变量,求其二进制表示中“1”的个数,要求算法的执行效率尽可能地高。
《编程之美》中给出了五种解法,但是实际上从 Wikipedia 上我们可以找到。
这道题的本质相当于求二进制数的 Hamming 权重,或者说是该二进制数与 0 的 Hamming 距离,这两个概念在信息论和编码理论中是相当有名的。在二进制的情况下,它们也经常被叫做 population count 或者 popcount 问题,比如 gcc 中就提供了一个内建函数:
int __builtin_popcount (unsigned int x)
输出整型数二进制中 1 的个数。但是 GCC 的 __builtin_popcount 的实现主要是基于查表法做的,跟编程之美中解法 5 是一样的。
注:我查到的算法是这样的,并非查表,而是Wikipedia 上的方法:
_LIBCPP_ALWAYS_INLINE int __builtin_popcount(unsigned int x) {&& static const unsigned int m1 = 0x; //binary: 0101...&& static const unsigned int m2 = 0x; //binary: ..&& static const unsigned int m4 = 0x0f0f0f0f; //binary:& 4 zeros,& 4 ones ...&& static const unsigned int h01= 0x; //the sum of 256 to the power of 0,1,2,3...&& x -= (x && 1) & m1;&&&&&&&&&&&& //put count of each 2 bits into those 2 bits&& x = (x & m2) + ((x && 2) & m2); //put count of each 4 bits into those 4 bits&& x = (x + (x && 4)) & m4;&&&&&&& //put count of each 8 bits into those 8 bits&& return (x * h01) && 24;& //returns left 8 bits of x + (x&&8) + (x&&16) + (x&&24)}
Wikipedia 上的解法是基于分治法来做的,构造非常巧妙,通过有限次简单地算术运算就能求得结果,特别适合那些受存储空间限制的算法中使用:
/* ===========================================================================* Problem: *&& The fastest way to count how many 1s in a 32-bits integer.** Algorithm:*&& The problem equals to calculate the Hamming weight of a 32-bits integer,*&& or the Hamming distance between a 32-bits integer and 0. In binary cases,*&& it is also called the population count, or popcount.[1]**&& The best solution known are based on adding counts in a tree pattern*&& (divide and conquer). Due to space limit, here is an example for a*&& 8-bits binary number A=]* | Expression&&&&&&&&&&& | Binary&& | Decimal | Comment&&&&&&&&&&&&&&&&&&& |* | A&&&&&&&&&&&&&&&&&&&& |
|&&&&&&&& | the original number&&&&&&& |* | B = A & &&&&& |
| 1,0,1,0 | every other bit from A&&&& |* | C = (A&&1) &
| 0,1,1,0 | remaining bits from A&&&&& |* | D = B + C&&&&&&&&&&&& |
| 1,1,2,0 | # of 1s in each 2-bit of A | * | E = D & &&&&& |
| 1,0&&&& | every other count from D&& |* | F = (D&&2) &
| 1,2&&&& | remaining counts from D&&& |* | G = E + F&&&&&&&&&&&& |
| 2,2&&&& | # of 1s in each 4-bit of A |* | H = G & &&&&& |
| 2&&&&&& | every other count from G&& |* | I = (G&&4) &
| 2&&&&&& | remaining counts from G&&& |* | J = H + I&&&&&&&&&&&& |
| 4&&&&&& | No. of 1s in A&&&&&&&&&&&& |* Hence A have 4 1s.** [1] http://en.wikipedia.org/wiki/Hamming_weight** 这个算法的设计思想用的是二分法,两两一组相加,之后四个四个一组相加,接着八个八个,最后就得到各位之和了。
* 设原整数值为x,* 第一步:把x的32个bit分成16组(第32bit和第31bit一组,第30bit和第29bit一组……以此类推),然后将每一组的两bit上的值(因为是二进制数,所以要么是0要么是1)相加并把结果还放在这两bit的位置上,这样,得到结果整数x1,x1的二进制(32bit)可以分为16组,每一组的数值就是原来整数x在那两bit上1的个数。* 第二步:把第一步得到的结果x1的32bit,分成8组(第32、31、30、29bit一组,第28、27、26、25bit一组……以此类推),然后每一组的四bit上的值相加并把结果还放在这四bit的位置上,这样,又得到结果整数x2,x2的二进制可以分为8组,每一组的数值就是原来整数x在那四bit上的1的个数。* ……* 这样一直分组计算下去,最终,把两个16bit上1的个数相加,得到原来整数x的32bit上1的个数。
===========================================================================*/#include &stdio.h&
typedef unsigned int UINT32;const UINT32 m1& = 0x;& // const UINT32 m2& = 0x;& // const UINT32 m4& = 0x0f0f0f0f;& // const UINT32 m8& = 0x00ff00ff;& // const UINT32 m16 = 0x0000ffff;& // const UINT32 h01 = 0x;& // the sum of 256 to the power of 0, 1, 2, 3
/* This is a naive implementation, shown for comparison, and to help in * understanding the better functions. It uses 20 arithmetic operations* (shift, add, and). */int popcount_1(UINT32 x){& x = (x & m1) + ((x && 1) & m1);& x = (x & m2) + ((x && 2) & m2);& x = (x & m4) + ((x && 4) & m4);& x = (x & m8) + ((x && 8) & m8);& x = (x & m16) + ((x && 16) & m16);& return}
/* This uses fewer arithmetic operations than any other known implementation* on machines with slow multiplication. It uses 15 arithmetic operations. */int popcount_2(UINT32 x){& x -= (x && 1) & m1;&&&&&&&&&&&& //put count of each 2 bits into those 2 bits& x = (x & m2) + ((x && 2) & m2); //put count of each 4 bits into those 4 bits & x = (x + (x && 4)) & m4;&&&&&&& //put count of each 8 bits into those 8 bits & x += x && 8;&&&&&&&&&& //put count of each 16 bits into their lowest 8 bits& x += x && 16;&&&&&&&&& //put count of each 32 bits into their lowest 8 bits& return x & 0x1f;}
/* This uses fewer arithmetic operations than any other known implementation* on machines with fast multiplication. It uses 12 arithmetic operations, * one of which is a multiply. */int popcount_3(UINT32 x){& x -= (x && 1) & m1;&&&&&&&&&&&& //put count of each 2 bits into those 2 bits& x = (x & m2) + ((x && 2) & m2); //put count of each 4 bits into those 4 bits & x = (x + (x && 4)) & m4;&&&&&&& //put count of each 8 bits into those 8 bits & return (x * h01) && 24;& // left 8 bits of x + (x&&8) + (x&&16) + (x&&24)}int main(){& int i = 0x1ff12ee2; & printf("i = %d = 0x%x/n", i, i);& printf("popcount_1(%d) = %d/n", i, popcount_1(i));& printf("popcount_2(%d) = %d/n", i, popcount_2(i));& printf("popcount_3(%d) = %d/n", i, popcount_3(i));& /* If compiled with other compiler than gcc, comment the line bellow. */& printf("GCC's& __builtin_popcount(%d) = %d/n", i,& __builtin_popcount(i));& return 0;}
以上内容来源于
===========================================================
HAKMEM算法:
int Count(unsigned x){&&&&&&
&&& n = (x && 1) & ;&&& &&& x = x -&& &&& n = (n && 1) & ;&& &&& x = x -&&& &&& x = (x + (x && 3)) & ;&& &&& x = modu(x, 63);& &&&&& }&
说明:首先是将二进制各位三个一组,求出每组中1的个数,然后相邻两组归并,得到六个一组的1的个数,最后很巧妙的用除63取余得到了结果。因为2^6 = 64,也就是说 x_0 + x_1 * 64 + x_2 * 64 * 64 = x_0 + x_1 + x_2 (mod 63),这里的等号表示同余。这个程序只需要十条左右指令,而且不访存,速度很快。
本文来自CSDN博客:
TA的最新馆藏[转]&[转]&[转]&[转]&[转]&
喜欢该文的人也喜欢问题描述:
世界上有10种人,一种懂二进制,一种不懂。那么你知道两个int32整数m和n的二进制表达,有多少个位(bit)不同么?
输入例子:
1999 & & 2299
输出例子:
我的代码:
* 求两个数的二进制中不同的位数
* @param m
* @param n
* @return 返回不同的位数的个数
public static int countBitDiff(int m, int n) {
int ans = m^n;
//求ans中1的个数
int count = 0;
while(ans != 0){
ans &= (ans -1);
& & 注意通过这道题学习如何求一个数二进制中1的个数
本文已收录于以下专栏:
相关文章推荐
我们一般的算法是将整数A与整数B转换为二进制数,然后通过移位操作来统计总共有多少位不同,现在我像大家介绍一种更加高效的算法。
int cal(int a, int b)
int M = a ^...
实习生笔试题
问题引入1、二进制表达方式——位运算
2、有多少位不同——好像只能一位一位的取比较
3、如何取得一个数的每一位呢?
4、比较完一位之后,能否把这一位去掉,比较剩下的,然后重复整个...
如题 : 给定俩个十进制的整数,求解对应的二进制不同的位数有几位
测试数据 :
思路 : 使用异或,异或运算相当于没有进位的加法运算,故该位为1表示对应位不同,对异或...
m和n的二进制表达中,有多少个位不同 三种方法
简单的二进制比较计数
解法一:举例说明,为了减少复杂度,就使用八位二进制吧。设 A = , B = .
1. C = A & B = ;
2. D = A | B ...
给定A, B两个整数,不使用除法和取模运算,求A/B的商和余数。
最基本的算法是,从小到大遍历:
for (i = 2 to A -1)
if (i * B > A)...
K-means聚类算法是一种非层次聚类算法,在最小误差的基础上将数据划分了特定的类,类间利用距离作为相似度指标,两个向量之间的距离越小,其相似度就越高。程序读取全国省市经纬度坐标,然后根据经纬度坐标进...
本人最近在研究Radon变换,在查阅了各种资料之后在此写下个人的理解,希望与各位牛牛进行交流共同进步,也使得理解更加深刻些。
Radon变换的本质是将原来的函数做了一个空间转换,即,将原来的XY平...
他的最新文章
讲师:董岩
您举报文章:
举报原因:
原文地址:
原因补充:
(最多只允许输入30个字)

我要回帖

更多关于 二进制转十进制算法 的文章

 

随机推荐