ActiveRecord 中的浮点型与小数型
有时,Activerecord 数据类型让我感到困惑。呃,经常。我永恒的问题之一是,对于特定情况,
我应该使用
:decimal
还是:float
?
我经常遇到这个链接,ActiveRecord: :decimal vs :float? ,但答案还不够明确,无法让我确定:
我见过很多帖子,人们建议坚决不要使用 浮动并始终使用小数。我也看到了一些人的建议 人们仅将浮点数用于科学应用。
以下是一些示例:
- 地理位置/纬度/经度:
-45.756688
,120.5777777
,... - 比率/百分比:
0.9
,1.25
、1.333
、1.4143
、...
我在中使用了 :decimal
过去,但我发现与浮点数相比,在 Ruby 中处理 BigDecimal 对象不必要地尴尬。例如,我还知道我可以使用 :integer
来表示金钱/美分,但它不太适合其他情况,例如当精度可能随时间变化的数量时。
- 使用每种方法的优点/缺点是什么?
- 有哪些好的经验法则可以帮助您了解使用哪种类型?
Sometimes, Activerecord data types confuse me. Err, often. One of my eternal questions is, for a given case,
Should I use
:decimal
or:float
?
I've often come across this link, ActiveRecord: :decimal vs :float?, but the answers aren't quite clear enough for me to be certain:
I've seen many threads where people recommend flat out to never use
float and always use decimal. I've also seen suggestions by some
people to use float for scientific applications only.
Here are some example cases:
- Geolocation/latitude/longitude:
-45.756688
,120.5777777
, ... - Ratio/percentage:
0.9
,1.25
,1.333
,1.4143
, ...
I have used :decimal
in the past, but I found dealing with BigDecimal
objects in Ruby was unnecessarily awkward as compared to a float. I also know I can use :integer
to represent money/cents, for example, but it doesn't quite fit for other cases, for example when quantities in which precision could change over time.
- What are the advantages/disadvantages of using each?
- What would be some good rules of thumb to know which type to use?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我记得我的 CompSci 教授说过永远不要使用浮动货币。
原因在于 IEEE 规范如何以二进制格式定义浮点数。基本上,它存储符号、分数和指数来表示浮点数。它就像二进制的科学记数法(类似于
+1.43*10^2
)。因此,不可能在 Float 中精确存储分数和小数。这就是为什么有十进制格式。如果你这样做:
而如果你只是
这样做,那么如果你正在处理小分数,比如复利,甚至可能是地理定位,我强烈推荐十进制格式,因为在十进制格式中
1.0/10
是正好是 0.1。然而,应该指出的是,尽管精度较低,但浮点数的处理速度更快。这是一个基准:
回答
当您不太关心精度时,请使用float。例如,一些科学模拟和计算最多只需要3或4位有效数字。这对于权衡准确性和速度很有用。由于他们对精度的要求不如对速度的要求,因此他们会使用浮动。
如果您处理的数字需要精确并求和为正确的数字(例如复利和与金钱相关的事物),请使用小数。请记住:如果您需要精度,那么您应该始终使用小数。
I remember my CompSci professor saying never to use floats for currency.
The reason for that is how the IEEE specification defines floats in binary format. Basically, it stores sign, fraction and exponent to represent a Float. It's like a scientific notation for binary (something like
+1.43*10^2
). Because of that, it is impossible to store fractions and decimals in Float exactly.That's why there is a Decimal format. If you do this:
whereas if you just do
So if you are dealing with small fractions, like compounding interests, or maybe even geolocation, I would highly recommend Decimal format, since in decimal format
1.0/10
is exactly 0.1.However, it should be noted that despite being less accurate, floats are processed faster. Here's a benchmark:
Answer
Use float when you don't care about precision too much. For example, some scientific simulations and calculations only need up to 3 or 4 significant digits. This is useful in trading off accuracy for speed. Since they don't need precision as much as speed, they would use float.
Use decimal if you are dealing with numbers that need to be precise and sum up to correct number (like compounding interests and money-related things). Remember: if you need precision, then you should always use decimal.
在 Rails 3.2.18 中,使用 SQLServer 时 :decimal 会变成 :integer,但它在 SQLite 中工作正常。切换到 :float 为我们解决了这个问题。
吸取的教训是“始终使用同质开发和部署数据库!”
In Rails 3.2.18, :decimal turns into :integer when using SQLServer, but it works fine in SQLite. Switching to :float solved this issue for us.
The lesson learned is "always use homogeneous development and deployment databases!"
在 Rails 4.1.0 中,我遇到了将纬度和经度保存到 MySql 数据库的问题。它不能用浮点数据类型保存大分数。我将数据类型更改为十进制并为我工作。
In Rails 4.1.0, I have faced problem with saving latitude and longitude to MySql database. It can't save large fraction number with float data type. And I change the data type to decimal and working for me.