title: Rounding at specific precision with ApFloat
body: <p>ApFloat <a href="http://www.apfloat.org/" rel="nofollow">http://www.apfloat.org/</a> is a C/C++/Java math library that can calculate many trascendental operations such as square roots, exponentiations, logarithms, trigonometric/hyperbolic functions, numeric value of &pi;, etc. with numbers of arbitrary precision, which are not available in the <code>BigDecimal</code> Java class.</p>
  
  <p>We all know that the expansion of 4/3 is infinite: 1.333.... so when we try to get it at any specific precision, no matters how long it is, there will be loss of information, but the rounding mode is important, too, i.e.</p>
  
  <ul>
  <li>4/3 with precision of 5 and floor rounding mode is 1.3333</li>
  <li>4/3 with
  precision of 5 and ceiling rounding mode is 1.3334</li>
  </ul>
  
  <p>Unfortunately, the rounding mode cannot be specified when performing such those operations, maybe because "Due to different types of round-off errors that can occur in the implementation, no guarantees about e.g. monotonicity are given for any of the methods."</p>
  
  <p>There is, however a method to round an ApFloat numbers with a specific precision and rounding mode <a href="http://www.apfloat.org/apfloat_java/docs/org/apfloat/ApfloatMath.html#round-org.apfloat.Apfloat-long-java.math.RoundingMode-" rel="nofollow">http://www.apfloat.org/apfloat_java/docs/org/apfloat/ApfloatMath.html#round-org.apfloat.Apfloat-long-java.math.RoundingMode-</a></p>
  
  <p>A simple solution could be calculating the operation with an extra precision and then rounding the result with the original precision and desired rounding mode, as the following example:</p>
  
  <pre><code>// Trying to get the square root of 2
  // with precision of 10
  // and different roundig modes
  
  Apfloat two = new Apfloat(2, 15); // precision is 15, not 10
  // result: 2
  
  Apfloat sqrt = ApfloatMath.sqrt(two);
  // result: 1.41421356237309
  
  ApfloatMath.round(sqrt, 10, RoundingMode.FLOOR);
  // result: 1.414213562
  
  ApfloatMath.round(sqrt, 10, RoundingMode.CEILING);
  // result: 1.414213563
  </code></pre>
  
  <p>The questions are:</p>
  
  <ul>
  <li>Is this method [always] correct ? do you know any counterexample or false-positive ?</li>
  <li>Is 1 the least necessary value to be added to the precision in order to the extra information ensures a correct rounding ? I think adding 1 to the precision will not be enough, because the additional digit could be already rounded by the internal algorithm used to perform the calculation. Adding at least 2 positions would ensure the first digit -right to the desired precision- will be the the true digit present in the real -infinite- value of the number and not a rounded one.</li>
  <li>Do you realize a better method ? specially one where two-steps is avoided, because Apfloat -like BigDecimals- are immutable classes so new instances are created for every step, that could be problematic when using numbers with thousand or millions of precision places.</li>
  </ul>