Go to comments

PHP 进制详解

一、什么是数制

计算机内部只有二进制

计算机科学中经常使用的数制还有十进制、八进制和十六进制

进位计数制:简称数制

是按进位方式,进行计数的数制叫做进位计数制。

比如:逢十进一,是十进制

          逢二进一,是二进制

  逢R进一,是R进制

二、权值

日常生活中数数

1 2 3 4 5 6 7 8 9 -再往后数-> 10


10(读一零)

左数第二位的"1",代表10个

30

左数第二位"3",代表30个


同样的一个数字,在不同位置上,发挥的"重量"是不一样的(重量,是通俗的说法,术语叫权值)

1   -> 代表 1个

10  -> 一零中的1代表 10个

100 -> 一百中的1代表 100个


用术语来说,在不同位置上,发挥的"重量"叫"权值"

以十进制1234(一千二百三十四)为例

1234 = 1000 + 200 + 30 + 4 

+-------+-------+--------+-------+

 |     1    |     2      |     3      |     4    |

+-------+-------+--------+-------+  

 | 一千   |  一百    |     十     |   一     |

+         +           +            +          +

 |第四位 | 第三位 | 第二位  | 第一位 | 

+-------+-------+--------+-------+

第一位:权值是一        一 代表1          第一位数值(基数)是4,代表  4

第二位:权值是十        十代表10         第二位数值(基数)是3,代表  30

第三位:权值是一百   一百代表100     第三位数值(基数)是2,代表  200

第四位:权值是一千   一千代表1000   第四位数值(基数)是1,代表  1000

所以最终值是,1000 + 200 + 30 + 4 


继续归纳

第一位权值是1,      10的零次方,10^0

第二位权值是10,    10的一次方,10^1

第三位权值是100,  10的二次方,10^2

第四位权值是1000,10的三次方,10^3


PS: 常数项是零次方项。任何除0以外的数的0次方都是1 。如3的0次方是1,-1的0次方也是1,0的0次方没有意义。


那么回答问题

比如abcdef是十进制,十进制的abcdef的值是多少?

f*10^0  +  e*10^1  +  d*10^2  +  c*10^3  +  b*10^4  +  a*10^5

三、基数

在十进制中 0、1、2、3、4、5、6、7、8、9 在不同位置上,发挥的“权值”是不一样的

但是通过 0 ~ 9 这十个基础数,放在不同位置上,就有不同的权重,再组合起来,形成千变万化的数字。

因此0 ~ 9 这几个数我们叫做“基数”

一个是“基数”,一个是“权值”这两个概念形成进制的核心。

在十进制中基数是0 ~ 9,十进制中最大的基数是9,因为到十就进位了,把1进到第二位来表示了。

在M进制中,基数的最大值是M - 1

四、八进制

八进制的1234,值是多少?

个位:权值是8^0 = 1     基数是4   基数4 * 权值1     = 4

十位:权值是8^1 = 8     基数是3   基数3 * 权值8     = 24

百位:权值是8^2 =64    基数是2   基数2 * 权值64   = 128

千位:权值是8^3=512   基数是1   基数1 * 权值512 = 512

计算出来对应十进制:4 + 24 + 128 + 512 = 668


PHP中在数字1234前面加一个0,就按照八进制输出(js里也是)

echo 01234;  // 668

023前面加了一个0,按八进制输出的是19

/**
 * 个位3:还是3
 * 十位2:权值是8,基数2 * 权值8 = 16
 * 转换为十进制:3 + 16 = 19
 *
 */

echo 023; // 19

八进制的26,转十进制是22

/**
 * 22岁用八进制说是26岁
 * 26 / 8 = 商3 余数 2
 * 2  / 8 = 商0 余数 2
 *
 */
 
echo 026; // 22

0239,前面有0代表是八进制,而9超出八进制最大基数,怎么来理解?

/**
 * 0239前面加0是八进制
 * 而八进制的基数要比进制数小1,8减1,最大基数是7
 * 现在冒出一个9,自然是违法的,
 *
 * 碰到这情况
 * PHP5.0 会把后面的9舍弃,打印结果还是19
 * PHP7.0 报错 Parse error: Invalid numeric literal in
 *
 */
 
echo 02399999; // PHP5输出 19

echo 0239;     // PHP7输出 Parse error: Invalid numeric literal in

五、十六进制

十六进制比十进制的基数要多,碰16才进位,以为这0 ~ 15都是单个的基数来表示的

十六进制:0、 1、 2、 3、 4、 5、 6、 7、 8、 9、  a、   b、   c、   d、   e、   f

                 0、 1、 2、 3、 4、 5、 6、 7、 8、 9、 10、 11、 12、 13、 14、 15


ab(十六进制)

左数第一个:权值是16^0 = 1,  基数是b,值是b * 1

左数第二位:权值是16^1 = 16,基数是a,值是a * 16 


数字前面加"0x",按十六进制输出

十六进制的0x24,转成十进制是多少?

/**
 * 个位4,基数是4,权值是16^0, 基数4 * 权值1 = 4 
 * 十位2,基数是2,权值是16^1, 基数2 * 权值16 = 32
 * 32 + 4 = 36
 *
 */

echo 0x24; // 36

年龄按十六进制,0x1c是多少岁?

/**
 * 0x1c,0x按十六进制
 * 1代表16
 * c代表12
 * 16 + 12 = 28
 *
 */
$age = 0x1c;

echo $age; // 28

六、程序员的冷笑话

为什么,程序员分不清,圣诞节和万圣节?

圣诞节:12月25日,dec代表十二月,dec25

万圣节:10月31日,oct代表八月,oct31


进制的英语

Dinary               二进制

Decimal            十进制

Octonary          八进制

HexaDecimal   十六进制


在程序员眼里

dec25 --> 是十进制的25

oct31 --> 是八进制的31 --> 转成十进制是25(3*8 + 1 = 25)

七、二进制

二进制,基数只能是1,0两个

二进制的10(一零),相当于十进制的2


二进制1101

从左到右

左数第一位:基数是1,权值2^0=1,基数1 * 权值1 = 1

左数第二位:基数是0,权值2^1=2,基数0 * 权值2 = 0

左数第三位:基数是1,权值2^2=4,基数1 * 权值4 = 4

左数第四位:基数是1,权值2^3=8,基数1 * 权值8 = 8

转换成十进制:1 + 0 + 4 + 8 = 13


在PHP5.4后,引进了二进制的直接表示,数字前加0b

echo 0b1101;  // 13

PHP版本

echo PHP_VERSION;

八、进制练习题

1、李开复在一个节目出的题

某珠宝商,有31颗明月珍珠,光芒夺目

此商人呢,把珍珠分成了若干盒,每盒的珠子数量都不一样。

分完后,发现特别巧,

你想买1-31颗之间的珠子,

此商人,都能正好取出其中若干盒,正好能组成你要买的数量


思考:分成了几盒?每盒又各是多少颗珠子呢?


比如买15颗珍珠,正好把其中的三个盒子 或 两个盒子拿出来,

这三盒加在一起、或这二盒加一起,就正好是15颗。

比如买17颗,这四盒加在一起正好是17颗

总之,想买1至31之间数量的珠子,总能单拿出几盒正好组成想买数量。

要想解决这个题,就要用到进制的知识


计算机中有一门很重要的课叫"信息论"

一种东西,他的状态,能用来标识信息

比如,一只眼睛,能睁眼,能闭眼,能代表两种状态(态位)

想用来表示心情,最多能表示两种,因为态位有限,要么表示心情好,要么表示心情坏,

如果用两只眼睛,组合起来就能表示四种心情

比如:

0 1

1 0

1 1

0 0 


重点分析这句,正好取出其中若干盒


每盒有几种状态?

每盒有两种状态,要么取,要么不取,不能把盒子拆开

可以标记为,取就是:1,不取就是:0


因此,[1/0]    [1/0]    [1/0]    [1/0]    [1/0]

         权值16  权值8   权值4   权值2   权值1


用二进制来分析

左数第一盒权值是 1

左数第二盒权值是 2

左数第三盒权值是 4

左数第四盒权值是 8

左数第五盒权值是 16

取或者不取是1和0,代表二进制的两种态,盒子里面不同的数字1、2、4、8、16代表权值,我们就可以任意组合了


比如:

17 = 二进制的10001,取第五盒 + 第一盒


29 = 而进制的11101,取第五盒 + 第四盒 + 第三盒 + 第一盒 

29 / 2 = 14 余数1

14 / 2 = 7   余数0

7  / 2 = 3    余数1

3  / 2 = 1    余数1

1  / 2 = 0    余数1

29转换二进制1  1 1 0 1

                   16  8 4    1

2、还有一个题

8瓶水,其中一瓶有毒,拿小白鼠做实验

药效发挥,需要需要2个小时,才能让小白鼠死

只给两个小时时间

问,最少,需要几只老鼠?


分析:

需要2个小时,只给两个小时,推测出我们只有一次机会

两个小时之后,小白鼠只有两种状态:死,活

一只小白鼠有两种状态,2只小白鼠则有四种组合状态,N只小白鼠则有2^N次方组合状态

一共有8只小白鼠,最多需要八种状态,就能区分

一只老鼠2种状态,两只老鼠4种状态,三只老鼠8种状态

abcd -> abc死 c活

         ->

从理论上说三只老鼠足够了,把8个瓶子试出来了

4 2 1

3、第三题

有个商人,不小心把40磅的砝码摔碎了,摔成了4块,

欲哭无泪时发现,这4块砝码恰好可以组合能1 - 40的任意重量,

求这4块碎砝码的质量

提示:组合的意思不是单纯的相加,因为天平,你懂的。

          例如,2 = 3 - 1

          意思是没有2克的砝码,可以用3克减1克

分析:

某一块砝码可以放左边,也可以放右边,也可以不放

也就是说一个砝码表示,3种态位

可以标识为0 1 2

[0/1/2]  [0/1/2]  [0/1/2]  [0/1/2]

  权值1

以上可以组合出一个三进制数字来


想表示出连续的数字来,每个位上的权值,也要符合三进制的规律

权值是:27 9 3 1  


1 <--> 1

2 <--> 3 - 1

3 <--> 3

4 <--> 3 + 1

5 <--> 9 - 3 - 1

……

……




40 / 2 = 20 余数0

20 / 2 = 10 余数0

10 / 2 = 5     0

5  / 2 = 2     1

2  / 2 = 1     0

1  / 2 = 0     1


0010 1000

 32    8  


40 / 4 = 10  0

10 / 4 = 2   2

2  / 4 = 0   2

  

2   2   0

16  4   

32  8  





Leave a comment 0 Comments.

Leave a Reply

换一张