2
头图

Hello, I am crooked.

Step on the pit, step on the pit again!

This time I stepped on a particularly silent pit of common sense. At the moment of knowing the truth, a person is completely numb.

First code:

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

Don't ask why BigDecimal is not used for calculation, anyway, there is a method similar to this in the program.

There is nothing wrong with normal use:

Note that I said "normal use looks fine", what about abnormal use?

When I saw that the output was "Infinity", I even rubbed my eyes, thinking that I was too passionate about my work, which led to overuse of my eyes and looking at flowers.

One thing to say, I've never seen this thing. But I know this word:

In my limited knowledge, 0 cannot be used as a divisor. If it is used as a divisor, an exception will be thrown.

But this simple case broke my cognition, not only did it not throw an exception, it also gave me an "infinite number".

In a dazed look, I know that the material is coming.

search

If I encounter problems in the process of using the framework, generally speaking, I will debug it myself first, and struggle for a while to see if my opening method is wrong.

But the problem is so simple that I can't even find a debugging angle.

How to do?

Only directly take out the ancestral skills of programmers: programming for the browser.

So I typed in the search keyword "Java Infinity", and the top one was a blog site:

I personally don't like this site very much, so I searched again according to my personal habits:

Found this link:

https://www.cnblogs.com/zhisuoyu/p/5314541.html

From this article, I know that in my cognition, 0 as a divisor will throw the following exception, and another premise is "integer operation":

java.lang.ArithmeticException: / by zero

The two constants "positive infinity" and "negative infinity" are defined in Double and Float:

Now I know that in floating point arithmetic, 0 can be used as a divisor.

But why?

What is this design in Java, and why isn't it treated equally?

It is not written in the blog, but I know that to find the answer to this question, this place can be visited:

https://stackoverflow.com/

So I used the "Java Double Float Infinity" keyword to query:

It's easy to find this link:

https://stackoverflow.com/questions/12954193/why-does-division-by-zero-with-floating-point-or-double-precision-numbers-not

The question asked by the questioner, translated, is exactly the same as the one I encountered earlier:

Why doesn't dividing by zero with Float or Double throw a java.lang.ArithmeticExceptionL:/by zero exception?

The highly praised answer to this question is this:

The ultimate answer to the question is hidden in this high praise answer, and I will analyze it for you.

reveal

This high praise answer, in fact, has only one sentence:

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.

All other parts are references.

In this sentence, he mentions two key things:

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

This means that Java's floating-point operations are based on the IEEE-754 standard.

One of the hyperlinks he gave is the Java Language Specification:

https://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.2.3

The Java language specification says: you have to ask me why, and I can only tell you that I abide by the international specification IEEE 754.

So, don't ask:

So what is this IEEE 754?

I don't know either, so check it out:

Good guy, the background is not small.

IEEE, full name Institute of Electrical and Electronics Engineers, Institute of Electrical and Electronics Engineers.

The full name of IEEE 754 is IEEE Standard for Floating-Point Arithmetic.
Represents a technical standard for floating-point arithmetic developed by the Institute of Electrical and Electronics Engineers.

Standard, standard, you understand?

There must be some standards, and some things are easy to handle, otherwise, they will fight each other, and they will be compatible and uncomfortable.

So, the standard was created to address various issues in different floating-point implementations that made them difficult to use and port reliably.

Once there is a standard and everyone abides by it, it will be easy to handle.

The standard specifies how exceptions should be handled:

Come, the framed part, read it out loud to me:

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

For "divide by 0" exceptions, IEEE 754 states that operations on finite operands yield an exact infinite result, eg, 1/0 or log(0). By default, ±infinity is returned.

So the question comes again?

Why is there such a requirement in the standard?

In the previously mentioned high praise answer, a link like this is given:

https://web.archive.org/web/20180112211305/http://grouper.ieee.org/groups/754/faq.html#exceptions

The answer to this question is hidden in this link:

Ask: Why does dividing by zero (or overflow, or underflow) not stop the program or throw an error?

I gave a long reply below. I tried to understand it a few times, but I found that it was a bit out of line, and I really don't know what it means.

I personally think it means: this thing is widely used, for the stability of the program, I don't want to throw an exception to terminate the program, and the user should know that my "divide by 0 is an infinite number" "Such a setting.

So why exactly?

OK,

Stop asking,

Just here.

ask again,

It's not polite.

After reading it, you only need to remember one sentence: in Java, if the divisor is 0, an ArithmeticException will not necessarily be thrown. Don't form such a fixed thinking, which will affect the direction of your troubleshooting.

Finally, the article was first published on the WeChat public account. Welcome to pay attention:


why技术
2.2k 声望6.8k 粉丝