Problem
We came across an issue today and believe I have figured out why it occurs. When using pebble with id values that are longs we noticed odd behavior where pebble considered the values 325055142682428416 and 325055142682428417 to be equal. You can recreate this issue with any large longs.
After reviewing the code we realized that all number comparisons in Pebble are converted to Double values which we believe is the issue. Please see the following lines for reference:
The line that calls wideningConversionBinaryComparison from a comparison where the type is Number:
|
return wideningConversionBinaryComparison(op1, op2, Comparison.EQUALS); |
The line in wideningConversionBinaryComparison that actually performs the double comparison:
|
return doubleComparison(num1.doubleValue(), num2.doubleValue(), comparison); |
Edit : Same Problem Affects All Binary Operators
This line shows another use of doubleValue() in OperatorUtils.wideningConversionBinaryOperation:
|
return bigDecimalOperation(BigDecimal.valueOf(num1.doubleValue()), |
Solution
I would recommend adding a type check for Number to also see if the instance also implements Comparable as this should work for many numerics reliably without conversion. This would also give you support for BigDecimal and BigInteger which we also use a lot for their reliability in financial math. The downside of Comparable is it can be tricky if you have to handle the case of comparing two numbers of different types, where both implement Comparable<T> of their own type, but a class cast exception would be thrown with double.compareTo(long) for example.
Here to assist as needed if we can contribute, but this is obviously a sensitive low level operator for Pebble, so requires your input on implementation I believe. 👍
Problem
We came across an issue today and believe I have figured out why it occurs. When using pebble with id values that are longs we noticed odd behavior where pebble considered the values
325055142682428416and325055142682428417to be equal. You can recreate this issue with any large longs.After reviewing the code we realized that all number comparisons in Pebble are converted to Double values which we believe is the issue. Please see the following lines for reference:
The line that calls
wideningConversionBinaryComparisonfrom a comparison where the type isNumber:pebble/pebble/src/main/java/com/mitchellbosecke/pebble/utils/OperatorUtils.java
Line 69 in aa43888
The line in
wideningConversionBinaryComparisonthat actually performs the double comparison:pebble/pebble/src/main/java/com/mitchellbosecke/pebble/utils/OperatorUtils.java
Line 191 in aa43888
Edit : Same Problem Affects All Binary Operators
This line shows another use of
doubleValue()inOperatorUtils.wideningConversionBinaryOperation:pebble/pebble/src/main/java/com/mitchellbosecke/pebble/utils/OperatorUtils.java
Line 154 in aa43888
Solution
I would recommend adding a type check for
Numberto also see if the instance also implementsComparableas this should work for many numerics reliably without conversion. This would also give you support forBigDecimalandBigIntegerwhich we also use a lot for their reliability in financial math. The downside ofComparableis it can be tricky if you have to handle the case of comparing two numbers of different types, where both implementComparable<T>of their own type, but a class cast exception would be thrown withdouble.compareTo(long)for example.Here to assist as needed if we can contribute, but this is obviously a sensitive low level operator for Pebble, so requires your input on implementation I believe. 👍