Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does writing a number in scientific notation make a difference in this code?

Tags:

I am trying to write a code to determine when the number of milliseconds since the beginning of 1970 will exceed the capacity of a long. The following code appears to do the job:

public class Y2K {     public static void main(String[] args) {         int year = 1970;         long cumSeconds = 0;          while (cumSeconds < Long.MAX_VALUE) {             // 31557600000 is the number of milliseconds in a year             cumSeconds += 3.15576E+10;             year++;         }         System.out.println(year);     } } 

This code executes within seconds and prints 292272992. If instead of using scientific notation I write cumSeconds as 31558000000L, the program seems to take “forever” to run (I just hit pause after 10 mins or so). Also notice that writing cumSeconds in scientific notation does not require specifying that the number is a long with L or l at the end.

like image 605
sedeh Avatar asked Sep 18 '15 18:09

sedeh


People also ask

Why is writing numbers in scientific notation important?

The primary reason for converting numbers into scientific notation is to make calculations with unusually large or small numbers less cumbersome. Because zeros are no longer used to set the decimal point, all of the digits in a number in scientific notation are significant, as shown by the following examples.

How does scientific notation help writing numbers and equations?

Scientific notation is like shorthand for writing very large or very small numbers. Instead of writing the number in decimal form, the number is shortened to a number multiplied by a power of ten.

Does the value change when it is in scientific notation?

To write a large number in scientific notation, move the decimal point to the left to obtain a number between and . Since moving the decimal point changes the value, you have to multiply the decimal by a power of so that the expression has the same value. Let's look at an example.

What is the purpose of scientific notation How is it represented?

Scientific notation is a way of writing very large or very small numbers. A number is written in scientific notation when a number between 1 and 10 is multiplied by a power of 10. For example, 650,000,000 can be written in scientific notation as 6.5 ✕ 10^8. Created by Sal Khan and CK-12 Foundation.


1 Answers

The reason it makes a difference is because the scientific notation number 3.1558E+10 is a double literal, whereas the literal 31558000000L is of course a long literal.

This makes all the difference in the += operator.

A compound assignment expression of the form E1 op= E2 is equivalent to E1 = (T) ((E1) op (E2)), where T is the type of E1, except that E1 is evaluated only once.

Basically, long += long yields a long, but long += double also yields a long.

When adding a double, the initial value of cumSeconds is widened to a double and then the addition occurs. The result undergoes a narrowing primitive conversion back to long.

A narrowing conversion of a floating-point number to an integral type T takes two steps:

  1. In the first step, the floating-point number is converted either to a long, if T is long

(snip)

  • Otherwise, one of the following two cases must be true:

    • The value must be too small (a negative value of large magnitude or negative infinity), and the result of the first step is the smallest representable value of type int or long.

    • The value must be too large (a positive value of large magnitude or positive infinity), and the result of the first step is the largest representable value of type int or long.

(bold emphasis mine)

The result eventually is too big to be represented in a long, so the result is narrowed to Long.MAX_VALUE, and the while loop ends.

However, when you use a long literal, you are continuously adding an even value to an even value, which will eventually overflow. This does not set the value to Long.MAX_VALUE, which is odd, so the loop is infinite.

But instead of relying on an addition eventually yielding Long.MAX_VALUE, with Java 1.8+ you can explicitly test for overflow with Math.addExact.

Returns the sum of its arguments, throwing an exception if the result overflows a long.

Throws:

ArithmeticException - if the result overflows a long

like image 164
rgettman Avatar answered Oct 13 '22 00:10

rgettman