2

I want to find the quotient and remainder using Java, but am having difficulty when repeating decimals are involved.

Take the following equations for example (tested with Google calculator):

division: 182.5 / (365 / 12) = 6
remainder: 182.5 % (365 / 12) = 0

Now, a simple test in Java:

System.out.println("division: " + 182.5 / (365.0 / 12));
System.out.println("remainder: " + 182.5 % (365.0 / 12));

Output:

division: 6.000
remainder: 30.415

I understand double has limitations, so I tried with BigDecimal:

BigDecimal daysInYear = new BigDecimal("365");
BigDecimal monthsInYear = new BigDecimal("12");
BigDecimal daysInMonth = daysInYear.divide(monthsInYear, 3, RoundingMode.CEILING);
BigDecimal daysInHalfYear = new BigDecimal("182.5");
BigDecimal division = daysInHalfYear.divide(daysInMonth, 3, RoundingMode.CEILING);
BigDecimal remainder = daysInHalfYear.remainder(daysInMonth);
System.out.println("division: " + division);
System.out.println("remainder: " + remainder);

Output:

division: 6.0
remainder: 30.41666666666666

What do I need to do to get the following result?

182.5 % (365 / 12) = 0
nanoai
  • 25
  • 3
  • 5
    I would be mildly surprised if you could do this at all without inventing your own `Rational` class. – Louis Wasserman Aug 20 '18 at 02:44
  • (The standard approach with `double` is to test "within some epsilon," you would have to manage those details yourself with a 'wrapping' operation like `%`.) – Louis Wasserman Aug 20 '18 at 02:49
  • The result of the division is slightly less than 6 (but is rounded when you output it), therefore you get the remainder of 30.415. – Henry Aug 20 '18 at 04:23

1 Answers1

3

There are many programming languages that have native support for accurate operations on rational numbers. Java isn't one of them. Generally this isn't a huge problem as the precision of double is enough for most applications. Remainders are an edge case where very small rounding errors can cause large unexpected results.

Your options are:

  1. Use a different language
  2. Use a library with support for rationals (e.g. Rational)
  3. Write your own Rational class
  4. Use maths to rework your operation x % (y / z) => (x * z % y) / z
sprinter
  • 27,148
  • 6
  • 47
  • 78