Python: create a fixed-point decimal point from two 32-bit ints (one for int, one for decimal)

I have a 64-bit timestamp unpacked from a binary file, where the upper 32 bits is the number of seconds and the lower 32 bits is the fraction of a second. I am stuck on how to actually convert the bottom 32 bits to a fraction without iterating over it bit by bit.

Any suggestions?

For reference, the number is 4ca1f350 9481ef80translated into1285682000.580107659

Edit: For context: the data comes from a packet capture device, and the documentation I saw suggests that the fractional part has approximately nano-second precision (in particular, it outputs 29 out of 32 bits, giving ~ 2ns).

+3
source share
3

(32 + 29 = 61 ), ( 28 , 93 ),

>>> from decimal import Decimal
>>> Decimal(0x9481ef80) / Decimal(2**32) + Decimal(0x4ca1f350)
Decimal('1285682000.580107659101486206')

(),

>>> from fractions import Fraction
>>> Fraction(0x9481ef80, 2**32) + Fraction(0x4ca1f350)
Fraction(43140329262089183, 33554432)
>>> float(_)
1285682000.5801077

, float " IEEE", 53 :

>>> a = 0x9481ef80 / 2**32 + 0x4ca1f350
>>> b = 0x9481ef90 / 2**32 + 0x4ca1f350
>>> a == b

, , , -?

>>> 0x9481ef80 / 2**32
0.5801076591014862
>>> 0x9481ef90 / 2**32
0.5801076628267765
+2

:

>>> float(0x9481ef80) / 0x100000000
0.58010765910148621
+3

. , 1970-01-01. , (1970-01-01) . ... vadj = float(hi32 - fudge) + lo32 / 2.0 ** 32

max (hi32) min (lo32) , 6 ( (?)), 19 hi32-fudge. 19 + 32 - 51 - IIRC Python.

, , .

: @unwind :

>>> a = 0x00000001/4294967296.0 + 0x4ca1f350
>>> b = 0x00000002/4294967296.0 + 0x4ca1f350
>>> b - a
0.0
>>>

2: , str(), repr(), timestamp_from_str()? , . - :

>>> class TS64(object):
...   def __init__(self, hi, lo):
...     self.hi = hi
...     self.lo = lo
...   def float_delta(self, other):
...     hi_delta = self.hi - other.hi
...     # check that abs(hi_delta) is not too large, if you must
...     return hi_delta + (self.lo - other.lo) / 4294967296.0
...
>>> a = TS64(0x4ca1f350, 1)
>>> b = TS64(0x4ca1f350, 2)
>>> b.float_delta(a)
2.3283064365386963e-10
>>> repr(_)
'2.3283064365386963e-10'
>>>

" ": 6 , (/2 ** 32)??? , float(difference(ts1, ts2)) float(ts1) - float(ts2), .

3: /

, :

, "" , , , - ( , 29 32 ) "". URL- .

1000000000 (10**9) . , math.log(10**9, 2) ( 29.897352853986263 , .. 30) , 29. , .

, : 32 , 29 30 3 2 ?

Secondly, one could count nanoseconds by seconds, dividing by 10**9. However, your expression in your question "" number 4ca1f350 9481ef80 translates to 1285682000.580107659 "" corresponds to the division by 2**32. In fact, 0x9481ef80 is 2,491,543,424, which is more than double 10**9. Please explain. What is the source of the expression "translates to"? Do you have other examples?

+1
source

Source: https://habr.com/ru/post/1766984/


All Articles