Ric*_*ich 24 java protocol-buffers
我开始将自定义序列化机制迁移到Protocol Buffers.将特别定期使用的一种数据类型是BigDecimal.
有没有人知道在Protocol Buffers中序列化这个的好方法?我们当前的序列化例程BigDecimal.toPlainString()用于序列化和new BigDecimal(String)反序列化 - 我假设有更好的方法.
我的猜测是将a定义BigDecimal为:
message BDecimal {
required int32 scale = 1;
required BInteger int_val = 2;
}
Run Code Online (Sandbox Code Playgroud)
但我不太清楚如何定义BigInteger- 也许使用它的toByteArray()方法?
not*_*oop 17
是.您应该将BigInteger定义为BigInteger.toByteArray().
我的猜测是BigDecimal会:
message BDecimal {
required int32 scale = 1;
required BInteger int_val = 2;
}
Run Code Online (Sandbox Code Playgroud)
而BigInteger可能被定义为
message BInteger {
required bytes value = 1;
}
Run Code Online (Sandbox Code Playgroud)
处理BigInteger的代码是:
BInteger write(BigInteger val) {
BInteger.Builder builder = BInteger.newBuilder();
ByteString bytes = ByteString.copyFrom(val.toByteArray());
builder.setValue(bytes);
return builder.build();
}
BigInteger read(BInteger message) {
ByteString bytes = message.getValue();
return new BigInteger(bytes.toByteArray());
}
Run Code Online (Sandbox Code Playgroud)
Die*_*ida 12
我最近有与OP相同的需求,并使用了与@notnoop提出的类似的解决方案。看到 @stikkos 的评论后将其发布在这里:
\n\n\n如何将 BigDecimal 转换为 BigInteger 并进行缩放?然后回来 ?
\n
根据BigDecimal课程文档:
\n\n的值为
\nBigDecimal(unscaledVal\xc3\x97 10-scale),根据精度和舍入模式设置进行舍入。
因此,java.math.BigDecimal可以考虑三个属性来序列化 a:
unscaledValuescaleprecision现在,代码。
\nProtobuf v3 消息定义:
\nsyntax = "proto3";\n\nmessage DecimalValue {\n uint32 scale = 1;\n uint32 precision = 2;\n bytes value = 3;\n}\nRun Code Online (Sandbox Code Playgroud)\n如何将 a 序列java.math.BigDecimal化为 Protobuf 消息:
syntax = "proto3";\n\nmessage DecimalValue {\n uint32 scale = 1;\n uint32 precision = 2;\n bytes value = 3;\n}\nRun Code Online (Sandbox Code Playgroud)\n如何将 Protobuf 消息反序列化回java.math.BigDecimal:
import com.google.protobuf.ByteString;\nimport DecimalValue;\n\njava.math.BigDecimal bigDecimal = new java.math.BigDecimal("1234.56789");\nDecimalValue serialized = DecimalValue.newBuilder()\n .setScale(bigDecimal.scale())\n .setPrecision(bigDecimal.precision())\n .setValue(ByteString.copyFrom(bigDecimal.unscaledValue().toByteArray()))\n .build();\nRun Code Online (Sandbox Code Playgroud)\n我们可以检查获得的产量java.math.BigDecimal是否与原始值相同,如下所示:
java.math.MathContext mc = new java.math.MathContext(serialized.getPrecision());\njava.math.BigDecimal deserialized = new java.math.BigDecimal(\n new java.math.BigInteger(serialized.getValue().toByteArray()),\n serialized.getScale(),\n mc);\nRun Code Online (Sandbox Code Playgroud)\njava.math.BigDecimal注意:OP 假设有比使用普通更好的方法来序列化 a String。在存储方面,这个解决方案更好。
例如,要序列化 \xcf\x80 的前 100 位小数:
\n3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679\nRun Code Online (Sandbox Code Playgroud)\nassert bigDecimal.equals(deserialized);\nRun Code Online (Sandbox Code Playgroud)\n这产生:
\nDecimalValue: 48\nString: 104\nRun Code Online (Sandbox Code Playgroud)\n