DNF阿拉德游戏论坛

 找回密码
 立即注册
搜索
查看: 1851|回复: 1
打印 上一主题 下一主题

计算机专业玩家分析破败之王BUG原理:原码和补码问题

[复制链接]

签到天数: 7 天

[LV.3]阿拉德菜鸟

10

主题

13

帖子

98

积分

阿拉德菜鸟

Rank: 2

积分
98
怒气
28
声望
22
战力
13
跳转到指定楼层
楼主
发表于 2021-3-12 00:50:06 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
计算机专业玩家分析破败之王BUG原理:只是一个简单的原码和补码的问题,有多少人看懂了??[泪奔]

“65534,计算机专业才能反应过来,2的16次方就是65536!

根据这个数字,可以断定杀人戒的层数是用一个二进制的值表示,用16bit的内存来记录的。

如果是1层杀人戒,内存里存的就会是:
0000000000000001,16位,最后一位是1。

2层,就是0000000000000010。

破败之王击杀敌方英雄,戒指本应该是+2的,但是却变成了65534,在内存中表示1111111111111110。

这时候就要引入另一个概念,补码。

前面所说的都是原码,是不能表达负数的。而表达负数,就要用补码了。

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

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

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

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

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

这样就完全对的上了。

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

这么看来,这种严重的BUG,竟然只是因为程序员一个简单的错误,有些离谱。

大家这波看懂了吗?非专业人士表示看几遍都是懵懵懂懂!![泪奔][泪奔]




“啊!令人怀孕的故乡!”——凯莉
【腾讯云】推广者专属福利,新客户无门槛领取总价值高达2860元代金券,每种代金券限量500张,先到先得。

签到天数: 14 天

[LV.3]阿拉德菜鸟

32

主题

36

帖子

239

积分

阿拉德玩家

Rank: 3Rank: 3

积分
239
怒气
68
声望
51
战力
33
沙发
发表于 2021-3-12 00:50:55 | 只看该作者
跟补码源码没关系,C++从内存读int全都是补码方式读出来的。这个bug的根本原因是:声明的时候,c++ 里,是uint16_t,所以最高位的1代表的不是+/-,就是2*15。程序在下面跑下就完事了。
“啊!令人怀孕的故乡!”——凯莉
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋|DNF阿拉德游戏论坛 ( 渝ICP备2024024979号 )

渝公网安备50023502000547号

GMT+8, 2024-11-22 02:38 , Processed in 0.152991 second(s), 37 queries .

快速回复 返回顶部 返回列表