Ruby JSON将非整数解析为字符串(或BigDecimal)

时间:2016-06-28 22:03:14

标签: ruby json

有没有办法告诉默认的ruby JSON库将非整数数值解析为字符串(或BigDecimal?)而不是浮点数?

JSON.parse('{"foo": 123.45}')['foo'].class输出Float,这可能会导致精确问题。

PD:oj库支持将这些值加载为BigDecimals。

PD2:似乎没有:https://github.com/flori/json/blob/76f41a84e2bace20c3076aba53887537e37dfdb2/lib/json/pure/parser.rb#L196

1 个答案:

答案 0 :(得分:0)

理论上,作为容器的JSON可以保存高度精确的数字,但实际上,一端通常仅限于IEEE 754双精度浮点数,因为这本身就是JavaScript本身所限制的。如果值是用JavaScript或几乎任何JSON实现编码的话,就会产生任何精度损失。

因此,从解析后的BigDecimal转换为Float几乎总会导致精确度不会下降:

data = JSON.parse("[1.025]")
# Float can't represent decimal values precisely, so `round` fails
data.first.round(2) # => 1.02
# Converting to big decimal improves the precision of future operations
BigDecimal.new(data.first.to_s).round(2).to_s # => "1.03"

最好将高精度值作为字符串传输。

最后,如果你真的需要ruby库,可以随时修补猴子以表现你想要的行为。