我最近和 OP 有同样的需求,并使用了与@notnoop 提出的类似的解决方案。在看到@stikkos 的评论后在这里发布:
您如何将 BigDecimal 转换为 BigInteger 并进行缩放?然后回来 ?
根据BigDecimal
类文档:
的值为BigDecimal
( unscaledVal
× 10-scale
),根据精度和舍入模式设置进行舍入。
因此,java.math.BigDecimal
可以考虑三个属性对 a 进行序列化:
现在,代码。
Protobuf v3 消息定义:
syntax = "proto3";
message DecimalValue {
uint32 scale = 1;
uint32 precision = 2;
bytes value = 3;
}
如何将 a 序列化为java.math.BigDecimal
Protobuf 消息:
import com.google.protobuf.ByteString;
import DecimalValue;
java.math.BigDecimal bigDecimal = new java.math.BigDecimal("1234.56789");
DecimalValue serialized = DecimalValue.newBuilder()
.setScale(bigDecimal.scale())
.setPrecision(bigDecimal.precision())
.setValue(ByteString.copyFrom(bigDecimal.unscaledValue().toByteArray()))
.build();
如何将 Protobuf 消息反序列化回java.math.BigDecimal
:
java.math.MathContext mc = new java.math.MathContext(serialized.getPrecision());
java.math.BigDecimal deserialized = new java.math.BigDecimal(
new java.math.BigInteger(serialized.getValue().toByteArray()),
serialized.getScale(),
mc);
我们可以检查获得的java.math.BigDecimal
产量是否与原始值相同,如下所示:
assert bigDecimal.equals(deserialized);
注意:OP 假设有java.math.BigDecimal
比使用普通的更好的方法来序列化 a String
。在存储方面,这个解决方案更好。
例如,要序列化 π 的前 100 位小数:
3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679
System.out.println("DecimalValue: " + serialized.getSerializedSize());
System.out.println("String: " + StringValue.of(pi).getSerializedSize());
这产生:
DecimalValue: 48
String: 104