小数值用 to_f 截断
Decimal values are truncating with to_f
我有一个名为 Item 的模型,我正在其中更新 unit_price(数据类型为十进制)值,目前我在存储值时没有设置任何限制,按原样存储值。但是现在我可以看到这个 PG 错误 PG::NumericValueOutOfRange,当值超过限制时。
所以我只是想限制值并在控制台中检查一些东西,下面是数据。 (这里的数据我没有放所有的小数值)
#<Item id: 167199, description: "192830139", category_id: 10327, unit_id: 5596, weight: 0.1e5, unit_price: 0.4083333333659917816764132553606237816656920077972709552126705653021442494641325536062378168e1
i = Item.find 167199
i.unit_price.to_f
=> 4.083333333659918
#<Item id: 167199, description: "192830139", category_id: 10327, unit_id: 5596, weight: 0.1e5, unit_price: 0.6511366980197836882065909262763993442019943880913510722934069011050182329156169820243980265070876781866034494363303661586489199452739290976143216266200531728395970406461889852558384421962422689303402903e-2
i.unit_price.to_f
=> 0.006511366980197837
请问to_f自动减少小数限制的原因是什么?解决这个问题的最佳方法是什么,我只是在考虑一些有限制的截断。
您可以使用 ruby 的内置 .truncate() 方法
例如:
floatNum = 1.222222222222222
truncatedNum = floatNum.truncate(3) #3 is the number of decimal places you want
puts floatNum #returns 1.222
另一种方法是使用 .round() 方法
例如:
Can I know what will be the reason the to_f automatically reduce the limit of the decimal?
原因是 to_f
方法用于将对象转换为 Float
s, which are standard 64-bit double precision floating point numbers. The precision of these numbers is limited, therefore the precision of the original object must be automatically reduced during the conversion process in order to make it fit in a Float
。所有额外的精度都将丢失。
您似乎在使用 the BigDecimal
class. The BigDecimal#to_f
method will convert the arbitrary precision floating point decimal object into a Float
. Naturally, information will be lost during this conversion should the big decimal be more precise than what Float
s 允许。如果超出限制,此转换实际上可能会溢出或下溢。
I was just thinking about some truncate with some limit
There is a truncate
method if you'd like explicit control over the precision of the result. No rounding of any kind will occur, there is a separate method for that.
BigDecimal#truncate
删除数字的整个小数部分,只留下一个整数。
BigDecimal('3.14159').truncate #=> 3
BigDecimal#truncate(n)
保留 n
位精度,删除其余部分。
BigDecimal('3.14159').truncate(3) #=> 3.141
我有一个名为 Item 的模型,我正在其中更新 unit_price(数据类型为十进制)值,目前我在存储值时没有设置任何限制,按原样存储值。但是现在我可以看到这个 PG 错误 PG::NumericValueOutOfRange,当值超过限制时。
所以我只是想限制值并在控制台中检查一些东西,下面是数据。 (这里的数据我没有放所有的小数值)
#<Item id: 167199, description: "192830139", category_id: 10327, unit_id: 5596, weight: 0.1e5, unit_price: 0.4083333333659917816764132553606237816656920077972709552126705653021442494641325536062378168e1
i = Item.find 167199
i.unit_price.to_f
=> 4.083333333659918
#<Item id: 167199, description: "192830139", category_id: 10327, unit_id: 5596, weight: 0.1e5, unit_price: 0.6511366980197836882065909262763993442019943880913510722934069011050182329156169820243980265070876781866034494363303661586489199452739290976143216266200531728395970406461889852558384421962422689303402903e-2
i.unit_price.to_f
=> 0.006511366980197837
请问to_f自动减少小数限制的原因是什么?解决这个问题的最佳方法是什么,我只是在考虑一些有限制的截断。
您可以使用 ruby 的内置 .truncate() 方法
例如:
floatNum = 1.222222222222222
truncatedNum = floatNum.truncate(3) #3 is the number of decimal places you want
puts floatNum #returns 1.222
另一种方法是使用 .round() 方法
例如:
Can I know what will be the reason the to_f automatically reduce the limit of the decimal?
原因是 to_f
方法用于将对象转换为 Float
s, which are standard 64-bit double precision floating point numbers. The precision of these numbers is limited, therefore the precision of the original object must be automatically reduced during the conversion process in order to make it fit in a Float
。所有额外的精度都将丢失。
您似乎在使用 the BigDecimal
class. The BigDecimal#to_f
method will convert the arbitrary precision floating point decimal object into a Float
. Naturally, information will be lost during this conversion should the big decimal be more precise than what Float
s 允许。如果超出限制,此转换实际上可能会溢出或下溢。
I was just thinking about some truncate with some limit
There is a truncate
method if you'd like explicit control over the precision of the result. No rounding of any kind will occur, there is a separate method for that.
BigDecimal#truncate
删除数字的整个小数部分,只留下一个整数。
BigDecimal('3.14159').truncate #=> 3
BigDecimal#truncate(n)
保留
n
位精度,删除其余部分。BigDecimal('3.14159').truncate(3) #=> 3.141