今儿看到了破败之王的bug,一级团杀了人变成了对面,然后送塔,戒指就变成了很夸张的层数。

视频如下:

https://www.bilibili.com/video/BV1yr4y1A7Mo

一开始我也只是觉得好夸张啊,这什么玩意儿。但是看到杀人戒的层数,瞬间就大概明白怎么回事了。

下面粗略说一下思路,可能不对,但是原理应该差不多。

先看看戒指层数:

65534!学计算机的可能立马就会想到2的16次方,也就是65536。

众所周知,计算机中的数据都是用二进制表示的,杀人戒的层数肯定也是用的一个二进制的值表示的。而根据65534这个数字,基本可以断定这个值用的是16bit的内存来记录的。

如果是1层杀人戒,内存里存的就会是:

0000000000000001,16位,最后一位是1。

2层的呢,就是

0000000000000010。

这个二进制表示我就不多做赘述了,大家感兴趣的可以查一下。

这个视频里,是破败之王击杀了牛头,戒指本应该是+2的,但是却变成了65534,那么65534在内存中怎么表示的呢?

1111111111111110。

这时候就要引入另一个概念了,补码。前面所说的都是原码,是不能表达负数的。而表达负数,就要用补码了。这个具体原理这里也不引申了,就是一种 内存字节 ->实际值的表达方式。

65534用原码表示是1111111111111110,而1111111111111110这一坨二进制内存,如果用补码表示,它代表的值就是-2!

这个就是关键了!65534和-2在不同的编码方式中,所对应的二进制是一样的。

再想一下杀人戒的属性,杀人应该是+2的,但是此时破败之王变成了敌方单位,是不是这里的代码有bug,将+2就给算成了-2?

然后算戒指层数的时候,程序员用的是补码,-2就是1111111111111110。

而读取戒指层数时,另一个程序员却用了原码,1111111111111110就读取成了65534(原码和补码在表示比较小的正数时是完全一样的,所以正常情况下戒指层数也不会读错)。

这样就完全对的上了。。

溢出了的话不应该是65534,出现65534应该就是我描述的这样了,程序本身有bug,原码和补码也用混了。

最新文章

  1. 自定义样式 实现文件控件input[type='file']
  2. HDU 5033 Building
  3. Android动画设计源码地址
  4. django 快速实现session的操作
  5. hdu 1561 The more, The Better (树上背包)
  6. 232. Implement Queue using Stacks
  7. win10任务视图
  8. C++ 编程输入输出语句
  9. thinkphp+mysql+bootstrap
  10. java学习之i/o
  11. paip.自适应网页设计 同 响应 与设计的原理的差and实践总结
  12. 基于Selenium2+Java的UI自动化(8)- 显式等待和隐式等待
  13. JAVA-Servlet-过滤器知识总结
  14. nova创建虚拟机源码分析系列之七 传入参数转换成内部id
  15. appium滑动操作(向上、向下、向左、向右)
  16. ISP PIPLINE (二) LensShading Correct
  17. 【Storm】Storm实战之频繁二项集挖掘(附源码)
  18. svn更新项目之后,项目报错一大堆并且tomcat部署项目时找不到项目
  19. 理解java的三大特性之继承
  20. FIFO的使用总结

热门文章

  1. WSL2 使用Docker运行.NET Core
  2. SpringSecurity简单使用
  3. Keepalived+LVS实现LNMP网站的高可用部署
  4. codeforces 911D
  5. spring-cloud-netflix-eureka-server
  6. HDU 4280 Island Transport(HLPP板子)题解
  7. Object Destructuring Assignment vs Object.assign
  8. Protocol Buffers All In One
  9. JWT & JSON Web Tokens
  10. learning-js-by-reading-source-codes