[英]Python cbor2 encode float in preferred (efficient) format
The CBOR docs state that the most efficient (less number of bytes) encoding should be preferred. CBOR 文档 state 应该首选最有效(字节数较少)的编码。
floats can be encoded as 64-bit floats, or with extensions as 32-bit, 16-bit, BigFloat or DecimalFloat formats.浮点数可以编码为 64 位浮点数,或扩展为 32 位、16 位、BigFloat 或 DecimalFloat 格式。
Stanards 64-bit encoding uses 9 bytes.标准 64 位编码使用 9 个字节。 Some floating values can take much less space if using an alterantive format (eg the values 0.0, 1.0, 1.5 can be represented as 4 bytes using BigFloats).如果使用替代格式,一些浮点值可以占用更少的空间(例如,值 0.0、1.0、1.5 可以使用 BigFloats 表示为 4 个字节)。
Some values are better represented as standard floats (eg 0.123456789 is represented by 9 bytes as 64-bit float or 29 bytes with BigFloats.有些值更好地表示为标准浮点数(例如 0.123456789 由 9 个字节表示为 64 位浮点数或 29 个字节与 BigFloats。
The cbor2
python library supports BigFloats if using the Decimal
type, or the float if using the float
type.如果使用Decimal
类型, cbor2
python 库支持 BigFloats,如果使用float
类型,则支持 float。
How can I get cbor2
to automatically emit the most efficient type depending on the actual value?如何让cbor2
根据实际值自动发出最有效的类型?
I have tried various arbitrary values using cbor2.dumps()
.我使用cbor2.dumps()
尝试了各种任意值。 floats
are always encoded as CBOR floats, and Decimal
types are alwasy encoded as CBOR BigFloats. 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
So I found the answer is a combination of using the canonical=True
argument to dumps()
and casting the floats to lower precision floats (using numpy
) where suitable (if any loss of precision is tolerable/acceptable).所以我发现答案是结合使用 dumps dumps()
的canonical=True
参数并将浮点数转换为较低精度的浮点数(使用numpy
)(如果任何精度损失是可以容忍/可接受的)。
NOTE: have to cast back to python float as cbor
can't encode numpy
classes at the momement.注意:必须转换回 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.