0

Please forgive the obvious "I should probably already know this" element to the question but I'm not seeing a method that I would run the division side of this evaluation through, to get the result to come back as true.

I'm looking for a function that would return the result as a float of specific precision, so that the following would work...

float a = 0.66;

if( magicPrecisionFunction(2.0f/3.0f , 2) == a){ //the 2 specifies the level of precision
   //something
}

I realize that I can write this myself in 2 minutes, but I was hoping to find a Java native way to do this "properly".

Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
Yevgeny Simkin
  • 27,946
  • 39
  • 137
  • 236
  • 7
    Using double or float, you will never have a precise value for floating point numbers. If you want to handle these numbers, use `BigDecimal` instead. Sorry to say but yes, this is a *you should probably already know this*. – Luiggi Mendoza May 13 '13 at 22:31
  • 4
    I don't think you mean irrational numbers. Every finite number you can represent in a floating type is rational. – Paul May 13 '13 at 22:35
  • AFAIK you can round the result. If you see the [`java.math.BigDecimal`](http://docs.oracle.com/javase/7/docs/api/java/math/BigDecimal.html) documentation you can achieve this using [`BigDecimal#setScale`](http://docs.oracle.com/javase/7/docs/api/java/math/BigDecimal.html#setScale%28int,%20int%29) – Luiggi Mendoza May 13 '13 at 22:40
  • AH! so that's the secret to BigDecimal. Good to know! thanks very much. – Yevgeny Simkin May 13 '13 at 22:41
  • Could you please change the title to "how do I compare rational numbers" :) I already tried to edit but it was denied. – greedybuddha May 13 '13 at 22:52
  • Possible duplicate of [Comparing floating point numbers in Java](http://stackoverflow.com/questions/5923682/comparing-floating-point-numbers-in-java) – Raedwald Feb 27 '16 at 13:51

3 Answers3

2

If you want precision I wouldn't use float as double is simpler to write and gives you half a trillion times the accuracy.

Similar to @rofl's example

int n = 2, d = 3;
if ((long)(100.0 * n / d) == 66) {
  ...
}

Not only is this about 100x faster than using BigDecimal, the code is shorter to write.

BTW The proper way to to convert a double to a BigDecimal is to use valueOf

BigDecimal bd = BigDecimal.valueOf(0.1);
System.out.println(bd); // prints 0.1
Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
1

you can use BigDecimal, it will do exactly what you need, you can create the number you need and set the precision with MathContext

    BigDecimal b1 = new BigDecimal("2.0");
    BigDecimal b2 = new BigDecimal("3.0");
    BigDecimal ans = b1.divide(b2, new MathContext(2)); // 2 is precision
flavian
  • 28,161
  • 11
  • 65
  • 105
Dima
  • 8,586
  • 4
  • 28
  • 57
  • Interesting. You pass in a String to get back your resulting object? – Yevgeny Simkin May 13 '13 at 22:43
  • you dont have to pass a string, this constructor can take many classes, take a look at it – Dima May 13 '13 at 22:44
  • @Dr.Dredel because if you pass a `double` or a `float` the `BigDecimal` instance will work with the wrong number i.e. 0.1 could be 0.9999999... – Luiggi Mendoza May 13 '13 at 22:44
  • yes doubles are very bad, you should always work with BigDecimal if you need precise calculations – Dima May 13 '13 at 22:45
  • @Dr.Dredel this is critical if you will work in financial applications (just to let you know and don't want to break a financial system (= ). – Luiggi Mendoza May 13 '13 at 22:48
  • @LuiggiMendoza Which is why most investment banks and trading houses use `double` or `long`. ;) Note: C & C++ don't have decimal and are widely used for financial applications. – Peter Lawrey May 14 '13 at 04:45
1

how abut...

if (Math.round(100.0f * 2.0f/3.0f) == 66) {
  ..
}

EDIT: Ahhh... missed the point... not round, but truncatte. in which case:

if ((int)(100.0f * 2.0f / 3.0f) == 66) {
  ...
}
rolfl
  • 17,539
  • 7
  • 42
  • 76