0

I'm trying to use Junit to test a java program, and I'm not sure how to go about testing for upper-bound violations.

Specifically, I have written a simple program to convert between kilometers and miles.

For example, here is the method for converting from miles to kilometers

    public static double mileToKm(double mile){
    //1.1170347260596139E308 / 0.621371192 = Double.MAX_VALUE
    try{
        if (mile < 0 || mile > 1.1170347260596139E308){
            throw new IllegalArgumentException();
        }
        else
            return mile / 0.621371192;}
    return 0;
}

So, I guess my question is two-fold: First, why is it that I can't conjure up an exception when I try

mileToKm(1.1170347260596139E308 + 1)

in junit? I assume it's a rounding issue, but if that's the case then how can I get the exception thrown?

Second, for the method to convert from km to mile, I want to throw an exception if the parameter is greater than Double.MAX_VALUE. How can I pass such a parameter? I can get the Junit test to pass if I just pass as parameter Double.MAX_VALUE * 10, but I also get a message in the Console (this is all in Eclipse Mars 4.5.1, btw) saying 'MAX = 1.7976931348623157E308'. The parameter has to be a double so it can't be BigDecimal or something like that.

OK, I lied, the question is three-fold. What's up with this:

double value =  Double.MAX_VALUE * 0.621371192; //max_value * conversion factor
System.out.println(value);

prints 1.1170347260596138E308, but then these two statements

System.out.println(value / 0.621371192);
System.out.println(Double.MAX_VALUE);

print 1.7976931348623155E308 and 1.7976931348623157E308, respectively. In other words, I would expect these two values to both be equivalent to Double.MAX_VALUE, but the first statement has a 5 right before the E, instead of a 7. How can I fix this? Thanks so much, hope this isn't too prolix.

Brian Wray
  • 125
  • 1
  • 8
  • It would really help if you'd ask *one* question per post. But how do you expect a double to have a value that's more than `MAX_VALUE`, other than being positive infinity? If there *were* a finite value bigger than `MAX_VALUE`, that would be a more appropriate `MAX_VALUE`, wouldn't it? – Jon Skeet Feb 02 '16 at 22:37
  • Have you considered using `BigDecimal` instead of `double`? That would side-step some of the issues related to max values and rounding error. If you really want to deal with `double`, you could still use `BigDecimal` to do the calculation within the method, converting back to `double` for the return value (and appropriately handling the cases where the result cannot be appropriately represented as a double). – Rob Feb 02 '16 at 22:44
  • One question per post, got it. Thanks for your replies. I guess I can't really do what I thought I wanted to do here anyway. – Brian Wray Feb 03 '16 at 00:01

1 Answers1

0

You're confused about floating point numbers.

Firstly, the number 1.1170347260596139E308 + 1 is not representable using primitives in Java, as doubles have ~16 significant digits, and that addition requires 308 significant digits.

Secondly, float/double operations are not idempotent if you use intermediate storage (and most of the times even without it). Floating point operations lose accuracy, and arithmetic methods that retain accuracy over large computations (think weather models) are sought after in the scientific sector.

Thirdly, there's Double.MAX_VALUE, which represents the largest representable number in a primitive in Java; the only other value X such that X > Double.MAX_VALUE can hold is Double.POSITIVE_INFINITY, and that's not a real number.

Community
  • 1
  • 1
Tassos Bassoukos
  • 16,017
  • 2
  • 36
  • 40
  • This is one of the first times I'm playing around with such large numbers, and I really DON'T understand them. Thanks a lot for the reply, it was helpful. I guess I'll go spend some time with the javadoc for Double! – Brian Wray Feb 02 '16 at 23:59
  • It's not about large numbers; it's that floating point is fixed precision. You won't find that in the javadoc of Double - for a better intro and insight into the matter, read up the links in the [wiki](http://stackoverflow.com/tags/floating-point/info). – Tassos Bassoukos Feb 03 '16 at 08:11