1

I need a way to express that into valid java code: I have 2 BigDecimals, and I want to know if the smaller BigDecimal can (when added to the bigger BigDecimal once) change the integral part of the bigger BigDecimal. Example:

0.6; 0.4 ->true

0.6; 0.39 ->false

Is there any efficient way of doing that, or do I have to test?

user207421
  • 305,947
  • 44
  • 307
  • 483
Distjubo
  • 959
  • 6
  • 21
  • When the smaller bigDecimal is added once to what? – ninesalt Sep 04 '15 at 11:44
  • to the bigger bigdecimal. – Distjubo Sep 04 '15 at 11:45
  • Why is one true and the other false? Can you express your requirement precisely? – user207421 Sep 04 '15 at 11:45
  • Maybe you meant the non fractional part? In your example both examples change the fractional part of the bigger decimal, but only one changes the non fractional part. `0.6 + 0.4 = 1.0 , 0 -> 1` and `0.6 + 0.39 = 0.99 , 0 -> 0` – Alkis Kalogeris Sep 04 '15 at 11:46
  • 1
    `Math.floor(numbA) != Math.floor(numbA + numB)` should be ok – Hacketo Sep 04 '15 at 11:47
  • 4
    And can we please get out of the habit of referring to fractional parts as decimals? Every digit in both these numbers is a decimal. There is an integral part and a fractional part, and a decimal point. Come this question, I have now seen 'decimal' used to refer to all three. It's meaningless. – user207421 Sep 04 '15 at 11:47
  • Sorry for my english, with decimal part I mean the part before the '.'. I thought thats how its called, correct me if I'm wrong. – Distjubo Sep 04 '15 at 11:48
  • ah, its integral part. sorry for confusion. – Distjubo Sep 04 '15 at 11:49
  • 2
    If you only test one set of numbers, I would guess your best bet is to simply add them and check (as suggested by @Hacketo). If you have to test *lots* of smaller numbers with the same big number, you could calculate the threshold (`Math.floor(big)+1-big`) once and then compare each small number to that. Perhaps that would increase performance a bit. – icke Sep 04 '15 at 11:50

3 Answers3

2

You can do something like this:

BigDecimal b1 = new BigDecimal("0.90");
BigDecimal b2 = new BigDecimal("0.20");
if(b1.add(b2).intValue() > Math.max(b1.intValue(), b2.intValue())){
    System.out.println("The integral has changed");
}else {
    System.out.println("The integral is the same");
}

How the intValue() method works:

Converts this BigDecimal to an int. This conversion is analogous to the narrowing primitive conversion from double to short ... Specification: any fractional part of this BigDecimal will be discarded ...

Titus
  • 22,031
  • 1
  • 23
  • 33
  • This doesn't work for very big numbers. Since the OP is using `BigDecimal` you have to account the possibility of very big non fractional part. An example would be `BigDecimal bigA = new BigDecimal(Integer.MAX_VALUE + ".90");` – Alkis Kalogeris Sep 04 '15 at 16:42
0

I've edited my answer after realizing Titus' answer was simpler. Credit goes to him/her.

 public static boolean integral(BigDecimal a, BigDecimal b) {

    BigDecimal greater;

    if (a.compareTo(b) == 1) {
        greater = a;
    } else {
        greater = b;
    }

    BigDecimal sum = a.add(b);

    return (sum.intValue() != greater.intValue());
}
Alkis Kalogeris
  • 17,044
  • 15
  • 59
  • 113
ninesalt
  • 4,054
  • 5
  • 35
  • 75
  • `charAt(0)` well .., `integral(new BigDecimal("13.39"), new BigDecimal("0.7"))` return false – Hacketo Sep 04 '15 at 11:58
  • when comparing strings, you have to use `equals` and not `==` or `!=` – Hacketo Sep 04 '15 at 12:06
  • No this do not work .. try with `integral(new BigDecimal("13.39"), new BigDecimal("0.1"))` should return false . BTW see [this post](http://stackoverflow.com/questions/513832/how-do-i-compare-strings-in-java) – Hacketo Sep 04 '15 at 12:12
  • Oh. I've always been hesitant to use == but most of the time it worked fine. Thanks for that. Edited the post. – ninesalt Sep 04 '15 at 12:16
0
private static boolean isNonFractionalChanged(BigDecimal a, BigDecimal b) {
    BigInteger aInt = a.toBigInteger();
    BigInteger aNewInt = a.add(b).toBigInteger();

    return aInt.compareTo(aNewInt) != 0;
}

The above works even for very big numbers.

BigDecimal a = new BigDecimal("0.90");
BigDecimal b = new BigDecimal("0.20");
System.out.println(a + " + " + b + " = " + a.add(b) + " : " + isNonFractionalChanged(a, b));

BigDecimal bigA = new BigDecimal(Integer.MAX_VALUE + ".90");
System.out.println(bigA + " + " + b + " = " + bigA.add(b) + " : " + isNonFractionalChanged(bigA, b));
Alkis Kalogeris
  • 17,044
  • 15
  • 59
  • 113