我有一个需要保存18位数值的列。它在我的rails文件中定义为
Schema.rb
t.decimal "revenue", precision: 23, scale: 5
现在,当我在控制台中尝试以下操作时:
obj = Model.last
obj.revenue = 999999999999999999 ( 18 nines)
obj.save is returning false
(我已确认最大收入应小于1000000000000000000(1后跟18个零)
对模态的验证:
validates :revenue , numericality: {:greater_than => WBConstants::MIN_REVENUE_LIMIT, :less_than => WBConstants::MAX_REVENUE_LIMIT}, allow_blank: true
错误消息显示该值应小于100 ...(1后跟18个零)
我无法保存。 我使用的数据库是sqlserver 列数据类型为decmial(23,5)
答案 0 :(得分:2)
这是Rails中的一个错误,已经有pull request。
在修复合并之前,您可以perform custom validation。
使用Kernel.Float
:
f = Kernel.Float(999_999_999_999_999_999)
#=> 1.0e+18
f < 1_000_000_000_000_000_000
#=> false
f == 1_000_000_000_000_000_000
#=> true
因为浮点数的精度有限,并且只能完全代表某些整数:
(999999999999999000..1000000000000001000).map { |i| i.to_f.to_i }.uniq
#=> [999999999999998976,
# 999999999999999104,
# 999999999999999232,
# 999999999999999360,
# 999999999999999488,
# 999999999999999616,
# 999999999999999744,
# 999999999999999872,
# 1000000000000000000,
# 1000000000000000128,
# 1000000000000000256,
# 1000000000000000384,
# 1000000000000000512,
# 1000000000000000640,
# 1000000000000000768,
# 1000000000000000896,
# 1000000000000001024]
有关详细信息,请参阅What Every Computer Scientist Should Know About Floating-Point Arithmetic。
答案 1 :(得分:0)
到目前为止,您可以使用自定义验证来解决此问题。 请查看以下链接: Custom Validators
希望这对你有所帮助。