详细解释2进制,10进制,16进制,8进制,36进制

本篇介绍C/C++语言中的进制的概念,主要介绍2进制、10进制、16进制,这三种是编程时必须掌握的也是最常用的。另外,介绍8进制和36进制,其中 36进制在实际工程项目中会遇到。 (本文选自《C/C++学习指南》,邵发,附录“2进制,10进制,16进制”)

权利声明:作者拥有本书的全部权利。作者授权任何人都可以自由转载本网站发布的内容,但转载时必须遵守以下限制:
①转载时必须全文转载,不得有任何修改,必须包含“权利声明”和“官网地址” ② 仅限于网络转载,即最终结果公布于网络上。凡是不遵守以上两条的转载行为视为侵权行为。除非本人允许,任何人不得将本网站内容内容用于任何的其他用途。

官网地址: http://www.afanihao.cn
留言请到http://www.afanihao.cn/kbase/

1.1         引例一

先给出一段代码,请读者现在立即编译运行一遍,观察结果。

#include <stdio.h>
void main()
{
       int a = 'A';
       int b = 65;
       int c = 0x41;
       printf("%d, %d, %d \n", a, b, c);
}

如果你还没有动手编译,那么请立即终止阅读本书,因为本书不是为太懒的人准备的。所有代码和示例,请读者务必自己手打一遍,不要拷贝。如果你是拷贝过去的,请立即烧掉本书,谢谢。

你会发现,输出结果为:

是的,变量a,b,c的值完全相同。实际上,这三种初始化(赋值)方法是完全等价的,只是写法不一样而已。你用哪一种办法都可以。

1.2         引例二

再给出另一段代码,请立即编译和运行一下:

#include <stdio.h>
void main()
{
       char  a = 65;
       printf("%d,  %02X ,  %c \n",  a,  a,  a);
}

它的运行结果为:

是的,对于同一个整数a,当它作为十进制显示时,显示为65;当作为十六进制显示为,显示为41,当作为字符显示时,显示A。

1.3         引例三

如果上面的例子给你的印象还不够深刻,再尝试一个例子:

#include <stdio.h>
void main()
{
       // 以下变量a和b的值是相同的
       int a = 0x12345678;
       int b = 305419896;
       printf("%d, %d \n", a, b);

       // buf的内容为"ABC"
       char buf[4] = { 0x41, 66, 'C' , 0};
       printf("%s \n", buf);
}

结果为:

1.4         整型变量的2进制表示

本节内容对理解本章乃至全书都极为重要,如果你理解了,那么所谓进制问题对你就不再是个问题。

首先,在第三章中已经明确的强调,每个变量都是具有一个内存地址的。对于char型变量来说,在内存中占了1个字节。对于int型变量来说,在内存中占了4个字节。为了让你更容易的理解,我们就先从char开始吧。

然后,我们看一下在计算机的内存里,倒底是怎么存储的。我们从最最简单的数开始。例如,定义一个变量 char  a = 13,此变量a占了一个字节的内存。在内存中,一个字节有8个位(bit),每一个位可以是1或0。那么a的表示为:


0


0


0


0


1


1


0


1

就是说,在物理内存中,它就是这么存储的。至于物理上如何表示1,如何表示0,读者是不需要关心的。你可以简单地认为一个位就对应一个“开关”,1表示打开,0表示关闭。以后,我们就称它的按位表示为 0000 1101 。

所以,char  a = 13 或者char  a = 0x0C ,这两种写法表示的意思是一样的:分配一个变量,对应一个字节,字节的按位物理表示为 0000 1101。

明白了吗?所谓10进制还是16进制是对人类而言的,不是同的说法。但是对于计算机而言,要存储这个数值,就是要用8个位(对应8个物理开关)。这是哲学上的“形式和内容”的关系。

反过来,已经知道一个变量a的内存表示为 0000 1101,我们想在控制台上把它的值显示出来。那么可以按10进制显示,也可以按16进制显示。

对你是小学生水平,那好吧,作为程序员我只好给按10进制显示给你了。

printf (" %d  ",  a);

如果你有碰巧看过本书,那好吧,我给按16进制显示:

printf(" %02X ", a);

1.5         进制换算

这一节介绍的是数学里的内容。作者的数学水平不高,在这里只能让你大概地理解一下。实际上,正如作者一再强调的,编程不需要太高的数学水平,几乎对数学是没有要求的。

首先,说说从16进制到10进制的换算。我们知道,0x41(十六进制) 和65(十进制)是等价的。那么怎么手工计算呢?下面给出示例:(以下不是代码,是在草稿纸的手算方法

0x41  =  4 * 16  + 1  = 65

0x12345678 = 1 * 167 + 2 * 166  + 3*165 + 4 * 164 + 5 * 16+ 6 * 162 + 7 *161 + 8 = 305419896

可以看出,对于16进制,每一个数字上的权重就是 16n-1  (即16的n-1次方)

然后,说说从2进制到10进制的换算。

0000 1101 =   0 + 0 + 0 + 0 + 8 + 4 + 0 + 1 = 13

或者严格一点:

0000 1101 =   0 + 0 + 0 + 0 + 23 + 22+ 0 + 1 = 13

可以看出,对于2进制,每一个数字上的权重就是2n-1(即2的n-1次方)

1.6         如何打印2进制

在printf参数中,使用控制符%d可以按10进制打印,使用%X可以按16进制打印,那么,有没有按2进制打印呢?

很遗憾,printf不能直接打印二进制。为了弥补这个遗憾,作者贡献一个按2进制打印的函数。

#include <stdio.h>

// 把一个整数转成二进制字符串
// value: 输入整数
// buf: 输出字符串
// num_of_bits: 指定要打印的位数
void to_binary(unsigned int value, char buf[], int num_of_bits)
{
       for(int i=0; i<num_of_bits; i++)
       {
              unsigned int mask = 1 << (num_of_bits -1 - i);
              if ( value & mask)
                    buf[i] = '1';
              else
                    buf[i] = '0';
       }
       buf[num_of_bits] = 0;
}

void main()
{
       char buf[33];
       to_binary(135, buf, 8);
       printf("%s \n", buf);
}

1.7         8进制

8进制在工程实际中一般不会用到,这个用法没有价值。和前面的类似,8进制表示每个数字的权重是8n-1(即8的n-1次方)。例如,15(八进制)等于13(十进制)。

在C/C++语言中,八进制的字面常量以0开头。例如下面的代码,

#include <stdio.h>
void main()
{
       int a = 015; // 以0开头表示八进制
       int b = 0x0D; // 以0x开头表示十六进制
       int c = 13;  // 十进制

       printf("%d, %d, %d \n", a, b, c);
}

1.8         36进制

正如序列 0, 1, 2, ..., 9, A, ..., F来表示16进制一样,用序列0, 1, 2, ...,9, A, B, ..., Y, Z来表示36进制。其运算方法也完全是一样的,每一个数字的权重是36n-1(36的n-1次方)。

例如,(以下不是代码,是草稿纸上的手算方法)

2Z = 36 * 2  + 35 = 107

事实上,36进制在工程实践中是一个很有用的知识。比如,同样用4个字符来表示数字,使用10进制可以表示0000~9999,使用16进制可以表示0000~FFFF,使用36进制可以表示0000~ZZZZ。可以,使用36进制的表示能力最强。

时间: 2025-01-08 10:44:55

详细解释2进制,10进制,16进制,8进制,36进制的相关文章

详解2进制,10进制,16进制,8进制,36进制

本篇介绍C/C++语言中的进制的概念,主要介绍2进制.10进制.16进制,这三种是编程时必须掌握的也是最经常使用的.另外,介绍8进制和36进制,当中 36进制在实际project项目中会遇到. (本文选自<C/C++学习指南>.邵发.附录"2进制,10进制,16进制") 讲2进制.10进制.16进制的视频教程,点击观看 权利声明:作者拥有本书的所有权利. 作者授权不论什么人都能够自由转载本站点公布的内容,但转载时必须遵守下面限制: ①转载时必须全文转载.不得有不论什么改动,

ORACLE 36进制和10进制,互相转换函数

第一部分 --36转10进制 create or replace function f_36to10 (str varchar) return int  is returnValue int;   str36     varchar(36);   subWork   varchar(1);   workIndex   int;   len     int;   i       int; begin returnValue:= 0;   str36 := '123456789ABCDEFGHIJK

10进制正整数转4位定长的36进制字符串

题目描述: 请设计一个函数可以把10进制的正整数转换为4位定长的36进制字符串. 36进制的规则为:“0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ”; 举例说明: 1=“0001” 10=“000A” 20=“000K” 35=“000Z” 36=“0010” 100=“002S” 2000=“01JK” 这是腾讯2015校园招聘技术类研发笔试题中的一题,给出自己的答案,欢迎拍砖. solution: string convert(int x) { string re

Oracle 10进制转36进制

CREATE OR REPLACE FUNCTION IDFMS.func_dec236 (parm IN INT DEFAULT 0)   RETURN VARCHAR2IS   /*   10进制数转36进制数   */   src   VARCHAR2 (36) := '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'; --改成其它字符串,就是任意进制   LEN   INT;   res   VARCHAR2 (10) := '';   tmp   INT; 

PHP生成唯一编号 36进制不重复编号

PHP实现生成唯一编号,文中使用10进制转换36进制得到不重复的6000多万个唯一编号,编号位数为10位. 当要将一个庞大的数据进行编号时,而编号有位数限制,比如5位的车牌号.10位的某证件号码.订单流水号.短网址等等,我们可以使用36进制计算出符合位数的不重复的编号.我们将0-Z(0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ)分别代表数值0-35,如字母Z代表35.这样的话我要得到一个5位的编号,最大信息量就是36的5次方了,36^5 = 60466176,即最大的

36进制加法

36进制由0-9,a-z,共36个字符表示,最小为’0’, ‘0’.'9’对应十进制的09,‘a’.'z’对应十进制的1035 例如: '1b' 换算成10进制等于 1 * 36^1 + 11 * 36^0 = 36 + 11 = 47 要求按照加法规则计算出任意两个36进制正整数的和 如:按照加法规则,计算'1b' + '2x' = '48' 要求: 不允许把36进制数字整体转为10进制数字,计算出10进制数字的相加结果再转回为36进制 思路按照十进制的加法方法,满36向前进一位 public

将16进制字符串转换成16进制数据

var tb1 = Tb1.Text; if (string.IsNullOrEmpty(tb1)) { tb1 = "0000"; } var s1 = tb1.Substring(0, 2); var int_1 = Convert.ToInt32(s1, 16); var s2 = tb1.Substring(2, 2); var int_2 = Convert.ToInt32(s2, 16); var bt1 = Convert.ToByte(int_1); var bt2 =

13 * 16 = 244 解这些数是什么进制数 -- C

/* 13 * 16 = 244 设为x进制数 解: (1*x + 3) * (1*x + 3) = 2*x^2 + 4*x +4 x^2 + 9x + 18 = 2x^2 + 4x + 4 x^2 - 5x - 14 = 0 (x - 7)(x - 2) = 0 解得: x = 7 或者 x = 2 接下来不用说了.. */ 13 * 16 = 244 解这些数是什么进制数 -- C

36进制流水

public class CodeManage{ String pk="1000000000"; int n=500; public CodeManage(){ BigInteger src=new BigInteger(pk,36);// 36进制 for(int i=0;i<n;i++){ src=src.add(new BigInteger("1",2)); System.out.println(src.toString(36)); } } } 原文地址