ruby - 将字符串货币转换为使用 ruby 浮动
问题描述
我有以下字符串:
“1.273,08”
我需要转换为浮点数,结果必须是:
1273.08
我尝试了一些使用 gsub 的代码,但我无法解决这个问题。我该如何进行这种转换?
解决方案
您已经收到了两个很好的答案,如何使用和将您按摩String
成您想要的格式。String#delete
String#tr
但还有一个更深层次的问题。
十进制值 1 273.08 10 无法准确表示为 IEEE 754-2019 / ISO/IEC 60559:2020 binary64浮点值。
就像值 1/3rd 可以很容易地以三进制 (0.1 3 ) 表示,但在十进制中具有无限表示 (0.33333333...<sub>10,即 0.[3]...<sub>10),因此无法准确表示, 值 8/100 可以很容易地用十进制 (0.08 10 ) 表示,但在二进制中具有无限表示 (0.0001010001111010111000010100011110101110000101...<sub>2, 即 0.[00010100011110101110]...<sub>2)。换句话说,不可能将 1 273.08 10表示为 Ruby Float
。
这不是特定于 Ruby,甚至不是编程,这只是基本的高中数学:你不能用二进制表示这个数字,句点,就像你不能用十进制表示 1/3 或任何整数基数的 π。
当然,计算机没有无限的内存,所以 1 273.08 10不仅在二进制中有无限表示,而且作为 a Float
,在 64 位之后也会被截断。作为 IEEE 754-2019 / ISO/IEC 60559:2020 binary64浮点值,最接近 1 273.08 10的可能值为 1 273.079 999 999 999 927 240 423 858 17 10,小于1 273.08 10。
这就是为什么你永远不应该使用二进制数字来表示货币:每个人都会期望它是十进制的,而不是二进制的;如果我写一张支票,我用十进制写,而不是二进制。人们会期望代表 1/3 美元是不可能的,他们会期望代表 π 美元是不可能的,但是他们不会期望也不会接受如果他们将 1273.08 美元存入他们的账户,他们实际上最终会得到略低于那个。
表示金钱的正确方法是使用专门的Money
数据类型,或者至少使用bigdecimal
标准库中的库:
require 'bigdecimal'
BigDecimal('1.273,08'.delete('.').tr(',', '.'))
#=> 0.127308e4
推荐阅读
- sql-server-2016 - 为什么时态表中的结束日期是最大系统时间而不仅仅是 NULL
- java - 即使为空,如何干净地处理 java 8 流“findFirst()”结果
- python - 张量流(或numpy)中特定维度的矩阵乘法
- prestashop - PrestaShop 在 1.7.4.3 上偏移 5 处的无效 UTF-8 字符串
- c++ - c++中的mpi all to all v
- mysql - 左连接上的 Concat 正则表达式
- javascript - 如何让视口元标记在我的响应式网站上正常工作?
- javascript - 从 offsetX 值中获取数值
- php - 挣扎于 PHP/MySQL 分页
- python - Cx_Freeze 构建没有错误,但 exe 没有打开