-
2021-07-21 05:31:49
虽然很早就接触了二进制,却一直没有正视这个问题,阅读《计算机科学导论》的时候,基本上是跳过了这一部分,总是以“这么基础的东西,反正工作中基本用不上”的理由给搪塞过去。最近正在阅读《编码》和《程序员的数学思维修炼》,心想终究还是得面对的,于是记录了一点笔记,希望不再回避letcode上关于二进制计算的题目。
10对于我们来讲是一个很平常但又十分神奇的数字。根据《编码》上面的解释,人类的双手非常适合数数,因而我们早已经适应了以10为基础的数字系统。也正是这个习惯,让我在刚接触二进制的时候,感到无比困惑,明明十分简单的概念,却始终不得要领。
十进制中以0-9这十个数码进行组合来表示数字,且赋予10的整数次幂重大的意义:十,百,千,万,亿...
那么,什么是二进制呢?
1. 概念
二进制就是使用0和1这两个数码进行组合来表示数字的一种计数方法。
计算机使用二进制的主要优点有:
技术实现简单,计算机的逻辑电路只需要表示两个状态(电路的断开与连接),使用1和0表示就够了;如果使用十进制,则只能依靠电压的高低进行区分,这无疑会大大增加技术实现的难度
运算规则简单,二进制的运算规则比十进制少了很多(不需要在文具盒上背诵加法表乘法表了),规则少意味着能够简化计算机的内容结构
适合逻辑运算,计算机不仅需要进行算术运算,还需要进行逻辑元素,二进制只有两个数码,恰好与逻辑代数中的真和假完全吻合!
2. 算术运算
2.1. 四则预算
2.1.1. 加
逢二进一
跟十进制的加法一样,只是进位从10变成了2,这是第一个需要认清的问题
// 加法表
0 + 0 = 0;
1 + 0 = 0;
0 + 1 = 1;
1 + 1 = 1; // 进位1
比如计算111 + 101,从右往左利用基本规则进行计算
第一位(从右往左的顺序)1 + 1 = 0;,进位1,
第二位原本是1 + 0,由于进位变成了1 + 1 = 0,继续进位1,
第三位原本是1 + 1 = 0并进位1,由于进位继续计算0 + 1 = 1,未再次进位
最后结果1100
好吧,我放弃用语言描述这个过程了,老老实实拿笔在纸上算两次就好了,实际上跟十进制没有任何区别,只是需要背诵的加法表缩短为仅仅四条了(考虑到加法交换率,实际上只有3条)!
2.1.2. 减
借一当二
// 减法表
0 - 0 = 0;
1 - 1 = 0;
1 - 0 = 1;
0 - 1 = 1; // 借位为1
比如计算111 - 101,最后结果10
2.1.3. 乘
与十进制相比(九九八十一种),二进制的乘法要简单得多(只有四种),只有1 * 1 = 1,其余全为0
// 乘法表
0 * 0 = 0;
0 * 1 = 0;
1 * 0 = 0;
1 * 1 = 1;
运算过程也与十进制类似,用第二个乘数的每位依次乘以第一个乘数,最后运用加法规则将结果相加,就得到了两个二进制数的乘积,可以理解为:“0乘以任何数都等于0,而1乘以任意数都等于乘数本身”。
乘法实际上可以看作是加法与移位的操作,如111 * 101可转换为111 + 0000 + 11100 = 100011。
2.1.4. 除
// 除法表
0 / 0 = 0; // 无意义
1 / 0 = 0; // 无意义
0 / 1 = 0;
1 / 1 = 1;
除法可以使用试商法进行,先从被除数的最高位开始,将被除数(或中间余数)与除数相比较,若被除数(或中间余数)大于除数,则用被除数(或中间余数)减去除数,商为1,并得相减之后的中间余数,否则商为0。再将被除数的下一位移下补充到中间余数的末位,重复以上过程,就可得到所要求的各位商数和最终的余数。
除法实际上可以看作减法和移位的操作。如:111/101 = 1 余 10。
2.2. 与十进制的转换
2.3. 二进制转十进制
虽然只有0和1两个数码,但是在位置化数字系统中,数码所处的位置不同(位置被称为权),其代表的实际数据大小也不相同。如1101,在二进制中:
第一个1表示1的个数
第二个0表示2的个数
第三个1表示4的个数
第四个1表示8的个数
好吧,实际上这儿又被带进坑了。更准确的说法是2的0次幂,2的1次幂,2的2次幂,2的3次幂的个数,只是2的2次幂用十进制表示是4,2的3次方幂用十进制表示是8罢了。
可见,只需要计算1*1 + 2*0 + 4*1 + 8*1,就可以二进制转换成十进制的数字了,结果显而易见13。其他二进制转十进制同理。
实际上这种转换方式并不是二进制独有的,其他进制转10进制也可以采用同样的方法,只需要将基数2转换成对应进制的基数就行了。
2.4. 十进制转二进制
十进制转二进制看起来要麻烦一点,通常采用“除2取余,逆序排序的方法”。比如将数字23转换为二进制表示的过程可如下表示:
23/2 = 11...1
11/2 = 5...1
5/2 = 2...1
2/2 = 1...0
最后结果逆序排序表示为1,0,1,1,1,所以23的二进制表示为10111;
上述过程用代码展示应该要清晰一些
function ten2bin(n){
if (n == 0){
return 0;
}
var res = "";
while(n){
res = n%2 + res;
n = Math.floor(n/2);
}
return res;
}
3. 逻辑运算
计算机不仅执行算术运算,也可以执行逻辑运算。在逻辑代数中,只有真和假两种逻辑值,这跟二进制中的仅有的两个数码1和0完全吻合。下面整理了关于逻辑运算的一些东西
3.1. 基本逻辑运算
逻辑运算中,"与"、"或"、"非"是三种最基本的运算规则。
3.1.1. 与
使用&&表示与运算,参与运算的所有逻辑代数必须全部为真,整个结果才为真。
在电路中表示就是:所有串联的开关必须全部闭合,灯泡才会通电。
1&& 1 = 1
1&& 0 = 0
0&& 1 = 0
0&& 0 = 0
发现没,"与"规则表跟二进制算术运算中的乘法是一模一样的哦!
3.1.2. 或
使用||表示或运算,参与运算的所有逻辑代数只要有一个为真,整个结果就为真。
在电路中表示就是:所有并联的开关只要有一个闭合,灯泡就会通电。
1|| 0 = 1
1|| 1 = 1
0|| 1 = 1
0|| 0 = 0
同样地,"或"运算规则表跟二进制算术运算中的加法基本一样(逻辑运算中不存在进位的说法)。
3.1.3. 非
使用!表示非运算,整个逻辑表达式的结果与逻辑代数相反
在电路中表示就是:如果开关闭合,则灯泡被短路;开关断开,灯泡通电
!1 = 0
!0 = 1
3.2. 复杂逻辑运算
"与"、"或"、"非"是三种最基本的运算规则,其他复杂的逻辑运算都可以用基本运算组合而成。
与非,运算中所有的逻辑代数都为真,则结果为假,!(a && b && c)
或非,运算中只要有一个逻辑代数为真,则结果为假,!(a || b || c)
异或,运算中的两个逻辑代数,有一个为真且另一个为假时,则结果为真,(a&&!b) || (!a && b)
同或,运算中的两个逻辑代数,都为真或者都为假时,则结果为真,(a && b) || (!a && !b)
4. 位运算
大部分高级编程语言都提供了按位操作数字的功能。这一点似乎有些不合理,在日常生活中的计算都是按照某个数字具体代表的值来进行计算的。但是在计算机中,操作数字的某个特定位是很有意义的。下面我们来学习位运算。
4.1. 位逻辑运算符
位逻辑运算符与逻辑运算符有很大的区别:
位逻辑运算符只操作位(位上的数码只可能是0或者1)
逻辑运算符操作的是真或者假,这是由整个变量的值所决定的
4.1.1. 位反
按位取反也叫做二进制反码,使用~表示,指将操作数全部位中的1变成0,将每个0变成1
~1011)
=0100
按位取反有个小技巧:a取反加一,再取反加一,还等于a 。更通俗一点将,如果操作数为-1,则按位取反结果为0。
这一点很有用处,很多接口都使用-1来表示程序未返回预期结果,比如JavaScript中的indexOf(),此时可以使用~idx来判断,比起idx === -1要好不少(看起来)。
4.1.2. 位与
二进制运算符与&通过对两个操作数逐位进行比较,对于每个位置,只有对应的位都为1时,结果对应位置的值才为1,否则为0
1010
& 1100
= 1000
位于通常用来实现掩码。
4.1.3. 位或
二进制运算符或|通过对两个操作数逐位进行比较,对于每个位置,只要任意一个操作数对应位为1时,结果对应位置的值就为1,否则为0
1010
& 1100
= 1110
4.1.4. 位异或
二进制运算符异或^通过对两个操作数逐位进行比较,对于每个位置,只要任意一个操作数对应位为1时,另一个位置为0,结果对应位置的值就为1。
1010
^ 1100
= 0110
4.2. 移位运算符
移位运算符将位向左或向右移动。了解移位运算应当首先了解整数的存储形式,在C语言中,一个int类型的整数占4个字节,而通常一个字节包括8个位,即一个整数包含32位。移位运算就是移动整个操作数在32个位中的位置。
二进制中的移位运算类似于十进制中的移动小数点的操作,从而快速进行乘除法。
4.2.1. 左移运算符
左移运算符<
1010 << 2
= 101000
在不溢出的情况下,左移n位会将操作数扩大2^n倍。
4.2.2. 右移运算符
右移运算符将其左侧操作数的值的每位向右移动,并丢弃移出左侧操作数右端的数(肯定会移出的)
1010 >> 1
= 101
5. 八进制与十六进制
使用二进制存储数据带来的问题是:二进制数字的位数增长十分迅速,保存一个不是很大的数字就需要很长的位数。可见二进制并不适合在计算机外部保存数字,因此产生了八进制和十六进制
5.1. 八进制
八进制使用0~7这八个数码来表示数字,由于2^3 = 8,因此二进制和八进制的转换十分方便。
从二进制转八进制,只需要从右往将三个二进制分为一组(最左不足可用0填充),然后计算为对应的八进制数码,最后将结果拼接在一起就可以了。比如101110:
将整个数字分为101和110
101计算结果为2^2 + 1 = 5,110计算结果为2^2 + 2^1 = 6
所以101110用八进制表示为56
同理,从八进制转二进制也十分简单,将八进制数字每位拆分成一个三个为二进制数(不足用0填充),然后将结果拼接在一起,比如76用二进制表示为111110,过程这里就不详细写了。
5.2. 十六进制
十六进制使用0~9加A~F这十六个数码来表示数字。由于2^4 = 16,加之有了八进制与二进制的相互转换规律,十六进制与二进制的相互转换就轻而易举了,无非是将二进制数按4个一组进行划分,或者将一个十六进制数码转换成4位二进制数
F2二进制表示为11110010
101101十六进制表示为2D
6. 小结
关于二进制的运算先到这里了,另外还有浮点数等知识,先留个坑了。
更多相关内容 -
二进制数的反码和补码
2019-01-16 22:12:54在大学的学习中,一开始自认为已经学会了反码与补码,但在看到多种表述之后,...首先从最一般的意义上,分别说一下二进制的反码和补码: 1、反码 1’s complement 把所有的0变为1,所有的1变为0。 如: 10110010 B...在大学的学习中,一开始自认为已经学会了反码与补码,但在看到多种表述之后,反而是越来越乱,疑惑越来越多,即使记住了之后又会混淆,今天又看到了一次,为了防止以后再次忘记,写这篇博客记录一下(记录过程依据《数字电子技术(第十版)》,中英文结合)
首先从最一般的意义上,分别说一下二进制的反码和补码:1、反码 (1’s complement)
把所有的0变为1,所有的1变为0。
如:
10110010 Binary number
01001101 1’s complement2、补码 (2’s complement)
在反码的最低有效位上加1。
补码 = 反码 + 1
另一种求补码的方法:- 从右边的最低有效位开始,往左边写下它们实际的位,直到遇到第一个1(包括1)
- 左边剩下的位求反码
如:
1011 1000 Binary number
0100 1000 2’s complement这是在不区分正负数的情况下泛泛而谈的,其侧重点在于反码与补码如何操作,但实际上反码和补码的作用是用在带符号数上面的,下面进入重点。
3、带符号数 Signed Number
3.1 符号位 The Sign Bit
带符号的二进制的最左边的那一位就是符号位,指出这个数为正数还是负数,0表示正数,1表示负数。
下面介绍几种表示带符号数的形式。3.2 符号数值的形式 Sign-Magnitude Form
最左边的一位是符号位,剩余的位都是数值位。其实也就是一般的带符号数的形式,数值位对于正数和负数来说都是二进制源码(in true (uncomplemented) binary)。如十进制数 +25 使用符号数值形式表示成8位带符号二进制数为:
十进制数 -25 表示为:
他们之间的唯一区别就是符号位不同。3.3 反码形式 1’s Complement Form
正数的反码形式:与符号数值形式相同;
负数的反码形式:相应正数的反码。也就是为相应正数的符号数值形式的每一位取反。应当注意的是并不是带符号数的反码都是每一位取反。
反码和补码其实是为了解决正数和负数的加减法运算的,所以正数其实不用做什么改变,而负数改变形式后可以巧妙解决一些运算问题。比如减去某个数和加上这个数的补码是一样的,这就是为什么计算机在所有的算术运算中都使用补码来表示负整数。
理解了反码是带符号数的一种表示形式及其目的,大概就能理解为什么正数的反码是其本身,下面要说到的补码也是一样的道理。举例:在反码表示形式中,
十进制数 25 表示为:
00011001
十进制数 -25 表示为:
111001103.4 补码形式 2’s Complement Form
正数的补码形式:与符号数值形式相同;
负数的补码形式:负数的反码加1。举例:在补码表示形式中,
十进制数 25 表示为:
00011001
十进制数 -25 表示为:
111001113.5 总结
对于带符号数,
正数的反码和补码与原码相同;
负数的反码等于相应正数的反码,补码等于相应正数的补码。但这样的说法是会让人产生疑惑的,因为既然正数的反码等于原码,且负数的反码等于相应正数的反码(即等于正数的原码),那正数负数的表示不就一样了。我也觉得这种说法很有歧义,但如果把第二个反码看成是一种广义上的操作,即把每一位取反,这样就没问题了,总之只要能理解就好,有时候反码就是真的“反”码,实实在在的操作。但为了避免这种困惑,倒不如表述得更清楚直接些:
对于带符号数,
正数的反码和补码与原码相同;
负数的反码等于相应正数的符号数值形式的各个位取反,补码等于反码加1。
如有不合理的地方,欢迎指正。
-
整数和真小数二进制原码、反码、补码转换代码
2020-08-21 11:55:30不能体现补码的取值范围与反码不同的特点。 本代码在code::blocks17.12中正常运行 #include <stdio.h> #include <stdlib.h> #define MAXSIZE 64 typedef struct rational_number{ char charnum[MAXSIZE...希望为计算机初学者提供一些帮助。笔者学术不精,时间仓促,一些功能写的比较笨,但是勉强能用。不能体现补码的取值范围与反码不同的特点。
本代码在code::blocks17.12中正常运行#include <stdio.h> #include <stdlib.h> #define MAXSIZE 64 typedef struct rational_number{ char charnum[MAXSIZE]; long long integer;//整数部分 double decimal;//小数部分(浮点数) double approximate;//输入的数的近似浮点数 }Rational; char* bin_plus_bin_direct(char* A, char* B); char* bin_to_truecode(long long num); //有理数扫描 Rational* scan_rational(){ Rational* num=(Rational*)malloc(sizeof(Rational)); char c; int flag=0;//触发器,整数部分=0,小数部分=1 int i=0;//全局char指针 int weight=10;//表示小数部分的权重 int negtive=1;//表示正负数 //初始化 num->integer=0; num->decimal=0; num->approximate=0; while((c=getchar())!='\n'){ num->charnum[i++]=c; if(c=='-'){ negtive=-1; continue; } if(c=='.'){ flag=1; continue; } if(flag==0){ num->integer=(num->integer)*10+c-'0'; num->approximate=(num->approximate)*10+c-'0'; }else{ num->decimal+=(float)(c-'0')/weight; num->approximate+=(float)(c-'0')/weight; weight*=10; } } num->charnum[i]='\0'; num->integer*=negtive; num->approximate*=negtive; return num; } //(真)小数 10进制转16位原码 char* dec_to_truecode(double num){ char* res=malloc(18*sizeof(char)); int i=2; memset(res,'0',17*sizeof(char)); res[16]='\0'; res[1]='.'; if(num>=1){ printf("需要真小数\n"); return res; } if(num<0){ res[0]='1'; num*=-1; }else{ res[0]='0'; } while(i<16){ if(num==0){ break; } num*=2; if(num>=1){ res[i++]='1'; num-=1; }else{ res[i++]='0'; } } return res; } //(真)小数 10进制转16位反码 char* dec_to_complementcode(double num){ char* complementcode=dec_to_truecode(num); if(complementcode[0]=='0'){ return complementcode; } for(int i=2;i<16;i++){ if(complementcode[i]=='0'){ complementcode[i]='1'; }else if(complementcode[i]=='1'){ complementcode[i]='0'; } } return complementcode; } //(真)小数 10进制转16位补码 char* dec_to_reversecode(double num){ char* reversecode=dec_to_complementcode(num); if(reversecode[0]=='0'){ return reversecode; } reversecode=bin_plus_bin_direct(reversecode,bin_to_truecode(1)); return reversecode; } //整数 10进制转2进制 long long int_to_bin(int num){ long long flag=1; long long res=0; while(num!=0){ res+=num%2*flag; flag*=10; num/=2; } return res; } //整数 2进制转16位原码 char* bin_to_truecode(long long num){ int weight; char* res=malloc(17*sizeof(char)); if(countdigits(num,-1)>16){// printf("所给数大于16位,无法处理"); res="0"; return res; } if(num>0){ res[0]='0'; weight=1; }else{ res[0]='1'; weight=-1; } res[16]='\0'; for(int i=15;i>0;i--){ if(num==0){ res[i]='0'; }else{ res[i]=weight*(num%10)+'0'; num/=10; } } return res; } //整数 2进制转16位反码 char* bin_to_complementcode(long long num){ char* complementcode=bin_to_truecode(num); if(complementcode[0]=='0'){ return complementcode; } for(int i=1;i<16;i++){ if(complementcode[i]=='0'){ complementcode[i]='1'; }else if(complementcode[i]=='1'){ complementcode[i]='0'; } } return complementcode; } //整数 2进制转16位补码 char* bin_to_reversecode(long long num){ char* reversecode=bin_to_complementcode(num); if(reversecode[0]=='0'){ return reversecode; } reversecode=bin_plus_bin_direct(reversecode,bin_to_truecode(1)); return reversecode; } //整数 (直接的)二进制加法 char* bin_plus_bin_direct(char* A, char* B){ //1001011+1110 char* res=malloc(17*sizeof(char)); int flag=0; res[16]='\0'; for(int i=15;i>=0;i--){ if(A[i]=='0'){ if(B[i]=='0'){ if(flag==0){//A=0,B=0,flag=0 res[i]='0'; }else if(flag==1){//A=0,B=0,flag=1 res[i]='1'; flag=0; } }else if(B[i]=='1'){//A=0,B=1,flag=0 if(flag==0){ res[i]='1'; }else if(flag==1){//A=0,B=1,flag=1 res[i]='0'; } } }else if(A[i]=='1'){ if(B[i]=='0'){ if(flag==0){//A=1,B=0,flag=0 res[i]='1'; }else if(flag==1){//A=1,B=0,flag=1 res[i]='0'; } }else if(B[i]=='1'){ if(flag==0){//A=1,B=1,flag=0 res[i]='0'; flag=1; }else if(flag==1){//A=1,B=1,flag=1 res[i]='1'; flag=1; } } }else if(A[i]=='.'){ res[i]='.'; } } return res; } //计算数字X中num出现的位数,当num=-1时取所有数 int countdigits(long long X,int num){ int res=0; if(num==-1){ while(X!=0){ res++; X/=10; } }else{ while(X!=0){ if(X%10==num) res++; X/=10; } } return res; } int main() { Rational* num; while(1){ num=scan_rational(); if(num->decimal==0){ //按整形处理 printf("> 输入数:%d\n",num->integer); long long code_0=int_to_bin(num->integer); printf(" 原码:%s |",bin_to_truecode(code_0)); printf(" 反码:%s |",bin_to_complementcode(code_0)); printf(" 补码:%s \n",bin_to_reversecode(code_0)); printf("> 输入数:%d\n",-1*num->integer); long long code_1=int_to_bin(-1*num->integer); printf(" 原码:%s |",bin_to_truecode(code_1)); printf(" 反码:%s |",bin_to_complementcode(code_1)); printf(" 补码:%s \n",bin_to_reversecode(code_1)); printf("-------\n"); }else if(num->integer==0){ //按小数型处理 printf("> 输入数:%f\n",num->decimal); printf(" 原码:%s |",dec_to_truecode(num->decimal)); printf(" 反码:%s |",dec_to_complementcode(num->decimal)); printf(" 补码:%s \n",dec_to_reversecode(num->decimal)); printf("> 输入数:%f\n",-1*num->decimal); printf(" 原码:%s |",dec_to_truecode(-1*num->decimal)); printf(" 反码:%s |",dec_to_complementcode(-1*num->decimal)); printf(" 补码:%s \n",dec_to_reversecode(-1*num->decimal)); printf("-------\n"); }else{ printf("暂时无法处理该类型\n"); } } }
-
用科学计数法表示二进制小数_数值数据的表示
2020-11-22 04:01:29无符号整型即我们数学中的正整数,在计算机中使用二进制的原码表示无符号整数,没有正负号占位。在32位电脑中,最大数为2^32-1,最小值为0。带符号整型带符号的整型,用最高位表示正负号。0表示正号,...在学习之前,我们先来看一段代码的计算。为什么会出现这样的结果呢?
std
在计算机中最主要的数据类型有无符号整型、有符号整型、浮点数、布尔值
- 布尔值
就是真/假,1或者0。在计算机中用最小的1个字节表示,即8位。
- 无符号整型
即我们数学中的正整数,在计算机中使用二进制的原码表示无符号整数,没有正负号占位。在32位电脑中,最大数为2^32-1,最小值为0。
- 带符号整型
带符号的整型,用最高位表示正负号。0表示正号,1表示负号。所以,在32位电脑中,最大值为2^31-1,最小值为-2^31。在计算机中,带符号整型的整数部分用补码表示。正数的补码还是自己,负数的补码是符号不变,其余各位取反,末尾加1。即[-1]=[100000001]原=[11111111]补
那么问题来了为什么不用原码表示?不是更直观?更让人理解吗?首先,我们人脑知道第一位是符号位,我们可以根据正负号来进行加减法。但是,对于计算机而已,加减法已经是最基础了,要设计的尽量简单。如果计算机辨别“符号位”显然让计算机的基础电路设计的变得十分复杂!于是人们想出将符号位也参与运算的方法。即1-1=1+(-1)。下面开始探索将符号位参与运算。有关原码、反码、补码的计算方式见如下:
Chdy:开篇——内容概要zhuanlan.zhihu.com原码:1+(-1)=[00000001]原+[10000001]原=[10000010]原=-2
反码:1+(-1)=[00000001]反+[11111110]反=[11111111]反=[10000000]原=-0
补码:1+(-1)=[00000001]补+[11111111]补=[00000000]补=[00000000]原=0显然,原码的计算结果是错误的。而反码和补码是正确的。而反码问题就出现在“0”的表示上,+0=[00000000]反,-0=[11111111]反。显然正负0用反码表示是不等的。于是,带符号的整数就用补码来表示。
说完了,有符号、无符号整型在计算机中的表示方式!我们就可以解答前面提到过的问题。 首先计算机在判断两个数的大小,先判断两个数的类型,两个值为有符号类型,则用有符号表示。如果一个值为无符号整型,另一个值为有符号整型,计算机就会使用无符号整型来比较。-1<0,在计算机中的结果为真,是因为将这两个值都当作是有符号整型来处理了,则[-1]=[111111111]补,[0]=[00000000]补,使用有符号整型处理,负数自然要比0小,所以结果为真。而-1<0U在计算机中的结果为假,是因为[-1]=[111111111]补,[0]=[00000000]原,计算机把他们当成了无符号的整型来比较了([11111111]=2^7),所以结果就出现了-1<0U为假。
- 浮点数
插入图片更加直观。其实,浮点数就是用我们的科学计数法来在计算机中表示。但是,里面也包含了一些规范。此处我们拿32位计算方式来举例,64位类推。
- 第一位表示正负号,0表示正号,1表示符号;
- 用8位表示科学计数法的指数,计算机内值需要减去127,才等于真值。反之真值加上127,等于计算机内值大家考虑一下,为什么要减去127呢?大家可以思考一下!
- 剩余的23位用于表示小数部分;
- 整数部分1,不在计算机中表示。转化为真值,需要加1。
-2.32在计算机中的表示为:
转化:将整数部分用二进制表示2=[10]原,小数部分0.32=[0.010100011110...]
规格化:使用科学计算法可表示为-1*1.0010100011110...*2^1
填充:用计算机內值表示为s为1,Exponent为1+127,Significand为尾数0010100011110...
内存中的表示为1 10000000 0010100011110...尾数部位是一个无限循环小数,看到这里我们就明白了,为什么在编译器中浮点数精确度不准确的原因了把!下面提供一个网站,可以用来将真值转化为计算机內值。
IEEE-754 Floating Point Converterwww.h-schmidt.net在结尾的时候,我们来思考一下!为什么指数的介要加一个偏置常数(127,即2^(8-1)-1)呢?试想一下,如果我们不加这个偏置常数,指数的介是负数要怎么表示?所以,这里面加上一个偏制常数,是为了表示负数的?一些好奇的同学又会问,为什么不跟带符号整型一样使用补码的方式来表示呢?上文中,不是提到很多补码的好处么?带着这个问题,我们进行下一个课题的学习——逻辑门电路。计算机是怎么实现加、减、乘、除的?
-
二进制数的编码:原码、反码和补码
2018-10-15 15:00:56常用编码有原码、反码和补码。 原码 将符号位数字化0或1,数的绝对值与符号一起编码,即“符号-绝对值表示”。 X = +0101011 ------------------&gt; [X]原 = 00101011 X = -0101011 -------------------&... -
二进制运算(原码、反码、补码)
2020-08-01 13:04:47二进制运算(正码、反码、补码) 机器数(机器存储的数) 一个数在计算机中的二进制表示形式, 叫做这个数的机器数。机器数是带符号的,在计算机用一个数的最高位存放符号, 正数为0, 负数为1 //比如byte类型... -
[数制与码制]: 有关十进制转换和二进制负数小数补码表示
2022-02-27 20:55:32有关十进制的转换 有关二进制负小数补码表示 -
有符号二进制数--补码
2022-04-06 11:12:58计算机内,有符号数的3种表示方法:原码,反码,补码。 (1)最高位为符号位,“0”为正,“1”为负,其余位为数值大小。 (2)反码:正数 反码 = 原码; &... -
十进制转换为二进制、原码、反码、补码、移码
2019-04-03 01:22:11十进制(小数)转换为二进制(8位): 原码:首位是符号位,其余的n-1位表示数值的绝对值,数位不够用0补足。数值0的原码有两种形式:[+0] 原=00000000, [-0]原=10000000。 正数的原码、反码、补码都一致。 ... -
原码、反码、补码及小数的存储
2022-04-24 19:52:35原、反、补码以及小数的存储 -
负数与二进制的转换(原码 反码 补码)
2019-05-16 09:27:24正数原码:正数的原码为取绝对值的数转二进制,5的原码为 0....0101 负数原码:负数的原码为取绝对值的数转二进制,然后符号位加一,-5的原码为 1....0101 正数的反码:正数的反码与原码相同。 负数的反码:负数... -
c 带符号位小数的二进制转十进制
2020-12-25 15:29:35带小数的二进制转十进制 看到的都是 理论 没有代码, 今天把自己的公布下,欢迎指正(部分是借用别人的)如有疏漏,恳请指出。 #include <stdio.h> #include <string.h> #include <math.h> void .... -
原码、反码、补码二进制表示
2021-10-18 07:13:21原码,反码,补码,都是计算机用二进制来表示数据的,计算机表示数据是由数据长度和符号位表示的,首位表示符号位,0表示正数,1表示负数,剩下的数据表示所要表示的数据。 什么是数据长度? 就是我们说的位数,... -
二进制下的正数、负数、小数、乘法溢出、精度丢失
2018-09-26 11:36:29负数的原码:负数的绝对值的二进制的最高位变为1。 负数的反码:负数的原码的最高位不变,其余取反。 负数的补码:负数的反码+1。 例: 1.正数 9 (0000 1001 = 23+20=9) 原码:0000 1001 反码:0000 1001 ... -
二进制运算以及源码、补码、反码概念讲解
2020-07-01 13:58:38在学习框架源码底层时,有非常多的二进制运算,由于大学学习计算机基础时抓梦脚(jio),没有学习牢固,所以在看底层源码的算法逻辑时遇到二进制 运算比较吃力,遂通过一篇博文来总结下二进制运算,记录一下。 正文 ... -
整数和真小数二进制原码、反码、补码转换代码(改进)
2020-08-21 19:28:002.对十进制转二进制完全char化,对二进制没有长度限制,只对十进制数有限制,只需要把int类型改成longlong类型就可以进一步扩大。 3.可以自定义输出的位长,为以后的调用做好准备。 #include <stdio.h> #... -
C语言中八进制和16进制怎么表示,原码,反码及补码,C语言按位取反运算符~
2021-05-23 02:15:37比如05,0237所以C语言没有二进制输入,最多可用函数去实现。八进制数的表达方法C/C++规定,一个数如果要指明它采用八进制,必须在它前面加上一个0(数字0),如:123是十进制,但0123则表示采用八进制。这就是八进制数... -
二进制,八进制,16进制间的互相转换含小数与负数
2021-06-15 22:25:50**B表示二进制 ** (010100101)B O、Q表示8进制 (12565)O或者是(12565)Q H表示16进制 (56BBA)H //正数拓展 进制 二进制 0b 十进制 八进制 0 十六进制 0x int a=10; int a1=0b10; int a2=010; int a3=0x10; int ... -
十进制转成二进制/八进制/十六进制,原码补码反码介绍
2020-02-28 18:44:13各种进制之间的相互转换...二进制 逢二进一 八进制 逢八进一 十六进制 逢十六进一 十进制—>二/八/十六进制 口诀 整数部分,除2/8/16取余; 小数部分,乘2/8/16取整 例:23.25转换成二进制为10111.01 二... -
计算机基础:16、二进制--有符号数和无符号数(二进制原码、补码、反码)
2021-06-12 15:10:46计算机基础:16、二进制--有符号数和无符号数1、有符号数和无符号数1.1、二进制原码表示法1.2、二进制的补码表示法1.3、二进制的反码1.4、小数的补码1.5、原码、补码、反码总结 1、有符号数和无符号数 1.1、二进制... -
十进制的正整数,负数, 小数转为二进制.八进制.十六进制的方法 包括原码,反码,补码的介绍
2014-09-14 17:23:16对于初学者,迟早要面对进制的转换,或许 -
十进制、二进制、八进制、十六进制、进制转换、二进制负数的反码与补码
2021-04-28 18:03:08目录十进制、二进制、八进制、十六进制对应表二进制转十进制8421码和十进制之间的对应关系十进制转二进制二进制、十进制互相转换(小数) 十进制、二进制、八进制、十六进制对应表 十进制 二进制 八进制 十六... -
二进制(原码、反码、补码)(转载)
2017-11-02 15:43:09bit(位):数据存储的最小单元...在计算机二进制系统中,位,简记为b,也称为比特(bit),每个二进制数字0或1就是一个位(bit),其中每 8bit = 1 byte(字节); Java 中的int数据类型占4个byte(字节),而1 byte(字节) = -
二进制及原码反码补码介绍、八进制、十六进制及Java中移位运算详解
2019-06-22 15:51:08二进制1.1.原码1.2.反码1.3.补码2.八进制3.十六进制4.位运算4.1.与(&)运算4.2.或(|)运算4.3.非(~)运算4.4.异或(^)运算4.5.移位(<< >> >>>)... -
十进制和二进制的转化;原码、反码和补码
2016-09-09 23:49:03因为数在计算机中是以二进制的形式表示的,并且在其最高位是其符号位,如六位整数000001=1,而100001=-1; 原码:原码就是这个数的二进制形式;正数的补码和反码和原码相同,而负数的反码为原码除了符号位之外其他... -
二进制,十进制,十六进制转化
2022-04-26 21:19:28把二进制数从低位到高位每4位组成一组,直接用16进制数来表示即可,例如: 0011 0101 1011 1111 3 5 B F 这里很好拼凑,1,2,4,8权相对应的位置只要是1,咱们加起来就可以了。 第一个末尾俩1(1+2=3),接着... -
C语言 八进制 16进制 原码 反码 补码 按位取反
2013-11-06 10:15:28C语言中8进制和16进制怎么表示 ...所以C语言没有二进制输入,最多可用函数去实现。 八进制数的表达方法 C/C++规定,一个数如果要指明它采用八进制,必须在它前面加上一个0(数字0),如:123是十进制, -
2,16进制原码补码反码问题
2021-05-21 02:31:161. 在计算机里,通常用数字后面紧跟一个英文字母来表示该数的数字,十进制一般用D,二进制用B,八进制用O,十六进用H来表示,2.首先,十进制数转换成二进制,除2取余,按箭头方向写,自上而下写出来,所以45D转换成二... -
C语言编程之二进制原码、反码和补码
2021-05-20 04:20:36详细释义所谓原码就是二进制定点表示法,即最高位为符号位,“0”表示正,“1”表示负,其余位表示数值的大小。反码表示法规定:正数的反码与其原码相同;负数的反码是对其原码逐位取反,但符号位除外。补码表示法... -
学计算机还能不懂二进制(原码反码补码各种运算)
2020-04-25 10:39:37二进制数据的表示方法2.1 有符号数与无符号数2.2 二进制的补码表示法2.3 二进制的反码表示法2.4 小数的二进制补码表示三.二进制的运算3.1 定点数与浮点数3.1.1 定点数的表示方法3.1.2 浮点数的表示方法3.1.3 定点数...