乐趣区

关于后端:踩坑了0作为除数不一定会抛出异常

你好呀,我是歪歪。

踩坑了啊,又踩坑了啊!

这次踩到一个特地无语的常识坑。晓得假相的那一刻,人就是整个麻掉。

先上个代码:

private static double calculate(double a, int b) {return a / b;}

你先别问为什么计算不必 BigDecimal,反正程序外面就是有一个相似于这样的办法。

失常用起来也没啥故障:

留神,我说的是“失常应用看起来没故障”,不失常应用是怎么样的呢?

看到输入后果是“Infinity”的时候,我甚至揉了一下眼睛,认为本人是过于热爱工作,导致用眼适度,看花了。

有一说一,我真没见过这玩意。然而这个单词我意识啊:

在我无限的认知外面,0 是不能够作为除数的,如果作为除数会抛出异样才对。

然而这个简略的案例突破了我的认知,它不仅没有抛出异样,还给我了一个“无穷大的数”。

在一脸懵逼中,我晓得,素材这不就来了嘛。

搜寻一番

如果是在应用框架的过程中遇到问题,一般来说我是先本人调试一下,挣扎一波,看看是不是本人的打开方式不对。

然而这个问题太简略了,以至于我甚至找不到调试的角度。

怎么办?

只有间接拿出程序员的祖传技能了:面向浏览器编程。

于是我输出搜寻关键字“Java Infinity”,排在第一的是某博客网站:

我集体是不太喜爱这个网站,所以我依照集体习惯从新搜寻了一次:

找到了上面这个链接:

https://www.cnblogs.com/zhisu…

从这篇文章中我晓得了,原来在我的认知外面,0 作为除数会抛出上面这个异样,还有一个前提是“整型运算”:

java.lang.ArithmeticException: / by zero

在 Double 和 Float 外面都定义了“正无穷”和“负无穷”这两个常量:

当初我晓得在浮点运算的时候,0 是能够作为除数的。

然而,为什么呢?

Java 外面什么这样设计呢,为什么不厚此薄彼呢?

博客外面没有写,然而我晓得要找到这个问题的答案,这个中央能够去看看:

https://stackoverflow.com/

于是我用“Java Double Float Infinity”关键字去查问了一下:

很容易就找到了这个链接:

https://stackoverflow.com/que…

这个提问者提出的问题翻译过去,和我后面遇到的问题截然不同:

为什么用 Float 或者 Double 除以零不会抛出 java.lang.ArithmeticExceptionL:/by zero 异样?

这个问题下的高赞答复是这样的:

问题的终极答案就藏在这个高赞答复中,我给你解析一番。

揭秘

这个高赞答复,其实就只有一句话:

In short, that’s the way it’s specified in the IEEE-754 standard, which is what Java’s Floating-Point Operations are based on.

其余的局部都是援用。

在这一句话中,他提到了两个要害的货色:

  • IEEE-754 standard
  • Java’s Floating-Point Operations

意思就是 Java 的浮点运算是基于 IEEE-754 规范来的。

他给的其中一个超链接是 Java 语言标准:

https://docs.oracle.com/javas…

Java 语言标准示意:你要问我为什么,我只能通知你我恪守的是 IEEE 754 这个国内标准。

所以,别问:

那么这个 IEEE 754 是个什么货色呢?

我也不晓得,所以查一下:

好家伙,来头还不小。

IEEE,全称 Institute of Electrical and Electronics Engineers,电气和电子工程师协会。

IEEE 754 的全称是 IEEE Standard for Floating-Point Arithmetic。
示意电气和电子工程师协会制订的浮点运算技术标准。

Standard,规范,你明确吧?

得有一些 Standard,有些事件才好办,不然各自为战,各自兼容,好受的一比。

所以,该规范是为了解决在不同的浮点实现中的各种问题,这些问题使它们难以牢靠地应用和移植。

一旦有了规范,大家都恪守,就好办了。

在规范中就规定了对于异样应该如何解决:

来,框起来的局部,跟我大声的朗诵一遍:

Division by zero: an operation on finite operands gives an exact infinite result, e.g., 1/0 or log(0). By default, returns ±infinity.

针对“除以 0”异样,IEEE 754 规定:对无限操作数的运算会失去一个准确的有限后果,例如,1/0 或 log(0)。 默认状况下,返回 ±infinity。

那么问题又来了?

为什么规范中要这样的规定呢?

在后面提到的高赞答复中,给到了这样的一个链接:

https://web.archive.org/web/2…

这个问题的答案就藏在这个链接外面:

请问:为什么除以零(或溢出,或下溢)不会进行程序或引发谬误?

上面给了一大段回复,我尝试着了解了几次,然而我发现有点超纲了,的确不晓得具体啥意思。

我集体通俗的认为它要表白的意思是:这玩意应用范畴很广,为了程序的稳定性,我不想抛出异样来终止程序,而使用者应该晓得我这个“除 0 之后是一个无穷大的数”这样的设定。

所以到底为什么呢?

好了,

别问了,

就到这吧。

再问,

就不礼貌了。

看完之后,你只须要记住一句话: 在 Java 外面,除数作为 0,不肯定会抛出 ArithmeticException,千万不要造成这样的固化思维,从而影响本人排除问题的方向。

最初,文章全网首发在微信公众号,欢送关注:

退出移动版