ruby-on-rails – Rails通过抛出浮点逻辑来搞乱BigDecimals

ruby-on-rails – Rails通过抛出浮点逻辑来搞乱BigDecimals,第1张

概述我正在玩铁轨,我发现了一些奇怪的东西.为了存储货币值,我使用典型的十进制数据类型,活动记录转换为BigDecimal.我认为这是精确的,我想避免浮点数学的奇怪行为.但是当我将99.99存储到数据库时,一切正常,但是当记录被活动记录加载时,它会失去精度并转换为99.9899999999之类的东西.这看起来像一个浮点问题. 我做了一些测试,发现像这样创建一个BigDecimal b = BigDeci 我正在玩铁轨,我发现了一些奇怪的东西.为了存储货币值,我使用典型的十进制数据类型,活动记录转换为BigDecimal.我认为这是精确的,我想避免浮点数学的奇怪行为.但是当我将99.99存储到数据库时,一切正常,但是当记录被活动记录加载时,它会失去精度并转换为99.9899999999之类的东西.这看起来像一个浮点问题.

我做了一些测试,发现像这样创建一个BigDecimal b = BigDecimal.new(“99.99”)导致一个“干净”的变量但是这样构建它b = BigDecimal.new(99.99)会导致“不洁”的版本我想避免.

我想,当从数据库加载记录时,ActiveRecord用一个中间浮点重建BigDecimal.这不是我想要的,我想知道是否可以避免.

Ruby版本1.9.3p0
Rails 3.2.9
sqlite 3.7.9

解决方法 您的问题是您使用的是sqlite,而sqlite没有对数字(m,n)数据类型的本机支持.从 fine manual:

1.0 Storage Classes and Datatypes

Each value stored in an sqlite database (or manipulated by the database engine) has one of the following storage classes:

NulL. The value is a NulL value. INTEGER. The value is a signed integer,stored in 1,2,3,4,6,or 8 bytes depending on the magnitude of the value. REAL. The value is a floating point value,stored as an 8-byte IEEE floating point number. TEXT. The value is a text string,stored using the database enCoding (UTF-8,UTF-16BE or UTF-16LE). BLOB. The value is a blob of data,stored exactly as it was input.

请继续阅读该页面,了解sqlite的类型系统的工作原理.

您的Ruby代码中的99.99可能是BigDecimal.new(’99 .99′),但它几乎可以肯定是sqlite中的REAL值99.99(即一个8字节的IEEE浮点值)并且存在邻域.

因此,在开发环境中切换到更好的数据库;特别是,在您要部署的任何数据库之上进行开发.

总结

以上是内存溢出为你收集整理的ruby-on-rails – Rails通过抛出浮点逻辑搞乱BigDecimals全部内容,希望文章能够帮你解决ruby-on-rails – Rails通过抛出浮点逻辑来搞乱BigDecimals所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1283363.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-09
下一篇 2022-06-09

发表评论

登录后才能评论

评论列表(0条)

保存