Fix: bt2: erroneous integer comparison of Field and Value
Issue
=====
The `{Unsigned, Signed}IntegerValue` class inherit its __eq__() method
from the `_NumericValue` class. This method converts the `other` object
to a `complex` number to make the comparison as generic as possible. The
issue is that the large complex number comparison is unreliable as it's
using float comparison[1]. The timestamps we are dealing with will often
be going beyond the limit of exact comparison possible with the IEEE 754
double-precision[2].
I encountered this issue while comparing a
`bt2.value.SignedIntegerValue` to a large Python Integer representing a
timestamp in nanosecond.
Here is a showcase of the issue reproduced without the `bt2` bindings:
In [1]: 42 == complex(42)
Out[1]: True
In [2]:
1561489497327275497 == complex(
1561489497327275497)
Out[2]: False
The same issue is reproducible with the `_{Unsigned,
Signed}IntegerField`.
Solution
========
Implement the __eq__() and __lt__() methods in the `_IntegralValue`
class and but still use `_NumericValue`'s methods if the `other` object
is not an instance of `numbers.Integral`.
Implement the __eq__() and __lt__() methods in the `_IntegralField`
class and but still use `_NumericField`'s methods if the `other` object
is not an instance of `numbers.Integral`.
Drawback
========
None.
Note
====
I added test cases to cover large integer comparison for both Integer Value and
integer Field classes.
[1]: https://stackoverflow.com/questions/
5595425/what-is-the-best-way-to-compare-floats-for-almost-equality-in-python
[2]: https://en.wikipedia.org/wiki/Double-precision_floating-point_format
Signed-off-by: Francis Deslauriers <francis.deslauriers@efficios.com>
Change-Id: I8448bd42704ad1a2d215bece8534c839b9468f25
Reviewed-on: https://review.lttng.org/c/babeltrace/+/1538
Reviewed-by: Philippe Proulx <eeppeliteloop@gmail.com>