最近,英雄联盟迎来了 S11 赛季的版本大更新。作为一名从 S2 一路走过来的老玩家,我自然也是非常的关注。除了发生了巨变的装备系统之外,各种各样的 bug,也是在玩家之间炽手可热的话题。这其中,较为严重的一个 bug 之一,就是打野英雄在特定的情况下,可以对野怪一击造成 -2147483648 的伤害。熟悉英雄联盟的玩家应该知道,21 亿在游戏中可以说是一个天文数字。哪怕是血量最多的野怪,在这个伤害面前也会瞬间灰飞烟灭,这简直是有史以来最大的峡谷惨案。那为什么会出现 -2147483648 这个大的数字呢?或者说,为什么就恰好就是这样一个数字呢?这个数看起来好像并没有什么规律,难道是由于程序异常导致某些数字累加或者累乘造成的?还是游戏开发者留下的一个类似于彩蛋的东西呢?这就是我今天要跟大家分享的内容——从编程的角度来分析这个 21 亿的神秘数字到底是怎么产生的。而这其中所涉及到的计算机知识,都可以作为面试题了!要想搞清楚这个问题,首先要了解三个概念:二进制、整数类型和补码。首先说二进制。无论你是否学过计算机,二进制这个词,多多少少你都可能听到过。那什么是二进制呢?首先我们来看下日常生活中我们广泛使用的十进制。十进制由十个数字符号组成,从 0 到 9。在计数过程中,逢十进一。比如说,9 的下一个数就需要进一位变为 10,19 的下一个数需要进一位变为 20,99 的下一个数需要进一位变成 100。同理,二进制就两个数字符号, 0 和 1,计数时逢二进一。比如说,0 就是 0,1 就是 1,十进制的 2 在二进制中就是 10,十进制的 3 在二进制中就是 11,4 则为 100,5 则为 101,以此类推。那为什么要提到二进制呢?这是因为,当今我们日常生活中所使用的计算机几乎都是大规模集成电路机,而这种计算机都是基于二进制来实现的。无论你平常见到的数字还是文字,甚至图像影音等等一切数据,最后在计算中都要转化成二进制的形式来存储或者计算。所以二进制可以说是计算机的灵魂,只有知道什么是二进制才能理解后面的内容。接下来再说整数类型。虽然计算机中的底层数据都要转化成二进制的形式,但是如果直接让程序员使用二进制进行编程则是一件非常麻烦事,毕竟二进制这个东西不是很直观,不利于人类直接操作。所以,为了方便广大编程人员更容易地编程,各种语言的设计者都对二进制做了进一步的封装。而整数类型就是在二进制的基础上,一个用于在编程中存放整数的一种数据类型,一般我们也称之为 int type。比如说,我现在想在程序中存放一个数字 100,那我可以定义一个整数类型的变量 a,用 a 来存放 100 这个数。而游戏中,伤害值都是以整数的形式呈现的,所以游戏开发者大概率使用整数类型来存储和计算伤害值。不过这里存在一个问题,就是现实世界中,整数的个数是无限的。我们可以从 0 到正无穷,也可以从 0 到负无穷。但是在计算机中,我们的存储空间是有限的,这是一种在物理层面上的限制。试想一下,如果我们想在计算机中存放一个无限大的数,那这个无限大的数转化成二进制后的位数也是无穷多位数,计算机不可能存放无限多位的数据。所以,我们要对存放的数据大小加以限制。对于一个整数类型,一般会分配给它 32 个比特的空间。看到这,有的同学可能会问啥是比特啊?还记得刚才说到的二进制么,二进制中的一位数就是一个比特(bit)。比如,二进制的 4 为 100,占 3 个比特。回到整数类型。刚才我们说道,一个整数类型被分配了 32 个比特的空间。其中,我们把第一个比特位拿出来作为符号位,0 代表正数,1 代表负数。剩下的 31 个比特位,我们用来存放数字。说得再通俗易懂一些,就是你可想象有 32 个格子排成一行,每个格子当中只能放一个数,0 或者 1。第一个格子用 0 和 1 分别表示正数和负数,剩下 31 个格子则用二进制的形式来存放想要表达的数字。比如,我想用一个整数类型存放 50 这个数。我们先把十进制的 50 转化成二进制的形式即 110010,在 32 比特中,第一位我们用 0 表示这是个正数,用后六位存放 110010,而中间的二十五位我们用 0 来填充。那如果想表达 -50 呢?这就需要我们了解第三个概念补码了。先说下补码的计算规则,刚刚我们算的 50 的 32 位二进制形式是 00…00110010,首先将所有位数上的数值取反,也就是 1 变为 0,0 变为 1,得到 11…11001101,这个我们称之为反码。然后在反码的基础上,我们在最后一位上作 +1 操作,则变成 11…11001110。那么这串数字,我们便称之为补码。在整数类型中,负数的存放形式跟正数的区别就是,负数存的是补码形式,而正数存的是原码形式。那为什么负数要用补码的形式存储呢?简单来说,就是大规模集成电路机中,加法运算是最为简单的。为了使计算机能够轻松计算减法,所以就把负数转化成为补码的形式,即将 A - B 转化成 A + (-B) 的形式,来方便计算机进行加减计算。具体有关原码、反码、补码的知识,这里就不多做展开了,以后有机会再跟大家详细分享。其实就算你没有理解补码的概念也不要紧,你只需要知道我们平常所用到的十进制的整数,在编程中是用 32 比特的整数类型存放就可以了。既然每个整数类型所分配的位数是固定的,都是 32 比特,那我们就可以计算一个整数类型所能表达的数字范围了。因为只有 31 位是真正用来表示数字的,每个位上有两种可能,所以范围即为~ 而超过这个范围的数,就不能够用整数类型来存放了。讲到这里,我们终于可以回到一开始的问题了,就是 -2147483648 这个神秘数字到底是怎么来的?当我们把 -2 的 31 次方算出来之后就会发现,-2 的 31 次方就是 -2147483648!惊不惊喜,意不意外!也就是说,这个 21 亿的伤害恰好是一个整数类型所能表达的最大负边界值了。是不是有一种谜底终于揭晓了的感觉!所以说,之所以打野英雄能造成这么高的伤害,极有可能是由于触发了某种 bug 导致伤害计算异常,使得伤害值溢出了整形类型所能表达的范围,而整数类型的下界最大便是 -2 的 31 次方,所以伤害最终就变成了 -2147483648 这个数字。没想到这个最近火遍全网的打野一刀秒杀野怪的 bug,居然是一个关于整数类型数值溢出的知识。所以说,掌握计算机思维,确确实实可以解决一些生活中遇到的问题。最后说几句题外话。一款游戏虽然在内测以及公测阶段能够发现并解决大部分显而易见的问题,但并不能保证在正式版本就一定不存在 bug。所以我们要对开发团队给予一定的信任和耐心,在等待 bug 修复前不要故意利用恶性 bug 来破坏游戏平衡,影响其它玩家的游戏体验,维护良好的游戏环境人人有责哦。

导致溢出_由整数类型溢出导致的英雄联盟峡谷惨案相关推荐

  1. 由整数类型溢出导致的英雄联盟峡谷惨案

    最近,英雄联盟迎来了 S11 赛季的版本大更新.作为一名从 S2 一路走过来的老玩家,我自然也是非常的关注.除了发生了巨变的装备系统之外,各种各样的 bug,也是在玩家之间炽手可热的话题.这其中,较为 ...

  2. spark如何防止内存溢出_什么叫内存溢出?内存泄漏的定义又是什么?使用中如何避免?...

    一.基本概念 内存溢出:简单地说内存溢出就是指程序运行过程中申请的内存大于系统能够提供的内存,导致无法申请到足够的内存,于是就发生了内存溢出. 内存泄漏:内存泄漏指程序运行过程中分配内存给临时变量,用 ...

  3. python整数类型提供了4种进制表示_关于整数类型的 4 种进制表示,哪个选项的描述是正确的?_学小易找答案...

    [单选题]锦葵科植物的雄蕊为() [单选题]决定地衣体形态的多是(1) [多选题]以下企业简介描述中,选择定位于利基市场的有() (2.0分) [单选题]异层地衣的藻类细胞排列于(2) [单选题]木犀 ...

  4. java 二维数组内存溢出_模拟Java内存溢出

    本文通过修改虚拟机启动参数,来剖析常见的java内存溢出异常(基于jdk1.8). 修改虚拟机启动参数 这里我们使用的是IDEA集成开发环境,选择Run/Debug Configurations 然后 ...

  5. unsigned long long 溢出 乘_Java整数相加溢出怎么办?Java8一步搞定

    问题 在之前刷题的时候遇见一个问题,需要解决int相加后怎么判断是否溢出,如果溢出就返回Integer.MAX_VALUE 解决方案 JDK8已经帮我们实现了Math下,不得不说这个方法是在Stack ...

  6. java bufferedimage 内存溢出_大图片内存溢出问题!!!

    2兆的图片还好,10几兆的图片就报内存溢出了,这个有什么好的解决方式吗 ?用的jdk1.7 /** * 给图片添加水印.可设置水印图片旋转角度 * * @param iconPath * 水印图片路径 ...

  7. mysql导入 内存溢出_导入数据库内存溢出

    {"moduleinfo":{"card_count":[{"count_phone":1,"count":1}],&q ...

  8. java递归堆栈溢出_【java】递归次数过多导致堆栈溢出

    在写一个算法中,由于递归调用次数过多,堆栈溢出. 堆栈的大小是系统控制的,无法改变. 如果递归调用出现问题,可以考虑采取循环的方式来解决,将需要的数据在关键的调用点保存下来使用.简单的说,就是用自己的 ...

  9. 堆栈溢出一般是由什么原因导致的 堆栈溢出怎么解决

    堆栈溢出的产生是由于过多的函数调用,导致调用堆栈无法容纳这些调用的返回地址,一般在递归中产生.堆栈溢出很可能由无限递归(Infinite recursion)产生,但也可能仅仅是过多的堆栈层级.下面小 ...

最新文章

  1. 为什么您不需要精通数学就可以学习编程
  2. 电脑任务管理器_安国戴尔电脑显示器维修,服务至上
  3. python写服务器端qt客户端_python写一些简单的tcp服务器和客户端
  4. c# asp.net Pdf 转换图片 在线预览 发布到iis中问题 最终解决篇—_—!
  5. Hadoop源码分析-Context
  6. eclipse部署web项目
  7. php round函数输出不对_PHP常量
  8. 一个500强公司的数据化运营管理实践
  9. debian 配置linuxptp 软件时间戳
  10. 思科路由器常用配置命令大全
  11. java ajax json 乱码_ajax请求返回200,json中文乱码怎么破?
  12. 去除右键菜单中图形属性、图形选项
  13. vs2017安装失败解决
  14. RGB-D相机原理与选型
  15. 基于OpenCV3.0的车牌识别系统设计(二)--车牌提取
  16. 74HC595芯片应用
  17. 医学图像分割常用的评价指标
  18. oracle 创建唯一索引
  19. 在jsp页面上直接打开PDF文件
  20. numpy 学习汇总18.2 - 数学运算( 基础学习 tcy)

热门文章

  1. Paxos 实现日志复制同步(Multi-Paxos)
  2. 【Struts2+Spring3+Hibernate3】SSH框架整合实现CRUD_1.0
  3. 回复:lerit的关于对象中字段的初始化问题
  4. 做到这23条,你就成熟了!
  5. GNSS用户设备的组成及原理——以GPS用户设备为例
  6. 数据单位:bit、Byte、KB、MB、GB、TB、PB、EB、ZB、YB、BB、NB、DB、、、
  7. 干货整理!深度学习相关的面试考点
  8. 近期发现的一些-20190519
  9. 在php storm中怎么搭建环境,PhpStorm搭建git环境
  10. python代码怎么设置,如何设置PyCharm中的Python代码模版(推荐)