如何使用谷歌protobuf在网络上发送浮点数?

时间:2015-08-05 06:32:08

标签: protocol-buffers

我有一个proto文件,其中包含以下消息:

$this->db->select('p.*,group_concat(t.name order by t.id) as thetags,
                       group_concat(t.relevance order by t.id) as therelevances');
$this->db->from('posts p');
$this->db->join('tags_map tm', 't.id_post = p.id');
$this->db->join('tags t', 't.id = tm.id_tag');
$this->db->group_by('p.id');

其中,version是浮点值。 当我将浮点值2.1从c ++发送到python时,在python端,它被反序列化为2.09999990463。

为什么会这样?对浮点数有任何特殊处理吗?

Protoc编译器版本和运行时protobuf库版本是2.4.1。

2 个答案:

答案 0 :(得分:1)

值2.1不能完全表示为浮点数。您可以在简单的C ++程序或C ++调试器中对此进行测试:

(gdb) print 2.1f
$1 = 2.0999999
然而,Python将一切都呈现为双打。因此,从C ++接收的浮点值将转换为最接近2.0999999 ...的double,而不是最接近2.1。

这只是因为并非所有十进制数都可以完全表示为浮点数。一般来说,浮点数总是有舍入误差,你不能指望它们是正确的值,只是非常接近。

答案 1 :(得分:0)

由于 Python 仅支持双精度,您还可以更改 C++ 代码和 proto 规范以使用“双精度”。那么一切都会加倍,同样的精度错误将以同样的方式影响 C++ 和 Python,你将在所有平台上得到相同的结果。

当然假设您的 C++ 编译器使用 IEEE 754 标准来处理双精度浮点数(大多数现代编译器都这样做。)