新手问题 请问有谁能谈谈,在migration里decimal和float的具体区别呢?

QueXuQ · 发布于 2013年01月25日 · 最后由 xiaoronglv 回复于 2013年12月08日 · 3565 次阅读
3547

我看基本涉及金额的,都是用decimal多。 如果我是一个数量问题呢,1,2,3,4,小数点也最多就1.11,2.34两位而已。 请问使用decimal和float有什么区别呢?

共收到 22 条回复
2880

decimal是用字符串存的, 或者说是10进制, 占用空间大, 运算速度慢, 精度可定制 float是按照ieee标准存的, 或者说是2进制, 占用空间小, 运算速度快, 精度固定

只是10进制有限小数在2进制里可能是无限循环小数, 存储空间的长度是固定的肯定要截断

3547

#1楼 @luikore 其实看了,觉得不是太理解,感觉是这样的话,好像float就没有存在的必要那样。 意思就是小数点尾数少的,数量小的,可以选择用float,提高效率。 而太大的,和需要精度定制就选择decimal了?

2880
1.4+1.7
=> 3.0999999999999996

如果是工程计算, 这个结果精度是非常高的, 但如果是算钱, 这个结果是 3.1 才对:

require 'bigdecimal'
(BigDecimal('1.4') + BigDecimal('1.7')).to_s 'F'
=> "3.1"
3547

#3楼 @luikore

1.9.3p125 :001 > 1.4+1.7
 => 3.0999999999999996 
1.9.3p125 :002 > 2.1+3.2
 => 5.300000000000001 
1.9.3p125 :003 > 455.2+2333.1112
 => 2788.3111999999996 
1.9.3p125 :004 > 2.3*4
 => 9.2 
1.9.3p125 :005 > 2.55*4.2
 => 10.709999999999999 

试了一下,还真的是,这种精度要什么场合才用的上。。 那像一般需要精确的数值,还是用decimal好了吧。我存的只是商品数量,需要有小数。

2880

#4楼 @QueXuQ 整数的话用 int 就可以了, 完全没这类问题

3547

#5楼 @luikore 不是整数,需要有小数。那是不是还是用decimal好了?

2880

#6楼 @QueXuQ 如果是需要显示".0", 最后格式化一下就好了... 如果商品的量是诸如千克之类的, 有 3 位小数, 改成用克 + 整数保存可能更方便

3547

#7楼 @luikore 不懂怎么是格式化? 比较混杂,有大量的整数,但是个别商品可能会分块出售,所以无论出入,都有可能出现数量是3.55,2.5,之类的情况,但在两位小数内。。请问怎么整比较好?

2880

#8楼 @QueXuQ decimal 或者 乘100 用整数都可以吧

我说的格式化是 '%.2f' % 1 #=> "1.00" 的意思, 好像没什么关系...

3547

#9楼 @luikore 哦。貌似是个单纯的显示。 没想到float有那么大的学问,等我想想用什么方案处理这个问题好。谢谢。_^

3191

涉及到金额用 integer 到保存到分

1342

我这编码规约只要是金额的全都用bigdecimal,因为客户要求最大存13个9

202

这个和数据库设计有关,Decimal比float位数宽,记录的信息更多一些。

3547

#11楼 @knwang 然后现实在除100吗?

3191

#14楼 @QueXuQ 什么叫“现实”?

3547

#15楼 @knwang 显示。。。 就是说,输入15.55元,存入时乘100 = 1555 读取时候,除于100 ,显示15.55

3191

#16楼 @QueXuQ 看你怎么显示了,换成元就是 / 100 了

3547

#17楼 @knwang 好。谢谢。似乎一般都使用integer,要比使用decimal和float好。

96

#1楼 @luikore 这个还真不是按照字符串存。字符串存浪费太大了。一般是八个位已存,第一位是1表示还有后续位,为0表示结束了。后面7个二进制位存数据。

2880

#19楼 @jimrokliu 用 BCD 存还是字符串存看数据库的实现吧, 如果是 mongo 或者 sqlite 肯定是字符串

96

#20楼 @luikore 是的,确实要看实现。可能有另外的实现。

1638

#1楼 @luikore

我忽然明白了1.4 + 1.7 = 3.09999999999999999了

谢谢

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册