/* * [TestAverage.java] * * Summary: Compute average of two ints four different ways. * * Copyright: (c) 2009-2017 Roedy Green, Canadian Mind Products, http://mindprod.com * * Licence: This software may be copied and used freely for any purpose but military. * http://mindprod.com/contact/nonmil.html * * Requires: JDK 1.8+ * * Created with: JetBrains IntelliJ IDEA IDE http://www.jetbrains.com/idea/ * * Version History: * 1.0 2007-07-08 */ package com.mindprod.example; import static java.lang.System.*; /** * Compute average of two ints four different ways. *

* Compute the Average of Two Numbers. Based on Joshua Bloch's blog. * http://googleresearch.blogspot.com/2006/06/extra-extra-read-all-about-it-nearly.html This little program demonstrate * how even simple computing techniques sometimes give incorrect answers. * * @author Roedy Green, Canadian Mind Products * @version 1.0 2007-07-08 * @since 2007-07-08 */ public final class TestAverage { /** * Compute average of two ints four different ways. Attempts to compute the average of low and high truncated down * to the nearest integer. * * @param low low value. * @param high high value. * @param description description of what is unusual about this pair. */ private static void trial( int low, int high, String description ) { int correct = ( int ) ( ( ( long ) low + ( long ) high ) / 2 ); // fails if low + high > Integer.MAX_VALUE. int average1 = ( low + high ) / 2; // fails if low > high, or if both low and high are negative, int average2 = low + ( ( high - low ) / 2 ); // fails if low and high are negative. int average3 = ( low + high ) >>> 1; out.printf( "%10d %10d %10d %10d %10d %10d %s%n", low, high, correct, average1, average2, average3, description ); } /** * main program to test average-calculating code. * * @param args command line not used. */ public static void main( String[] args ) { out.println( " low | high | long | simple div | +1/2diff | shift | " ); trial( 2, 5, "ordinary case" ); trial( -8, -5, "both negative" ); trial( -8, 11, "one negative, one positive " ); trial( 1000, 11, "low > high" ); trial( Integer.MAX_VALUE - 10, Integer.MAX_VALUE - 9, "sum greater than Integer.MAX_VALUE" ); trial( Integer.MAX_VALUE - 2, Integer.MAX_VALUE - 9, "sum greater than Integer.MAX_VALUE, low > high" ); } // Here is what the output looks like: // * marks an incorrect answer for the average. // low | high | long | simple div | +1/2diff | shift | // 2 5 3 3 3 3 ordinary case // -8 -5 -6 -6 -7* 2147483641* both negative // -8 11 1 1 1 1 one negative, one positive // 1000 11 505 505 506* 505 low > high //2147483637 2147483638 2147483637 -10* 2147483637 2147483637 sum greater than Integer.MAX_VALUE //2147483645 2147483638 2147483641 -6* 2147483642* 2147483641 sum greater than Integer // .MAX_VALUE, low > high }