gRPC中的协议缓冲区无法保存大的浮点数 - 该怎么办?

时间:2017-09-05 08:37:09

标签: python protocol-buffers grpc

我正在使用带有gRPC的协议缓冲区。我的.proto文件看起来像

syntax = "proto3";

option java_multiple_files = true;
option objc_class_prefix = "DRPC";

package my_rpc;

service RPCData {
  // Sends a cycle of data
  rpc RunRequest (CycleData) returns (OutputScores) {}
}

message CycleData {
  repeated float timestamps = 1;
  repeated float values = 2;
}

但系统似乎削减了我的价值观:

>>> dtw_rpc_pb2.CycleData(timestamps=[1501545616.742662], values=[5])
timestamps: 1501545600.0
values: 5.0

我猜它无法准确表示那些大值:

>>> dtw_rpc_pb2.CycleData(timestamps=[16.742662], values=[5])
timestamps: 16.74266242980957
values: 5.0
>>> dtw_rpc_pb2.CycleData(timestamps=[45616.742662], values=[5])
timestamps: 45616.7421875
values: 5.0
>>> dtw_rpc_pb2.CycleData(timestamps=[1545616.742662], values=[5])
timestamps: 1545616.75
values: 5.0
>>> dtw_rpc_pb2.CycleData(timestamps=[1501545616.742662], values=[5])
timestamps: 1501545600.0
values: 5.0

我该怎么办?

2 个答案:

答案 0 :(得分:1)

对于纯python protobuf,python-float用于float和double。但是cpp实现调用了一些C ++ protobuf代码,使它与纯python不同。

答案 1 :(得分:0)

documentation有点误导(这意味着对Python-float的转换独立于proto类型,所以我认为它没有帮助),但是如果使用“double”它就可以工作。 / p>

所以,我需要改变

message CycleData {
  repeated float timestamps = 1;
  repeated float values = 2;
}

message CycleData {
  repeated double timestamps = 1;
  repeated float values = 2;
}

正如Jie Luo在评论中解释的那样,背景是Python的浮动实际上已经具有双精度。没有C风格的浮动。另一方面,Protobuf确实将“浮动”和“双重”识别为不同的类型。使用Protobuf的double类型实际上与Python的float相同,而Protobuf的float会降低精度,导致问题中描述的问题。