Comparing BigDecimal

3 views
Skip to first unread message

fordfrog

unread,
Aug 5, 2007, 2:16:07 PM8/5/07
to Hamcrest Java Users
Hi,

I am very new to hamcrest. What is the recommended way in hamcrest to
test two BigDecimals that they contain the same value? Normally it is
written 'value1.compareTo(value2) == 0'. equal() also compares scale
which is not what I want to do.

Thanks for the help.

--
Miroslav Šulc

Nat Pryce

unread,
Aug 5, 2007, 2:49:55 PM8/5/07
to hamcre...@googlegroups.com
Strange. The equals(o) method should return the same boolean value as
compareTo(o) == 0. If it doesn't, the class is breaking the contract
of the Comparable interface.

However, if you need to compare BigDecimals differently than equals
you'll have to write a new Matcher. The Hamcrest wiki has a tutorial
that shows you how.

--Nat

Miroslav Šulc

unread,
Aug 5, 2007, 3:01:58 PM8/5/07
to hamcre...@googlegroups.com
Thanks for your answer.

In case of BigDecimal the behavior is this:
10.0 equals 10 = false (values are the same but scales are different)
10 equals 10 = true
10.0 compareTo 10 = true (just values compared)
which I think is correct.

The same is in case of Calendar and maybe there are even other classes
that implement this behavior. I think that some compareTo() in hamcrest
would come handy in these cases.

--
Miroslav Šulc

Nat Pryce napsal(a):

Miroslav Šulc

unread,
Aug 9, 2007, 2:33:22 PM8/9/07
to hamcre...@googlegroups.com
Hi Nat,

I went through the code and found OrderingComparisons.java which seems to be what I am looking for except two things:

- first, it misses method like compareEqualTo()
- second, it does not use compareTo() for equality but instead uses equalsTo() which IMO is not correct

In the case of my BigDecimal problem, I suppose the behavior will be this:

when running Assert.assertThat(BigDecimal.valueOf("10.0"), OrderingComparisons.greaterThanOrEqualTo(BigDecimal.valueOf("10")) I suppose I'll get failing assertion because OrderingComparisons does these checks:
- checks 10.0 > 10 using compareTo() which results in FALSE
- equalsTo() 10.0 and 10 which results in FALSE too as the scale is different though the value is the same

So the result of this comparison would be that 10.0 is not greater than 10 nor it is equal to each other (because scales differ) nor 10.0 is lower than 10 so this cannot evaluate to true in any case.

In general, compareTo() compares just the values whereas equalsTo() compares all properties of the object which is not appropriate when comparing for ordering. So using compareTo() for BigDecimal, 10.0 and 10 are equal wrt ordering, in case of Calendar, two dates with the same milliseconds since epoch but with some other properties different are considered equal too using compareTo().

IMO the fix should be to use compareTo() instead of equalsTo() in OrderingComparisons. And IMO method like compareEqualTo() which uses Comparable.compareTo(value) == 0 should be introduced too.


--
Miroslav Šulc

Nat Pryce napsal(a):
Strange.  The equals(o) method should return the same boolean value as
compareTo(o) == 0.  If it doesn't, the class is breaking the contract
of the Comparable interface.

However, if you need to compare BigDecimals differently than equals
you'll have to write a new Matcher.  The Hamcrest wiki has a tutorial
that shows you how.

--Nat

On 05/08/07, fordfrog <mirosl...@startnet.cz> wrote:
  

Nat Pryce

unread,
Aug 10, 2007, 8:33:01 AM8/10/07
to hamcre...@googlegroups.com
OrderingComparisons.compareEqualTo sounds like a good idea. Could you
raise an issue in the Hamcrest project on Google Code?

--Nat

Reply all
Reply to author
Forward
0 new messages