簡體   English   中英

Python cbor2 以首選(高效)格式編碼浮點數

[英]Python cbor2 encode float in preferred (efficient) format

CBOR 文檔 state 應該首選最有效(字節數較少)的編碼。

浮點數可以編碼為 64 位浮點數,或擴展為 32 位、16 位、BigFloat 或 DecimalFloat 格式。

標准 64 位編碼使用 9 個字節。 如果使用替代格式,一些浮點值可以占用更少的空間(例如,值 0.0、1.0、1.5 可以使用 BigFloats 表示為 4 個字節)。

有些值更好地表示為標准浮點數(例如 0.123456789 由 9 個字節表示為 64 位浮點數或 29 個字節與 BigFloats。

如果使用Decimal類型, cbor2 python 庫支持 BigFloats,如果使用float類型,則支持 float。

如何讓cbor2根據實際值自動發出最有效的類型?

我使用cbor2.dumps()嘗試了各種任意值。 floats總是被編碼為 CBOR 浮點數, Decimal類型總是被編碼為 CBOR BigFloats。

>>> x=0.0 ; x ; d1 = dumps(x) ; d1 ; len(d1) ; dx = Decimal(x) ; d2 = dumps(dx) ; d2 ; len(d2)
0.0
b'\xfb\x00\x00\x00\x00\x00\x00\x00\x00'
9
b'\xc4\x82\x00\x00'
4

>>> x=1.0 ; x ; d1 = dumps(x) ; d1 ; len(d1) ; dx = Decimal(x) ; d2 = dumps(dx) ; d2 ; len(d2)
1.0
b'\xfb?\xf0\x00\x00\x00\x00\x00\x00'
9
b'\xc4\x82\x00\x01'
4

>>> x=1.5 ; x ; d1 = dumps(x) ; d1 ; len(d1) ; dx = Decimal(x) ; d2 = dumps(dx) ; d2 ; len(d2)
1.5
b'\xfb?\xf8\x00\x00\x00\x00\x00\x00'
9
b'\xc4\x82 \x0f'
4

>>> x=0.123456789 ; x ; d1 = dumps(x) ; d1 ; len(d1) ; dx = Decimal(x) ; d2 = dumps(dx) ; d2 ; len(d2)
0.123456789
b'\xfb?\xbf\x9a\xdd79c_'
9
b'\xc4\x8287\xc2W\x80\xe5\x18Js\xc0\xe4\x8f-\xf1\xc9\xf0\x90\xf4u%+\x93\xa7\n\x88\xa2?'
29

所以我發現答案是結合使用 dumps dumps()canonical=True參數並將浮點數轉換為較低精度的浮點數(使用numpy )(如果任何精度損失是可以容忍/可接受的)。

注意:必須轉換回 python 浮點數,因為cbor目前無法編碼numpy類。

>>> x=0.123456789 ; x ; d1=dumps(x, canonical=True) ; d1 ; len(d1)
0.123456789
b'\xfb?\xbf\x9a\xdd79c_'
9

>>> x=float( np.float32( 0.123456789 ) ) ; x ; d1=dumps(x, canonical=True) ; d1 ; len(d1)
0.12345679104328156
b'\xfa=\xfc\xd6\xea'
5

>>> x=float( np.float16( 0.123456789 ) ) ; x ; d1=dumps(x, canonical=True) ; d1 ; len(d1)
0.12347412109375
b'\xf9/\xe7'
3

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM