浮法VS十进制的ActiveRecordVS、浮法、ActiveRecord、十进制

2023-09-08 15:42:48 作者:久伴必碍

有时候,ActiveRecord的数据类型,让我困惑。错了,经常。我的一个永恒的问题是,对于一个给定的情况下,

Sometimes, Activerecord data types confuse me. Err, often. One of my eternal questions is, for a given case,

我应该使用:十进制:浮法

我经常遇到这样的链接, 的ActiveRecord ::十进制VS:浮动 的,但答案是不太够清楚,我是肯定的:

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.

下面是一些例子情况:

地理位置/经/纬度: -45.756688 120.5777777 ... 比率/百分比: 0.9 1.25 1.333 1.4143 ... Geolocation/latitude/longitude: -45.756688, 120.5777777, ... Ratio/percentage: 0.9, 1.25, 1.333, 1.4143, ...

我已经使用:十进制在过去,但我发现,应对的BigDecimal 在Ruby对象是不必要的尴尬相比于浮动。我也知道我可以使用:整数来重新present钱/分,例如,但它并不完全适合其他情况下,例如当批量其中precision会随时间而改变。

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.

什么是使用每个?的优势/劣势 什么是拇指一些好的规则,知道使用?哪种类型

推荐答案

我记得我CompSci教授说从来没有使用花车货币。

I remember my CompSci professor saying never to use floats for currency.

这其中的原因是怎样的 IEEE规范定义的花车的二进制格式。基本上,它存储的迹象,小数和指数重新present一个浮动。这就像一个科学记数法二进制(类似 + 1.43 * 10 ^ 2 )。正因为如此,它是不可能的存储分数和小数的浮点精确地。

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:

irb:001:0> "%.47f" % (1.0/10)
=> "0.10000000000000000555111512312578270211815834045" # not "0.1"!

而如果你只是做

whereas if you just do

irb:002:0> (1.0/10).to_s
=> "0.1" # the interprer rounds the number for you

所以,如果你正在处理的小部分,像复利利益,或者甚至地理位置,我会强烈建议十进制格式,因为在十进制格式 1.0 / 10 正是0.1。

然而,应该指出的是,尽管是较不准确,浮筒被处理速度更快。这里有一个基准:

However, it should be noted that despite being less accurate, floats are processed faster. Here's a benchmark:

require "benchmark" 
require "bigdecimal" 

d = BigDecimal.new(3) 
f = Float(3)

time_decimal = Benchmark.measure{ (1..10000000).each { |i| d * d } } 
time_float = Benchmark.measure{ (1..10000000).each { |i| f * f } }

puts time_decimal 
#=> 6.770960 seconds 
puts time_float 
#=> 0.988070 seconds

答案

使用浮动当你不关心precision太多。例如,一些科学模拟和计算只需要高达3或4显著数字。这是在权衡精度速度非常有用。因为他们并不需要precision尽可能的速度,他们会用浮动。

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.

使用十进制如果你正在处理的需要是precise和总结,以正确的号码(如复合的利益和金钱有关的事情)的数字。请记住:如果你需要precision,那么你应该总是使用十进制

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.