0

ApFloat http://www.apfloat.org/ 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 π, etc. with numbers of arbitrary precision, which are not available in the BigDecimal Java class.

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.

  • 4/3 with precision of 5 and floor rounding mode is 1.3333
  • 4/3 with precision of 5 and ceiling rounding mode is 1.3334

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."

There is, however a method to round an ApFloat numbers with a specific precision and rounding mode http://www.apfloat.org/apfloat_java/docs/org/apfloat/ApfloatMath.html#round-org.apfloat.Apfloat-long-java.math.RoundingMode-

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:

// 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

The questions are:

  • Is this method [always] correct ? do you know any counterexample or false-positive ?
  • 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.
  • 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.
  • Can you post an example of input - output - expected output ? thx – RobertS Oct 21 '16 at 01:01
  • I hope the provided examples could help to clarify the question. Regards – Laurence R. Ugalde Oct 21 '16 at 15:24
  • I had a similar question a while ago. I found out that even for many digit BigDecimals (e.g. precision of 1000 or more), an additional precision of 5 for intermediate results was enough, at least for properly coded trig functions. Did not test any other functions yet. – Rudy Velthuis Oct 21 '16 at 16:14

1 Answers1

0

Here you go, I hope it helps

public static void main(String[] args) {
    Apfloat two = new Apfloat(2, 15); // Line 1: If you want precision be 10, than you can´t get result 1.41421356237309 on Line 4, because result have more than 10 numbers after . (decimal dot)
                                      // you can add new Apfloat variable with precision 15 for line 4 and for line 5,6 with precision 10
    System.out.print("Line2: Expected: 2 Result:" + two + "\n"); // Line 2:
    Apfloat sqrt = ApfloatMath.sqrt(two); // Line 3:
    System.out.print("Line4: Expected: 1.41421356237309 Result:" + sqrt + "\n"); // Line 4:
    System.out.print("Line5: Expected: 1.414213562 Result:" + ApfloatMath.round(sqrt, 10, RoundingMode.FLOOR) + "\n"); // Line 5:
    System.out.print("Line6: Expected: 1.414213563 Result:" + ApfloatMath.round(sqrt, 10, RoundingMode.CEILING) + "\n"); // Line 6:
}

Result:

enter image description here

RobertS
  • 135
  • 1
  • 11
  • Hi. Well the question is not about coding, but about the validity of the proposed method to ensure correct rounded values, since the results provided by the Apfloat library are undefined (in documentation), it is not known if these result are truncated, floored, ceiled, rounded-up, rounded-down, etc. Thanks – Laurence R. Ugalde Oct 27 '16 at 00:36