Puzzle 3: Division by length

Source: Internet
Author: User
Tags integer division

This puzzle is called long integer division because the program involved is related to the division of two long numeric values. The divisor represents the number of microseconds in a day, while the divisor represents the number of milliseconds in a day. What will this program print?

public class LongDivision{    public static void main(String args[]){        final long MICROS_PER_DAY = 24 * 60 * 60 * 1000 * 1000;        final long MILLIS_PER_DAY = 24 * 60 * 60 * 1000;        System.out.println(MICROS_PER_DAY/MILLIS_PER_DAY);    }}

This puzzle looks quite intuitive. The number of milliseconds per day and the number of microseconds per day are constants. For clarity, they are all expressed as products. The number of microseconds per day is (24 hours/day60 minutes/hour60 S/minute1000 ms/second1000 microseconds/MS ). The difference between the number of milliseconds per day is that the last factor is 1000 less.

When you use the number of milliseconds per day to divide the number of microseconds per day, all the factors in the divisor are approximately dropped, leaving only 1000. This is exactly the number of microseconds per millisecond.

Divisor and divisor are both of the long type. When the long type is large, the product can be easily saved without Overflow. Therefore, it seems that the program must print 1000.

Unfortunately, it printed 5. What happened here?

The problem is that the computation of the constant micros_per_day "indeed" overflows. Although the calculation result is suitable for putting in long and its space is surplus, this result is not suitable for putting in Int. This computation is completely performed using the int operation, and the result is promoted to long only after the computation is completed. It is too late: the computation has exceeded, it returns a value smaller than 200 times. Increasing from int to long is a type of widening original type conversion (widening primitive conversion), which retains (incorrect) values. This value is then divisible by millis_per_day, and the calculation of millis_per_day is correct because it is suitable for int operations. In this way, the division result is 5.

So why is the calculation performed using the int operation? Because all the factors that multiply together are int values. When you multiply two int values, you get another int value. Java does not have the type of the target, which is a language feature. It means that the type of the variable storing the result will affect the type used by calculation.

By using long constants to replace int constants as the first factor of each product, we can easily correct this program. In this way, all subsequent computations in the expression can be forced to use the long operation. Although this is only required in the micros_per_day expression, it is a good way to do so in both products. Similarly, using long as the product's "first" value is not always necessary, but it is also a good form. In both calculations, it can be clearly indicated that they do not overflow with the long value. The following program will print out the expected 1000:

public class LongDivision{    public static void main(String args[ ]){        final long MICROS_PER_DAY = 24L * 60 * 60 * 1000 * 1000;        final long MILLIS_PER_DAY = 24L * 60 * 60 * 1000;        System.out.println(MICROS_PER_DAY/MILLIS_PER_DAY);    }}

The lesson is simple: when you are operating on a large number, be sure to guard against overflow-it is a silent killer. Even if the variable used to save the result is large enough, it does not mean that the calculation of the result is of the correct type. If you are not sure, use the long operation to execute the entire computation.

What language designers can learn from this is that it is indeed worthwhile to reduce the possibility of silence overflow. This can be achieved by providing support for operations that do not produce a silent overflow. Programs can throw an exception rather than directly overflow, as ADA does, or they can automatically switch to a larger internal representation as needed to prevent overflow, as lisp does. Both methods may suffer performance losses related to them. Another way to reduce the silence overflow is to support the target determination type, but doing so will significantly increase the complexity of the type system.

Puzzle 3: Division by length

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.