代码之家  ›  专栏  ›  技术社区  ›  Two-Bit Alchemist

为什么Ruby不正确地解析带逗号的字符串?

  •  1
  • Two-Bit Alchemist  · 技术社区  · 7 年前

    irb(main):001:0> "5,280".to_f
    => 5.0
    

    我可以 几乎 "5,280".to_i == 5 自从 , 在某些区域设置中是十进制类型的分隔符,但是这里的精度损失让我感到困惑,特别是因为 "5.280".to_f 5.28

    这只是虫子吗?

    $ ruby --version
    ruby 2.3.7p456 (2018-03-28 revision 63024) [universal.x86_64-darwin17]
    
    3 回复  |  直到 7 年前
        1
  •  1
  •   igor_rb    7 年前

    Ruby只需呼叫 strtod https://github.com/ruby/ruby/blob/38caab29bc759be2694013fc3930116e64fcc1d4/object.c#L3278

    d = strtod(p, &end);
    

    strtod函数是这样的:

    /*
     * Count the number of digits in the mantissa (including the decimal
     * point), and also locate the decimal point.
     */
    
    decPt = -1;
    for (mantSize = 0; ; mantSize += 1)
    {
    c = *p;
    if (!isdigit(c)) {
        if ((c != '.') || (decPt >= 0)) {
        break;
        }
        decPt = mantSize;
    }
    p += 1;
    }
    

    https://opensource.apple.com/source/tcl/tcl-10/tcl/compat/strtod.c

    根据 if ((c != '.') || (decPt >= 0)) { break; 字符串转换为浮点数 如果发现任何非点符号,则停止,例如:

    irb(main):002:0> "2;58".to_f
    => 2.0
    irb(main):003:0> "2@58".to_f
    => 2.0
    irb(main):004:0> 
    

    UPD:这种方法对于mri2.6ruby实现是有效的。在其他版本/实现中可能会有所不同。

        2
  •  5
  •   mu is too short    7 年前

    fine 2.3.7 manual (但是 current docs


    返回解释中前导字符的结果 str 作为浮点数。超过有效数字结尾的多余字符将被忽略。如果开头没有有效的数字 str公司

    "5,280".to_f 做的正是它应该做的。逗号之前(但不包括)的所有字符都是有效的数字和多余的字符( ",280" 在这种情况下)被忽略。结果与调用相同 '5'.to_f .

    String#to_f 因为至少 Ruby 1.8.6 .

        3
  •  1
  •   Tennesseej    7 年前

    Ruby查看从左边开始的字符串,以及任何0-9的字符(第一个小数点)和后面0-9的字符,它将匹配并尝试转换为浮点。任何右边的都会被忽略。

    https://apidock.com/ruby/String/to_f

    示例:

    >>'5.5'.to_f 
    => 5.5
    
    >>'5.5stuff'.to_f 
    => 5.5   
    
    >>'5.stuff5'.to_f 
    => 5.0
    
    >>'5,5'.to_f 
    => 5.0
    
    >>'stuff5.5'.to_f 
    => 0.0
    
    推荐文章