-
2022-02-23 21:14:04
一、二进制数、位和字节
1、二进制数
以为基地表示的数字称为二进制数。二进制中的2和十进制中的10作用相同。二进制数1101可表示为:
1*23+1*22+0*21+1*20
以十进制数表示
1*8+1*4+0*2+1*1 = 13
二进制系统可以把任意整数(如果有足够的位)表示为 0和1的组合。数字计算机通过关闭和打开状态的组合来表示信息,分别是0和1。2、二进制整数
通常1字节包含8位。C语言用字节(byte)表示储存系统字符集所需的大小。所以C字节可能是8位、9位、16位或其他值。描述存储芯片和数据传输率中所用的字节指的是8位字节,计算机界通常用8位组这个术语特制8位字节。可以从左往右给这8位分别编号7-0。在1字节中,编号是7的位称为高阶位,编号是0的位被称为低阶位。
这里128是2的7次幂,依次类推,该字节能表示的最大数字是把所有位都设置1:11111111.这个二进制的值是
128+64+32+16+8+4+2+1=255
最小值是00000000,其值为0。
一字节可储存0-255范围内的数字,总共256个值。或者通过不同的方式解释位组合,程序可以用1字节存储-128-127范围内的整数,总共还是256个值。
通常unsigned char用一字节可表示的范围是0-255,而signed char用一个字节表示的范围是-128-127.3、有符号整数
如何表示有符号整数取决于硬件,而不是语言。
第一种:种符号量表示法
用1位(如,高阶位)储存符号,只剩下7位表示数字本身(假设储存在一个字节里面)。10000001表示-1,00000001表示1,因此,其表示范围是-127-+127。此方法的缺点是有俩个0:+0和-0。这容易混淆,而且用俩个位组合来表示一个值有些浪费。
第二种:二进制补码
二进制补码用1字节的后7位表示0-127,高阶位设置为0。如果高阶位是1,表示的值为负。
这俩种方法的区别在于如何区别负值。
二进制反码方法通过反转位组合中的每一位成一个负数。例如00000001是1,那么11111110是-1.这种方法也有一个-0:11111111.该方法能表示-127到127的数。4、二进制浮点数
浮点数分俩部分储存:二进制小数和二进制指数。
二、其他进制数
1、八进制
八进制指八进制计数系统,该系统基于8的幂,用0-7表示数字。例如,八进制数451(在C中写作0451)表示为:4*82+5*81+1*80=297(十进制数)。
每个八进制位对应三个二进制位。下表列出了对应关系。注意:将八进制数转换成二进制形式时,不能去掉中间的0。例如八进制数0173的二进制形式是011111011,不是0111111。八进制位 等价的二进制位 0 000 1 001 2 010 3 011 4 100 5 101 6 110 7 111 2、十六进制
十六进制指十六进制计数系统,该系统基于18的幂,用0-15表示数字。由于没有单独的数(即0-9这样单独一位的数)表示10-15,所以用字母A-F来表示,C语言中,可以用大写或者小写。例如,十六机制数A3F(在C中写作0xA3F)表示为
10*162+3*161+15*160=2623(十进制)
每一个十六进制位都对应一个4位的二进制数(即4个二进制位),那么俩个十六进制恰好对应一个8位字节。第一个十六进制表示前4位,第二个十六进制位表示后4位。因此,十六进制很适合表示字节值。十进制 十六进制 等价二进制 0 0 0000 1 1 0001 2 2 0010 3 3 0011 4 4 0100 5 5 0101 6 6 0110 7 7 0111 8 8 1000 9 9 1001 A 10 1010 B 11 1011 C 12 1100 D 13 1101 E 14 1110 F 15 1111 更多相关内容 -
C语言中十六进制转十进制两种实现方法
2021-01-20 06:47:40C语言 · 十六进制转十进制 问题描述 从键盘输入一个不超过8位的正的十六进制数字符串,将它转换为正的十进制数后输出。 注:十六进制数中的10~15分别用大写的英文字母A、B、C、D、E、F表示。 样例输入 FFFF... -
C语言二进制、八进制、十进制、十六进制深入探究
2021-07-17 00:11:44但是,表示一个二进制、八进制或者十六进制数字就不一样了,为了和十进制数字区分开来,必须采用某种特殊的写法,具体来说,就是在数字前面加上特定的字符,也就是加前缀。 1) 二进制 二进制由 0 和 1 两个数字组成...首先来一篇好文:C语言中的二进制数、八进制数和十六进制数
C语言中的整数除了可以使用十进制,还可以使用二进制、八进制和十六进制。
二进制数、八进制数和十六进制数的表示
一个数字默认就是十进制的,表示一个十进制数字不需要任何特殊的格式。但是,表示一个二进制、八进制或者十六进制数字就不一样了,为了和十进制数字区分开来,必须采用某种特殊的写法,具体来说,就是在数字前面加上特定的字符,也就是加前缀。
1) 二进制
二进制由 0 和 1 两个数字组成,使用时必须以
0b
或0B
(不区分大小写)开头,例如://合法的二进制int a = 0b101; //换算成十进制为 5 int b = -0b110010; //换算成十进制为 -50 int c = 0B100001; //换算成十进制为 33 //非法的二进制 int m = 101010; //无前缀 0B,相当于十进制 int n = 0B410; //4不是有效的二进制数字
读者请注意,标准的C语言并不支持上面的二进制写法,只是有些编译器自己进行了扩展,才支持二进制数字。换句话说,并不是所有的编译器都支持二进制数字,只有一部分编译器支持,并且跟编译器的版本有关系。
下面是实际测试的结果:
- Visual C++ 6.0 不支持。
- Visual Studio 2015 支持,但是 Visual Studio 2010 不支持;可以认为,高版本的 Visual Studio 支持二进制数字,低版本的 Visual Studio 不支持。
- GCC 4.8.2 支持,但是 GCC 3.4.5 不支持;可以认为,高版本的 GCC 支持二进制数字,低版本的 GCC 不支持。
- LLVM/Clang 支持(内嵌于 Mac OS 下的 Xcode 中)。
2) 八进制
八进制由 0~7 八个数字组成,使用时必须以
0
开头(注意是数字 0,不是字母 o),例如://合法的八进制数int a = 015; //换算成十进制为 13 int b = -0101; //换算成十进制为 -65 int c = 0177777; //换算成十进制为 65535 //非法的八进制 int m = 256; //无前缀 0,相当于十进制 int n = 03A2; //A不是有效的八进制数字
3) 十六进制
十六进制由数字 0~9、字母 A~F 或 a~f(不区分大小写)组成,使用时必须以
0x
或0X
(不区分大小写)开头,例如://合法的十六进制int a = 0X2A; //换算成十进制为 42 int b = -0XA0; //换算成十进制为 -160 int c = 0xffff; //换算成十进制为 65535 //非法的十六进制 int m = 5A; //没有前缀 0X,是一个无效数字 int n = 0X3H; //H不是有效的十六进制数字
4) 十进制
十进制由 0~9 十个数字组成,没有任何前缀,和我们平时的书写格式一样,不再赘述。
二进制数、八进制数和十六进制数的输出
C语言中常用的整数有 short、int 和 long 三种类型,通过 printf 函数,可以将它们以八进制、十进制和十六进制的形式输出。上节我们讲解了如何以十进制的形式输出,这节我们重点讲解如何以八进制和十六进制的形式输出,下表列出了不同类型的整数、以不同进制的形式输出时对应的格式控制符:
short int long 八进制 %ho %o %lo 十进制 %hd %d %ld 十六进制 %hx 或者 %hX %x 或者 %X %lx 或者 %lX 十六进制数字的表示用到了英文字母,有大小写之分,要在格式控制符中体现出来:
- %hx、%x 和 %lx 中的
x
小写,表明以小写字母的形式输出十六进制数; - %hX、%X 和 %lX 中的
X
大写,表明以大写字母的形式输出十六进制数。
八进制数字和十进制数字不区分大小写,所以格式控制符都用小写形式。如果你比较叛逆,想使用大写形式,那么行为是未定义的,请你慎重:
- 有些编译器支持大写形式,只不过行为和小写形式一样;
- 有些编译器不支持大写形式,可能会报错,也可能会导致奇怪的输出。
注意,虽然部分编译器支持二进制数字的表示,但是却不能使用 printf 函数输出二进制,这一点比较遗憾。当然,通过转换函数可以将其它进制数字转换成二进制数字,并以字符串的形式存储,然后在 printf 函数中使用
%s
输出即可。考虑到读者的基础还不够,这里就先不讲这种方法了。【实例】以不同进制的形式输出整数:
#include <stdio.h> int main() { short a = 0b1010110; //二进制数字 int b = 02713; //八进制数字 long c = 0X1DAB83; //十六进制数字 printf("a=%ho, b=%o, c=%lo\n", a, b, c); //以八进制形似输出 printf("a=%hd, b=%d, c=%ld\n", a, b, c); //以十进制形式输出 printf("a=%hx, b=%x, c=%lx\n", a, b, c); //以十六进制形式输出(字母小写) printf("a=%hX, b=%X, c=%lX\n", a, b, c); //以十六进制形式输出(字母大写) return 0; }
运行结果:
a=126, b=2713, c=7325603
a=86, b=1483, c=1944451
a=56, b=5cb, c=1dab83
a=56, b=5CB, c=1DAB83从这个例子可以发现,一个数字不管以何种进制来表示,都能够以任意进制的形式输出。数字在内存中始终以二进制的形式存储,其它进制的数字在存储前都必须转换为二进制形式;同理,一个数字在输出时要进行逆向的转换,也就是从二进制转换为其他进制。
输出时加上前缀
请读者注意观察上面的例子,会发现有一点不完美,如果只看输出结果:
- 对于八进制数字,它没法和十进制、十六进制区分,因为八进制、十进制和十六进制都包含 0~7 这几个数字。
- 对于十进制数字,它没法和十六进制区分,因为十六进制也包含 0~9 这几个数字。如果十进制数字中还不包含 8 和 9,那么也不能和八进制区分了。
- 对于十六进制数字,如果没有包含 a~f 或者 A~F,那么就无法和十进制区分,如果还不包含 8 和 9,那么也不能和八进制区分了。
区分不同进制数字的一个简单办法就是,在输出时带上特定的前缀。在格式控制符中加上
#
即可输出前缀,例如 %#x、%#o、%#lX、%#ho 等,请看下面的代码:#include <stdio.h> int main() { short a = 0b1010110; //二进制数字 int b = 02713; //八进制数字 long c = 0X1DAB83; //十六进制数字 printf("a=%#ho, b=%#o, c=%#lo\n", a, b, c); //以八进制形似输出 printf("a=%hd, b=%d, c=%ld\n", a, b, c); //以十进制形式输出 printf("a=%#hx, b=%#x, c=%#lx\n", a, b, c); //以十六进制形式输出(字母小写) printf("a=%#hX, b=%#X, c=%#lX\n", a, b, c); //以十六进制形式输出(字母大写) return 0; }
运行结果:
a=0126, b=02713, c=07325603
a=86, b=1483, c=1944451
a=0x56, b=0x5cb, c=0x1dab83
a=0X56, b=0X5CB, c=0X1DAB83十进制数字没有前缀,所以不用加
#
。如果你加上了,那么它的行为是未定义的,有的编译器支持十进制加#
,只不过输出结果和没有加#一样,有的编译器不支持加#
,可能会报错,也可能会导致奇怪的输出;但是,大部分编译器都能正常输出,不至于当成一种错误。
下面来实战一下,验证一下数值在不同进制的表示下的情况
首先我们总结一下上面的内容:
-
各进制表示
- 二进制表示:使用时必须以
0b
或0B
(不区分大小写)开头 - 八进制表示:使用时必须以
0
开头(注意是数字 0,不是字母 o) - 十六进制表示:使用时必须以
0x
或0X
(不区分大小写)开头
- 二进制表示:使用时必须以
-
各进制打印
- 二进制打印:C语言没有提供打印数值二进制表示的方式
- 八进制打印:printf("%o", n) printf("%#o", n)
- 十进制打印:printf("%d", n) printf("%#d", n)
- 十六进制打印:printf("%x", n)
-
基本常识:不管是哪种进制,在计算机里面都是以0/1来表示的,说的更具体一点,都是以补码的形式存在。
一、首先演示一下用不同进制来表示同一个数值
#include <stdio.h> //该函数用来打印unsigned char的二进制表示 void printf_bin_8(unsigned char num) { int k; unsigned char *p = (unsigned char*)# for (int k = 7; k >= 0; k--) //处理8个位 { if (*p & (1 << k)) printf("1"); else printf("0"); } printf("\r\n"); } int main() { unsigned char a = 99; printf("二进制表示为:0b"); printf_bin_8(a); printf("八进制表示为:%#o\n",a); printf("十进制表示为:%d\n",a); printf("十六进制表示为:%#x\n",a); }
二、不同进制的数据可以比较大小和进行数值运算吗?
int main() { int a = 99;//十进制99 int b = 0b01100011;//二进制99 int c = 0143;//八进制99 int d = 0x63;//十六进制99 if(a == b && b == c && c == d) printf("不同进制表示的数据是可以比较的"); printf("\na+b=%d",a + b); printf("\na-b=%d",a - b); printf("\na*b=%d",a * b); printf("\na/b=%d",a / b); }
可以看出不同进制表示的数据可以进行大小比较和运算的,其实只要我们理解了,不管什么进制表示的数据在计算机中都是以二进制补码的方式存储的。在进行大小比较或者运算时,我们可以都将其转成同一个进制的表示就可以了。
三、八进制、十六进制的数值表示可以作为数组索引吗?
int main() { int a = 99; int b = 0b01100011; int c = 0143; int d = 0x63; int arr[100]; arr[99] = 55; printf("%d",arr[a]); printf("\n%d",arr[b]); printf("\n%d",arr[c]); printf("\n%d",arr[d]); printf("\n%d",arr[0b01100011]); printf("\n%d",arr[0143]); printf("\n%d",arr[0x63]); }
-
C语言进制转换—16进制最大能表示10进制数是多少?
2021-05-19 11:06:271个字节:最大0xFF = 255(存储类型byte和char) 2个字节:最大0xFF FF = 65535(存储类型shot int) 4个字节:最大0xFF FF FF FF= 4294967295(存储类型int 、long) 8个字节:最大0xFF FF FF FF...十六进制(英文名称:He...1个字节:最大0xFF = 255(存储类型byte和char) 2个字节:最大0xFF FF = 65535(存储类型shot int) 4个字节:最大0xFF FF FF FF= 4294967295(存储类型int 、long) 8个字节:最大0xFF FF FF FF FF FF FF FF= 18446744073709551615(存储类型long long)
十六进制(英文名称:Hexadecimal),是计算机中数据的一种表示方法。同我们日常生活中的表示法不一样。它由0-9,A-F组成,字母不区分大小写。与10进制的对应关系是:0-9对应0-9;A-F对应10-15;N进制的数可以用0~(N-1)的数表示,超过9的用字母A-F。
中文名:十六进制
外文名:Hexadecimal
定义:计算机中数据的一种表示方法
组成:0-9,A-F
十六进制的表示方法:十六进制照样采用位置计数法,位权是16为底的幂。对于n位整数,m位小数的十六进制数用加权系数的形式表示如下:
举例说明:
16进制的20表示成10进制就是:2×161+0×16º=32
10进制的32表示成16进制就是:20
十进制数可以转换成十六进制数的方法是:十进制数的整数部分“除以16取余”,十进制数的小数部分“乘16取整”,进行转换。
比如说十进制的0.1转换成八进制为0.0631463146314631。就是0.1乘以8=0.8,不足1不取整,0.8乘以8=6.4,取整数6, 0.4乘以8=3.2,取整数3,依次下算。
编程中,我们常用的还是10进制.毕竟C/C++是高级语言。比如:
int a = 100,b = 99;
不过,由于数据在计算机中的表示,最终以二进制的形式存在,所以有时候使用二进制,可以更直观地解决问题。但二进制数太长了。比如int 类型占用4个字节,32位。比如100,用int类型的二进制数表达将是:
0000
0000
0000
0000
0110
0100
面对这么长的数进行思考或操作,没有人会喜欢。因此,C,C++ 没有提供在代码直接写二进制数的方法。用16进制或8进制可以解决这个问题。因为,进制越大,数的表达长度也就越短。不过,为什么偏偏是16或8进制,而不其它的,诸如9或20进制呢?2、8、16,分别是2的1次方、3次方、4次方。这一点使得三种进制之间可以非常直接地互相转换。8进制或16进制缩短了二进制数,但保持了二进制数的表达特点。在下面的关于进制转换的课程中,你可以发现这一点。
转换
二进制转换十进制
二进制数第0位的权值是2的0次方,第1位的权值是2的1次方……
所以,设有一个二进制数:101100100,转换为10进制为:356
用横式计算
0×20+0×21+1×22+0×23+0×24+1×25+1×26+0×27+1×28=356
0乘以多少都是0,所以我们也可以直接跳过值为0的位:
1×22+1×25+1×26+1×28=356
4+32+64+256 =356
八进制转换十进制
八进制就是逢8进1。
八进制数采用 0~7这八数来表达一个数。
八进制数第0位的权值为8的0次方,第1位权值为8的1次方,第2位权值为8的2次方……
所以,设有一个八进制数:1507,转换为十进制为:839,具体方法如下:
可以用横式直接计算:
7×80+0×81+5×82+1×83=839
也可以用竖式表示
第0位 7×80=7
第1位 0×81=0
第2位 5×82=320
第3位 1×83=512
十六进制转换十进制
16进制就是逢16进1,但我们只有0~9这十个数字,所以我们用A,B,C,D,E,F这六个字母来分别表示10,11,12,13,14,15。字母不区分大小写。
十六进制数的第0位的权值为16的0次方,第1位的权值为16的1次方,第2位的权值为16的2次方……
所以,在第N(N从0开始)位上,如果是数β (β大于等于0,并且β小于等于 15,即:F)表示的大小为 β×16的N次方。
假设有一个十六进数 2AF5
直接计算就是:
5×160+F×161+A×162+2×163=10997[1]
也可以用竖式表示:
第0位: 5×160=5
第1位: F×16^1=240
第2位: A×162=2560
第3位: 2×163=8192
-------------------------------
10997
此处可以看出,所有进制换算成10进制,关键在于各自的权值不同。
假设有人问你,十进数1234 为什么是一千二百三十四?你尽可以给他这么一个算式:
1234 = 1×103+2×102+3×101+4×100
十六进制互相转换
首先我们来看一个二进制数:1111,它是多少呢?
你可能还要这样计算:1×20+1×21+1×22+1×23=1×1+1×2+1×4+1×8=15。
然而,由于1111才4位,所以我们必须直接记住它每一位的权值,并且是从高位往低位记,:8、4、2、1。即,最高位的权值为23=8,然后依次是 22=4,21=2,20=1。
记住8421,对于任意一个4位的二进制数,我们都可以很快算出它对应的10进制值。
下面列出四位二进制数 xxxx 所有可能的值(中间略过部分)
仅4位的2进制数 快速计算方法 十进制值 十六进制
1111 = 8 + 4 + 2 + 1 = 15 =F
1110 = 8 + 4 + 2 + 0 = 14= E
1101 = 8 + 4 + 0 + 1 = 13= D
1100 = 8 + 4 + 0 + 0 = 12 =C
1011 = 8 + 0 + 2 + 1 = 11= B
1010 = 8 + 0 + 2 + 0 = 10 =A
1001 = 8 + 0 + 0 + 1 =9 =9
……
0001 = 0 + 0 + 0 + 1 = 1= 1
0000 = 0 + 0 + 0 + 0 = 0= 0
二进制数要转换为十六进制,就是以4位一段,分别转换为十六进制。
如(上行为二制数,下面为对应的十六进制):
1111 1101 , 1010 0101 , 1001 1011
F D , A 5 , 9 B
反过来,当我们看到 FD时,如何迅速将它转换为二进制数呢?
先转换F:
看到F,我们需知道它是15(可能你还不熟悉A~F这五个数),然后15如何用8421凑呢?应该是8 + 4 + 2 + 1,所以四位全为1 :1111。
接着转换D
看到D,知道它是13,13如何用8421凑呢?应该是:8 + 4 + 1,即:1101。
所以,FD转换为二进制数,为:1111 1101
由于十六进制转换成二进制相当直接,所以,我们需要将一个十进制数转换成2进制数时,也可以先转换成16进制,然后再转换成2进制。
比如,十进制数 1234转换成二制数,如果要一直除以2,直接得到2进制数,需要计算较多次数。所以我们可以先除以16,得到16进制数:
被除数 计算过程 商 余数
1234 1234/16 77 2
77 77/16 4 13 (D)
4 4/16 0 4
结果16进制为:4D2
然后我们可直接写出4D2的二进制形式:
0100
1101
0010
其中对映关系为:
0100 -- 4
1101 -- D
0010 -- 2
同样,如果一个二进制数很长,我们需要将它转换成10进制数时,除了前面学过的方法是,我们还可以先将这个二进制转换成16进制,然后再转换为10进制。
下面举例一个int类型的二进制数:
01101101
11100101
10101111
00011011
我们按四位一组转换为16进制:6D E5 AF 1B
十进制转十六进制
采余数定理分解,例如将487710转成十六进制:
487710÷16=30481....14(E)
30481÷16=1905....1
1905÷16=119....1
119÷16=7....7
7÷16=0....7
这样就计到487710(10)=7711E(16)
表达方法
程序的表达方法环境 格式备注URL%hex无 XML,XHTMLhex无HTML,CSS#hex6位,表示颜色UnicodeU+hex6位,表示字符编码MIME=hex无Modula-2#hex无Smalltalk,ALGOL 6816rhex无Common Lisp#xhex或#16rhex无IPv68个hex用:分隔无
C C++的表达方法
如果不使用特殊的书写形式,16进制数也会和10进制相混。随便一个数:9876,就看不出它是16进制或10进制。
C,C++规定,16进制数必须以 0x开头。比如 0x1表示一个16进制数。而1则表示一个十进制。另外如:0xff,0xFF,0X102A,等等。其中的x也不区分大小写。(注意:0x中的0是数字0,而不是字母O)
以下是一些用法示例:
int a = 0x100F;
int b = 0x70 + a;
至此,我们学完了所有进制:10进制,8进制,16进制数的表达方式。最后一点很重要,C/C++中,10进制数有正负之分,比如12表示正12,而-12表示负12,;但8进制和16进制只能表达无符号的正整数,如果你在代码中写:-078,或者写:-0xF2,C,C++并不把它当成一个负数。
在转义符中的使用
转义符也可以接一个16进制数来表示一个字符。如 \'?\' 字符,可以有以下表达方式:
\'?\' //直接输入字符
\'\77\' //用八进制,此时可以省略开头的0
\'\0x3F\' //用十六进制
同样,这一小节只用于了解。除了空字符用八进制数 \'\0\' 表示以外,我们很少用后两种方法表示一个字符。
-
进制转换:二进制、八进制、十六进制、十进制之间的转换
2021-05-20 10:27:19对于基础薄弱的读者,本节的内容可能略显晦涩和枯燥,如果觉得吃力,可以暂时跳过,用到的时候再来...将二进制、八进制、十六进制转换为十进制二进制、八进制和十六进制向十进制转换都非常容易,就是“按权相加”。...对于基础薄弱的读者,本节的内容可能略显晦涩和枯燥,如果觉得吃力,可以暂时跳过,用到的时候再来阅读。但是本节所讲的内容是学习编程的基础,是程序员的基本功,即使现在不学,迟早也要回来学。
上节我们对二进制、八进制和十六进制进行了说明,本节重点讲解不同进制之间的转换,这在编程中经常会用到,尤其是C语言。
将二进制、八进制、十六进制转换为十进制
二进制、八进制和十六进制向十进制转换都非常容易,就是“按权相加”。所谓“权”,也即“位权”。
假设当前数字是 N 进制,那么:
对于整数部分,从右往左看,第 i 位的位权等于Ni-1
对于小数部分,恰好相反,要从左往右看,第 j 位的位权为N-j。
更加通俗的理解是,假设一个多位数(由多个数字组成的数)某位上的数字是 1,那么它所表示的数值大小就是该位的位权。
1) 整数部分
例如,将八进制数字 53627 转换成十进制:
53627 = 5×84 + 3×83 + 6×82 + 2×81 + 7×80 = 22423(十进制)
从右往左看,第1位的位权为 80=1,第2位的位权为 81=8,第3位的位权为 82=64,第4位的位权为 83=512,第5位的位权为 84=4096 …… 第n位的位权就为 8n-1。将各个位的数字乘以位权,然后再相加,就得到了十进制形式。
注意,这里我们需要以十进制形式来表示位权。
再如,将十六进制数字 9FA8C 转换成十进制:
9FA8C = 9×164 + 15×163 + 10×162 + 8×161 + 12×160 = 653964(十进制)
从右往左看,第1位的位权为 160=1,第2位的位权为 161=16,第3位的位权为 162=256,第4位的位权为 163=4096,第5位的位权为 164=65536 …… 第n位的位权就为 16n-1。将各个位的数字乘以位权,然后再相加,就得到了十进制形式。
将二进制数字转换成十进制也是类似的道理:
11010 = 1×24 + 1×23 + 0×22 + 1×21 + 0×20 = 26(十进制)
从右往左看,第1位的位权为 20=1,第2位的位权为 21=2,第3位的位权为 22=4,第4位的位权为 23=8,第5位的位权为 24=16 …… 第n位的位权就为 2n-1。将各个位的数字乘以位权,然后再相加,就得到了十进制形式。
2) 小数部分
例如,将八进制数字 423.5176 转换成十进制:
423.5176 = 4×82 + 2×81 + 3×80 + 5×8-1 + 1×8-2 + 7×8-3 + 6×8-4 = 275.65576171875(十进制)
小数部分和整数部分相反,要从左往右看,第1位的位权为 8-1=1/8,第2位的位权为 8-2=1/64,第3位的位权为 8-3=1/512,第4位的位权为 8-4=1/4096 …… 第m位的位权就为 8-m。
再如,将二进制数字 1010.1101 转换成十进制:
1010.1101 = 1×23 + 0×22 + 1×21 + 0×20 + 1×2-1 + 1×2-2 + 0×2-3 + 1×2-4 = 10.8125(十进制)
小数部分和整数部分相反,要从左往右看,第1位的位权为 2-1=1/2,第2位的位权为 2-2=1/4,第3位的位权为 2-3=1/8,第4位的位权为 2-4=1/16 …… 第m位的位权就为 2-m。
更多转换成十进制的例子:
二进制:1001 = 1×23 + 0×22 + 0×21 + 1×20 = 8 + 0 + 0 + 1 = 9(十进制)
二进制:101.1001 = 1×22 + 0×21 + 1×20+ 1×2-1 + 0×2-2 + 0×2-3 + 1×2-4 = 4 + 0 + 1 + 0.5 + 0 + 0 + 0.0625 = 5.5625(十进制)
八进制:302 = 3×82 + 0×81 + 2×80 = 192 + 0 + 2 = 194(十进制)
八进制:302.46 = 3×82 + 0×81 + 2×80 + 4×8-1 + 6×8-2 = 192 + 0 + 2 + 0.5 + 0.09375= 194.59375(十进制)
十六进制:EA7 = 14×162 + 10×161 + 7×160 = 3751(十进制)
将十进制转换为二进制、八进制、十六进制
将十进制转换为其它进制时比较复杂,整数部分和小数部分的算法不一样,下面我们分别讲解。
1) 整数部分
十进制整数转换为 N 进制整数采用“除 N 取余,逆序排列”法。具体做法是:
将 N 作为除数,用十进制整数除以 N,可以得到一个商和余数;
保留余数,用商继续除以 N,又得到一个新的商和余数;
仍然保留余数,用商继续除以 N,还会得到一个新的商和余数;
……
如此反复进行,每次都保留余数,用商接着除以 N,直到商为 0 时为止。
把先得到的余数作为 N 进制数的低位数字,后得到的余数作为 N 进制数的高位数字,依次排列起来,就得到了 N 进制数字。
下图演示了将十进制数字 36926 转换成八进制的过程:
从图中得知,十进制数字 36926 转换成八进制的结果为 110076。
下图演示了将十进制数字 42 转换成二进制的过程:
从图中得知,十进制数字 42 转换成二进制的结果为 101010。
2) 小数部分
十进制小数转换成 N 进制小数采用“乘 N 取整,顺序排列”法。具体做法是:
用 N 乘以十进制小数,可以得到一个积,这个积包含了整数部分和小数部分;
将积的整数部分取出,再用 N 乘以余下的小数部分,又得到一个新的积;
再将积的整数部分取出,继续用 N 乘以余下的小数部分;
……
如此反复进行,每次都取出整数部分,用 N 接着乘以小数部分,直到积中的小数部分为 0,或者达到所要求的精度为止。
把取出的整数部分按顺序排列起来,先取出的整数作为 N 进制小数的高位数字,后取出的整数作为低位数字,这样就得到了 N 进制小数。
下图演示了将十进制小数 0.930908203125 转换成八进制小数的过程:
从图中得知,十进制小数 0.930908203125 转换成八进制小数的结果为 0.7345。
下图演示了将十进制小数 0.6875 转换成二进制小数的过程:
从图中得知,十进制小数 0.6875 转换成二进制小数的结果为 0.1011。
如果一个数字既包含了整数部分又包含了小数部分,那么将整数部分和小数部分开,分别按照上面的方法完成转换,然后再合并在一起即可。例如:
十进制数字 369260.930908203125 转换成八进制的结果为 110076.7345;
十进制数字 42.0.6875 转换成二进制的结果为 101010.1011。
下表列出了前 17 个十进制整数与二进制、八进制、十六进制的对应关系:
十进制
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
二进制
0
1
10
11
100
101
110
111
1000
1001
1010
1011
1100
1101
1110
1111
10000
八进制
0
1
2
3
4
5
6
7
10
11
12
13
14
15
16
17
20
十六进制
0
1
2
3
4
5
6
7
8
9
A
B
C
D
E
F
10
注意,十进制小数转换成其他进制小数时,结果有可能是一个无限位的小数。请看下面的例子:
十进制 0.51 对应的二进制为 0.100000101000111101011100001010001111010111...,是一个循环小数;
十进制 0.72 对应的二进制为 0.1011100001010001111010111000010100011110...,是一个循环小数;
十进制 0.625 对应的二进制为 0.101,是一个有限小数。
二进制和八进制、十六进制的转换
其实,任何进制之间的转换都可以使用上面讲到的方法,只不过有时比较麻烦,所以一般针对不同的进制采取不同的方法。将二进制转换为八进制和十六进制时就有非常简洁的方法,反之亦然。
1) 二进制整数和八进制整数之间的转换
二进制整数转换为八进制整数时,每三位二进制数字转换为一位八进制数字,运算的顺序是从低位向高位依次进行,高位不足三位用零补齐。下图演示了如何将二进制整数 1110111100 转换为八进制:
从图中可以看出,二进制整数 1110111100 转换为八进制的结果为 1674。
八进制整数转换为二进制整数时,思路是相反的,每一位八进制数字转换为三位二进制数字,运算的顺序也是从低位向高位依次进行。下图演示了如何将八进制整数 2743 转换为二进制:
从图中可以看出,八进制整数 2743 转换为二进制的结果为 10111100011。
2) 二进制整数和十六进制整数之间的转换
二进制整数转换为十六进制整数时,每四位二进制数字转换为一位十六进制数字,运算的顺序是从低位向高位依次进行,高位不足四位用零补齐。下图演示了如何将二进制整数 10 1101 0101 1100 转换为十六进制:
从图中可以看出,二进制整数 10 1101 0101 1100 转换为十六进制的结果为 2D5C。
十六进制整数转换为二进制整数时,思路是相反的,每一位十六进制数字转换为四位二进制数字,运算的顺序也是从低位向高位依次进行。下图演示了如何将十六进制整数 A5D6 转换为二进制:
从图中可以看出,十六进制整数 A5D6 转换为二进制的结果为 1010 0101 1101 0110。
在C语言编程中,二进制、八进制、十六进制之间几乎不会涉及小数的转换,所以这里我们只讲整数的转换,大家学以致用足以。另外,八进制和十六进制之间也极少直接转换,这里我们也不再讲解了。
总结
本节前面两部分讲到的转换方法是通用的,任何进制之间的转换都可以采用,只是有时比较麻烦而已。二进制和八进制、十六进制之间的转换有非常简洁的方法,所以没有采用前面的方法。
-
c语言中的进制转换
2021-05-20 10:04:381.2进位计数制及其转换计算机能够处理数值、文字、声音、图像等信息。读者也许会问:为什么作为电子设备的计算机能处理那么多复杂的信息呢?实际上,当把这些信息转换...本节将首先以常用的十进制为出发点,来讨论二... -
C语言中的二进制数、八进制数和十六进制数
2021-05-18 11:59:38二进制数、八进制数和十六进制数的表示一个数字默认就是十进制的,表示一个十进制数字不需要任何特殊的格式。但是,表示一个二进制、八进制或者十六进制数字就不一样了,为了和十进制数字区分开来,必须采用某种特殊... -
[c语言]进值转换的详细代码实现(二进制,十进制,十六进制等)
2021-10-24 15:30:04文章目录计算机进制以及进制转换计算机的多种进制:代码实现(正文):二进制转十进制:十进制转二进制:十六进制转十进制十进制转十六进制 计算机的多种进制: 今天给大家分享一下二进制,十进制,十六进制之间的转换... -
二进制十进制十六进制
2021-05-22 17:18:16原标题:二进制十进制十六进制在阿程学习C语言的过程中,我的室友和我说他不懂什么是二进制,什么是十进制。在这里,阿程将告诉大家什么是二进制,十进制和十六进制:我们平时使用的数字都是由 0~9 共十个数字组成的... -
c语言中的进制变换
2021-05-18 17:19:19c语言中的进制转换1.2进位计数制及其转换计算机能够处理数值、文字、声音、图像等信息。读者也许会问:为什么作为电子设备的计算机能处理那么多复杂的信息呢?实际上,当把这些信息转换...本节将首先以常用的十进制... -
二进制转十进制(BCD)码汇编算法(适用汇编初学者)
2021-05-21 11:54:10假若A是16位的二进制数字,转换的数学表达式如下:A = 2^15+2^14+.....2^1+2^0在转换的时候,待转换的数是16位(两字节),环路计数器是16次,最大的结果因有65535,所以至少要用2.5字节存结果,取整之后就是3个字节做... -
C 语言进制之间的转换
2021-05-20 07:15:52二进制、八进制和十六进制向十进制转换都是非常容易的,就是“按权相加”。所谓“权”,也即“位权”。例如,十进制第1位的位权为100=1,第2位的位权为101=10,第3位的位权为102=100;而二进制第1位的位权为20=1,第... -
将二进制、八进制、十六进制转换为十进制
2021-10-16 15:25:47上节我们对二进制、八进制和十六进制进行了说明,本节重点讲解不同进制之间的转换,这在编程中经常会用到,尤其是C语言。 将二进制、八进制、十六进制转换为十进制 二进制、八进制和十六进制向十进制转换都非常... -
C语言— —进制
2021-10-05 13:21:30进制转换2.1 十进制转换为其它进制2.2 其它进制转换为十进制2.3 二进制、八进制、十六进制之间的转换3. 二进制中的存储单位4. 原码、反码、补码4.1 原码、反码和补码4.2 为什么用补码存储整数?参考资料 1. 进制 本... -
C/C++编程笔记:C语言进制详解,二进制、八进制和十六进制!
2020-12-20 19:13:36我们平时使用的数字都是由 0~9 共十个数字组成的,例如 1、9、10、297、952 等,一个数字最多能表示九,如果要表示...因为逢十进一(满十进一),也因为只有 0~9 共十个数字,所以叫做十进制(Decimalism)。十进制是在... -
将二进制补码字符串转换为十进制整型数字
2021-07-02 17:43:43C语言把二进制转换为十进制数的方法和示例 代码如下:注释简单解释了下 #include<stdio.h> int main(void) { char input[20]; int dec; scanf("%s",input); dec = bin2dec(input); printf("%d\n",dec); ... -
JAVA中整数与C语言中十六进制的转换知识整合
2020-07-08 17:22:40十进制数(也就是我们平常使用的进制)16 0x10 十六进制(也叫HEX)表示方式 可以在JAVA中直接声明,byte num=0x10; 但这里有个问题,如果你直接声明num=0xd1会报错,这是为什么呢? 因为byte的取值范围是-128... -
10-C语言进制和位运算
2018-08-30 16:53:00进制基本概念 ...十进制、二进制、八进制、十六进制 进制书写的格式和规律 十进制 0、1、2、3、4、5、6、7、8、9 逢十进一 二进制 0、1 逢二进一 书写形式:需要以0b或者0B开头,例如: 0b101 八进制 0... -
C#IEEE754到十进制(C# IEEE754 to decimal)
2021-05-22 17:04:51C#IEEE754到十进制(C# IEEE754 to decimal)I got a HEX FLOAT IEEE 754 data, example "0x0017A8A6", how do I get it to decimal "1550502" in C#.Thanks.原文:https://stackoverflow.com/questions/36208341更新... -
C语言中一个字符对应一个ascii码;占一个1个字节8个二进制位;存到内存中也是用ascii的十进制的二进制表示
2021-05-19 09:26:47} LITTLE-ENDIAN(小字节序、低字节序) BOM——Byte Order Mark 字节序标记 数据在内存中的存放顺序 总结: 1. endian 字节存放次序 字节序,顾名思义字节的顺序,再多说两句就是大于一个字节类型的数据在内存中的... -
C语言项目设计——进制转换
2021-05-21 13:14:01《河海大学C语言项目设计》课程设计题目:...输入一个数,按要求转化成二进制,八进制,十进制。二、软件设计#include #include void erjz(__int64 n); void bajz(__int64 n); void sljz(__int64 n); int main() {in... -
16进制与10进制相互转化-C语言
2021-07-27 15:59:17char型数组转化为int数字,char型数组为16进制表示,其本质是byte与int类型的互相转化 byte不是一种新类型,在C++中byte被定义的是unsigned char类型;但在C#里面byte被定义的是unsigned int类型 以下双字节转换... -
进制转换:二进制、八进制、十进制、十六进制相互转换
2019-05-04 17:04:12将二进制、八进制、十六进制转换为十进制 二进制、八进制和十六进制向十进制转换都非常容易,就是“按权相加”。所谓“权”,也即“位权”。 假设当前数字是 N 进制,那么: 对于整数部分,从右往左看,第 i 位的...