Widening, Overflow, and Round-Off
Widening
A clip on a video platform runs 75 seconds, and a viewer plays it at one and a half times normal speed.
int seconds = 75;
System.out.println(seconds / 1.5);
The division has an
int on the left and a double on the right. Java converts the int 75 to the double 75.0 on its own, and the division gives 50.0. That conversion is called widening, and it never loses anything, since every int value has an equal double value.The range of an int
An
int is stored in 4 bytes of memory, a fixed amount set by the Java language. So there's a largest and a smallest int, and Java names them.System.out.println(Integer.MAX_VALUE);
System.out.println(Integer.MIN_VALUE);
These print 2147483647 and -2147483648. Both are legal
int values, and every int lies between them. The negative end is one farther from zero, because zero takes one of the places on the nonnegative side.Overflow
The platform keeps each video's view count. A popular video has 2,147,000,000 views, and half a million more arrive.
int views = 2147000000;
views = views + 500000;
System.out.println(views);
The true sum is 2,147,500,000, more than
Integer.MAX_VALUE. Java doesn't stop or report anything. The sum wraps around the range. The int type has 4,294,967,296 values, and 2,147,500,000 minus that is -2,147,467,296. The segment prints that negative number, a legal int with no sign that it's wrong except that a view count can't be negative.A
double can hold far larger values, so a count that might pass the limit can be kept in one.double allViews = 2147000000;
allViews = allViews + 500000;
System.out.println(allViews);
The
int literal is widened to a double when it's stored, and the addition is done with double values. The sum is exactly 2,147,500,000, and it prints as 2.1475E9, Java's way of writing 2.1475 times 10 to the 9th power for a large double.Round-off
A
double is also stored in a fixed amount of memory, and there the limit is precision. Most decimal fractions have no exact binary form. So a value like 1.2 is stored as the nearest value the memory can represent, which isn't exactly 1.2.An editor trims 1.0 second from a 1.2-second clip.
double clip = 1.2;
System.out.println(clip - 1.0);
This prints
0.19999999999999996. The stored 1.2 was a little less than 1.2, and the subtraction carries that difference into the result. That is a round-off error. It's small, but the result isn't 0.2.For the clip, the platform can store lengths as whole milliseconds. The clip is 1200 milliseconds, trimming takes off 1000, and
1200 - 1000 is exactly 200, since int values are stored exactly. A length shown in seconds can be computed once, at the end, from the exact count.