大概在06年,我看到了一本书,叫做<<深入Java虚拟机>>。

在周志明那本神书《深入理解Java虚拟机》出来之前,这本书应该是唯一一本讲JVM的书, 对Java class文件格式,执行引擎讲得特别详细。

我看了一遍看完了以后就“热血沸腾”:原来Java 的class 文件格式是这样的啊!也许我也可以写一个JVM了!

于是我就开始琢磨, 先写程序去解析.class文件, 然后写一个小的执行引擎,去执行那些字节码。

作为第一步,我要写个小程序去读取硬盘上的.class文件,然后看看它的头四个字节是不是著名的魔数:“CAFE BABE

第一个字节实际的输出结果让我大跌眼镜: -54 !

这是怎么回事呢?说好的CA呢?

这个问题让我想了很久,后来终于想明白了,CA 是16进制字符,变成二进制就是 1100 1010 , Java内部使用补码表示数字的,把1100 1010看作二进制补码,它对应的十进制可不就是-54嘛!

原来都是补码惹的祸!

那计算机为什么用补码呢?一个重要的原因就是简化电路的设计:把整数的加减法统统变成加法来运算。

比如一个4位的计算机,能表示的数字是 0 ~ 15

在做加法的时候非常简单:

8+3(十进制) = 1000 + 0011 = 1011 = 11 (十进制)

我们可以设计一套简单的数字电路(与门,或门等)来实现这个加法运算。

但是减法怎么办呢?难道再设计另外一套电路?这就浪费了。

于是人们就引入一个‘补数 '的概念, 例如 3的补数 是 13, 4的补数是12,  5 的补数是11......

当你计算7减去3 的时候, 可以变成 7加上3 的补数, 即 7 + 13 :

7-3 = 0111- 0011 (二进制3) = 0111 + 1101(二进制13) = 10100

10101已经是5位了,溢出了, 去掉最高位是 0100 ,就是十进制4 了。

那二进制的“补数”怎么得出呢?人们想出了一个异常简单, 又特别适合计算机电路的算法, 对二进制数的所有位取反, 然后加1

3 -> 0011 -> 1100 (取反) -> 1101 (加1)

这种方法是不是很神奇?只用一套加法电路和补码电路就可以高效地实现加法和减法了。

等等,负数怎么办?我们手写的时候,可以在一个数前加个负号, 就可以表示,但是对计算机来说,它必须得用某一位来表达正负,比如用这种方法:

最高位的0 表示整数,1 表示负数。

真正有效的数字只剩下3位了, 正数的范围是从1 到7 ,负数的范围从 -1到-7 ,不过这里出现了两个零!一个正0 , 一个负0 , 这肯定不好!

改进一下,把那个负0 认为是-8吧,这样还能多表示一个数字!

这样,数字的范围变成了从[-8 ,7]  。

推广一下,在编程语言中,对于n位整数,它的取值范围是[-2^(n-1) ~ 2^(n-1) - 1]  ,正数要比负数少一个。

但是之前的减法变加法的规则还能用吗?我们试试:

7-4  = 7+(-4) = 0111 +1100 = 10011 -> 0011 (舍掉最高位) = 3, 正确!

4-7 = 4+(-7) = 0100 + 1001 = 1101 = -3  ,正确!

注意,用这种办法,连符号位都参与了运算

总结一下, 在计算机内部,是使用补码来表示二进制数, 如果是一个正数, 补码就是它本身,  如果是个负数, 需要把除了符号位之外的二进制数进行取反加一的操作。

回到我们开头的问题, 如何正确地把第一个字节变成16进制字符串“CA”,然后展示出来呢?用这个函数就可以了:

传说中的CAFEBABE到底在哪儿?相关推荐

  1. 传说中的贝叶斯统计到底有什么来头?

    传说中的贝叶斯统计到底有什么来头? 2016-08-17 20:37 Blake 0条评论 贝叶斯统计在机器学习中占有一个什么样的地位,它的原理以及实现过程又是如何的?本文对相关概念以及原理进行了介绍 ...

  2. 传说中的RNN到底是何方神圣?

    假设你已经知道最基本的人工神经网络模型(也就是全连接的前馈神经网络),那么希望本文可以帮助你理解RNN,也就是传说中的循环神经网络.严格来说,本文是综合了(或翻译了)网上若干最容易理解.写得最棒的文章 ...

  3. 2018年终总结之最大遗憾 --- 没能看到传说中的‘断桥残雪’

    2018年终总结之最大遗憾 --- 没能看到传说中的'断桥残雪' 今年下半年,笔者有幸拿到杭州的某项目,要在杭州待上大半年.来之前对于西湖早已慕名很久,而对于传说终的断桥残雪则更是神往已久. 断桥残雪 ...

  4. 韩信竟是数学大师?中国古代数学启发计算机加密算法

    点击上方"AI遇见机器学习",选择"星标"公众号 重磅干货,第一时间送达 晓查 明敏 发自 凹非寺 量子位 报道 | 公众号 QbitAI 没想到,古代韩信点兵 ...

  5. ★ 省时省力又省钱--快来看win7家庭版升级旗舰版 ★

    看到标题心动了吧,你肯定在想 省时省力又省钱!!哪有这么好的事,还是听我说说吧 win7刚发布的时候,很想见见传说中的win7到底长什么样 嘿嘿,后来从导师那里要来一个win7的ISO带key的 然后 ...

  6. 百度发布智能电视伴侣,并公布短视频计划

    百度发布智能电视伴侣及小度在家1S 不同于2018年两次发布会的高调,这一次的新品发布会一直笼罩在某种神秘感里,从接到通知到走进发布会现场,参会者对这次的新品一无所知. 2018年3月,同样的地点,百 ...

  7. Spring AOP介绍及源码分析

    2019独角兽企业重金招聘Python工程师标准>>> 软件开发经历了从汇编语言到高级语言和从过程化编程到面向对象编程:前者是为了提高开发效率,而后者则使用了归纳法,把具有共性的东西 ...

  8. 切图教程,app切图命名总结

    再根据自己的习惯对APP切图命名进行整理总结. 结语: 作为一个有强迫症的设计师,希望产出是有缜密的思维逻辑,当然包括细节. 文字有的部分参考其它文章,整理后根据自己的工作经验作出的总结. 自己也还在 ...

  9. 一款APP从设计稿到切图过程全方位揭秘 Mark

    纯干货!一款APP从设计稿到切图过程全方位揭秘 @BAT_LCK :我本身是一名GUI设计师,所以我只站在GUI设计师的角度去把APP从项目启动到切片输出的过程写一写,相当于工作流程的介绍吧.公司不同 ...

最新文章

  1. android自定义组合view,自定义View之组合View
  2. 依赖注入利器 - Dagger ‡
  3. Simulink之功率场效应晶体管(P-MOSFET)
  4. ARM Cortex-M0(1)---浅谈ARM Cortex-M0
  5. 48.怎样消除桌面图标上的小箭头:
  6. SQL server 2008 r2导入数据
  7. 电信光猫获取超级账户和密码
  8. 【转载】高斯滤波器详解
  9. 合泰单片机驱动步进电机程序
  10. R语言|使用RGL包构建3D 图形(一)
  11. STM32F103_study69_The punctual atoms(STM32 SPI communication principle and configuration)
  12. 悉尼大学INFO1112Assignment1课业解析
  13. JavaScrpt LRC歌词同步 和 es6 的 fetch 的 async/await 和 promise 两种写法
  14. 大数据来临,商业银行面对合规挑战!
  15. 关于ssl证书:pem转成crt文件的最简单方法:直接改后缀名!
  16. 消失与存续——应用交付行业的跌宕演进
  17. Android 开发新技术:Jetpack Compose当仁不让
  18. wechat-web-devtools 之linux
  19. 31.企业快速开发平台Spring Cloud+Spring Boot+Mybatis之Highcharts 向下钻取柱形图
  20. 计算机科学技术的道与术

热门文章

  1. SIFT(ASIFT) Matching with RANSAC
  2. 最近的状态很不好,需要调整
  3. CCF NOI1010 邮寄包裹
  4. 一道比较实用的MySQL面试题:游戏数据充值查询
  5. XML Schema学习
  6. sass 在线转换器
  7. Python初学者之ModuleNotFoundError:No module named 'cv2'简单解决办法
  8. 详解EM算法与混合高斯模型
  9. matlab中print、fprintf、scanf、disp函数简要语法介绍
  10. 使用异步 I/O 大大提高应用程序的性能