惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

SecWiki News
SecWiki News
I
InfoQ
The Cloudflare Blog
人人都是产品经理
人人都是产品经理
博客园 - Franky
T
Tailwind CSS Blog
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
量子位
博客园_首页
罗磊的独立博客
V
V2EX
李成银的技术随笔
大猫的无限游戏
大猫的无限游戏
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
T
True Tiger Recordings
Vercel News
Vercel News
Cyberwarzone
Cyberwarzone
Cisco Talos Blog
Cisco Talos Blog
F
Fox-IT International blog
D
Darknet – Hacking Tools, Hacker News & Cyber Security
M
Microsoft Research Blog - Microsoft Research
Know Your Adversary
Know Your Adversary
爱范儿
爱范儿
The Register - Security
The Register - Security
G
Google Developers Blog
The Hacker News
The Hacker News
Malwarebytes
Malwarebytes
S
Securelist
博客园 - 三生石上(FineUI控件)
Jina AI
Jina AI
T
Threat Research - Cisco Blogs
T
The Exploit Database - CXSecurity.com
S
SegmentFault 最新的问题
博客园 - 叶小钗
F
Fortinet All Blogs
Apple Machine Learning Research
Apple Machine Learning Research
宝玉的分享
宝玉的分享
博客园 - 聂微东
T
Threatpost
博客园 - 【当耐特】
D
Docker
P
Privacy & Cybersecurity Law Blog
www.infosecurity-magazine.com
www.infosecurity-magazine.com
G
GRAHAM CLULEY
V
Visual Studio Blog
C
Cisco Blogs
IT之家
IT之家
S
Security Archives - TechRepublic
Latest news
Latest news
阮一峰的网络日志
阮一峰的网络日志

浮华生

Elasticsearch 检索性能优化 舆情监控系统综述 2024 半年度总结 2023 年终总结 - 浮华生 异地机器组网方案 Kubernetes 部署 Elasticsearch 和 Kibana 2022 年终总结 RabbitMQ connection channel 的关系 Kafka Java 客户端 Producer 原理分析 RabbitMQ 和 Kafka 应用原理简单对比 阿里云 OpenSearch 介绍 Golang Array 和 Slice 区别 - 浮华生 Mac OS 下打造 golang nvim 编程环境之基础配置 电商搜索技术总结 电商搜索业务总结 2021 年终总结 Cypress 实践总结 年终总结 关于我 使用 cucumber 进行行为驱动开发(BDD) 微服务应用集成 SpringCloud 步骤 电商搜索数据同步方案 - 浮华生 macOS 系统推荐的一些软件 - 浮华生 DevOps 实施规划(持续更新) rabbitmq 如何提高可靠性并保证消费端幂等 AMQ Model总结 结对编程 RSocket 介绍 面向对象的理解 企业平台技术框架 对创业的思考 - 浮华生 知难行易 - 浮华生 一年工作经验总结 - 浮华生 我与领域驱动之缘 TDD 中使用的工具 tf-idf 算法 gitlab 添加代码规范检测 query 改写 阶段性总结 操作系统作用 无标题 hamming-distance ElasticSearch API 基本操作 elasticsearch 集群容错 ElasticSearch 基础概念 技术选型怎么做 条件概率、全概率与贝叶斯公式 年终总结 迁移到 ubuntu18 的问题及配置 总结 使用 psi-probe 监控 Tomcat Tomcat 远程 Debug jstack 死循环和死锁定位 jmap & mat 内存溢出 JVM 常用参数查看 - 浮华生 周总结(8.13-8.19) - 浮华生 周总结(7.30-8.4) 使用移位运算符 master 公式 - 浮华生 VMware 12 NAT网络下配置 ubuntu 16.04 LTS 系统静态 IP - 浮华生 关于进制的计算 项目总结 第三篇 项目总结 第二篇 editor.md 富文本编辑器的使用 项目总结 第一篇 - 浮华生 2017至今总结 谈谈微服务 单例模式 - 浮华生 tor 使用 归档 搜索 - 浮华生 搜索 && 推荐
通过一道数值转换题重温计算机补码 - 浮华生
2020-07-02 · via 浮华生

问题

昨天同事和我聊了他偶然间看到的一道面试题,引出了后面的深入分析。

1
System.out.println(Integer.valueOf((char)-1)); //output: 65535

为什么输出是 65535 而不是 -1 呢?

分析

先回顾一下计算机相关的知识点:

原码(True form)

原码是指一个二进制数左边加上符号位后所得到的码,且当二进制数大于0时,符号位为0;二进制数小于0时,符号位为1;二进制数等于0时,符号位可以为0或1(+0/-0)。 –维基百科

原码根据符号位能很直观的看出是正数还是负数,但是对于计算机运算来说却不是那么好用了,比如:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
# 求解: 1 + (-1) 
---
站在人类的视角会立马得出 1 + (-1) = 0 的结论
---
而计算机的角度(假设长度是8-bit):
转换成二进制并相加:
  00000001
+ 10000001
 ----------
  10000010
 
这个结果是:-2,与正确值不符

所以如果有负数使用了原码运算,那还得把符号位撇开,这就增加了使用成本,为了解决这个问题就出现了反码。


反码(ones' complement),也叫一的补码

二进制数每个数字反转,得到的数即为原二进制的一的补码(英语:ones' complement)。若某一位为0,则使其变为1,反之亦然。

  • 一的补码以有符号比特的二进制数定义。
  • 一的补码是有符号比特的二进制数。
  • 正数和0的一的补码就是该数字本身。–维基百科

反码能解决负数运算的问题吗,可以,但是又会出现负零循环进位的问题。举例:

1
2
3
4
5
6
7
8
9
# 求解  1 + (-1)
---
转换成二进制并取反相加
  00000001 (正数的反码是它本身)
+ 11111110 (符号位不变其余取反)
------------
  11111111 
转换成原码为:100000000 = -0
  

对于 0 来说正负并没有意义, 而且还会有反码 0000 0000 和 1111 1111 这两种 0 的表现形式,在使用反码运算时判断是否为 0 还需要考虑这两种情况,为了解决这个问题就又出现了补码。


补码(2’s complement)

正数和0的补码就是该数字本身。负数的补码则是将其对应正数按位取反再加1。

补码系统的最大优点是可以在加法减法处理中,不需因为数字的正负而使用不同的计算方式。只要一种加法电路就可以处理各种有号数加法,而且减法可以用一个数加上另一个数的补码来表示,因此只要有加法电路及补码电路即可完成各种有号数加法及减法,在电路设计上相当方便。

另外,补码系统的0就只有一个表示方式,这和反码系统不同(在反码系统中,0有二种表示方式),因此在判断数字是否为0时,只要比较一次即可 –维基百科

补码有一个原则:数字a的补码为 -a,举例:

1
2
3
4
# a = -5,那么 a 的补码为 5
10000101  # -5 的原码
11111010  # -5 的反码
11111011  # -5 的补码 

解答

上面的问题可以拆分成下面的代码便于分析

image-20200707094407456

int(32-bit) 转 char(16-bit) 会失去精度

1
2
3
4
1000 0000 0000 0000 0000 0000 0000 0001   #int -1 的原码
1111 1111 1111 1111 1111 1111 1111 1111   #int -1 的补码(内存中的数值用补码表示 0Xffffffff) 
                    1111 1111 1111 1111   #char 只保留 16 位;10进制为 65535
0000 0000 0000 0000 1111 1111 1111 1111   #再转换成 int 执行零扩展;10进制同样为 65535             

扩展

溢出

符号扩展与零扩展

循环进位