total_seconds: Fix precision problem
Since CircuitPython floats have very small precision, the "total_seconds" method was not very useful for large timedeltas. Instead of always returning a float, use pure-integer arithmetic (and return an int) if either: * the length of time is big (1<<21 is 2097152 seconds or about 24 days) * the number of microseconds is zero Otherwise, for small values with nonzero microseconds, use floating-point math. The cut-off point was chosen because in CircuitPython float arithmetic, 2097151.0+0.5 is different from 2097151.0, but 2097152.0+0.5 and 2097152.0 are *the same float*.
This commit is contained in:
parent
c8486780b9
commit
13f93325d3
1 changed files with 9 additions and 3 deletions
|
|
@ -429,9 +429,15 @@ class timedelta:
|
|||
# Instance methods
|
||||
def total_seconds(self):
|
||||
"""Return the total number of seconds contained in the duration."""
|
||||
return (
|
||||
(self._days * 86400 + self._seconds) * 10 ** 6 + self._microseconds
|
||||
) / 10 ** 6
|
||||
# If the duration is less than a threshold duration, and microseconds
|
||||
# is nonzero, then the result is a float. Otherwise, the result is a
|
||||
# (possibly long) integer. This differs from standard Python where the
|
||||
# result is always a float, because the precision of CircuitPython
|
||||
# floats is considerably smaller than on standard Python.
|
||||
seconds = self._days * 86400 + self._seconds
|
||||
if self._microseconds != 0 and abs(seconds) < (1 << 21):
|
||||
seconds += self._microseconds / 10 ** 6
|
||||
return seconds
|
||||
|
||||
def __repr__(self):
|
||||
args = []
|
||||
|
|
|
|||
Loading…
Reference in a new issue