V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
songdg
V2EX  ›  Python

请教为什么不相等

  •  
  •   songdg · 2018-11-05 12:10:35 +08:00 · 3357 次点击
    这是一个创建于 2208 天前的主题,其中的信息可能已经有所发展或是发生改变。
    arr = np.array([3.12, 3.43, 3.77, 4.15, 4.57],dtype=np.float32)
    In : arr[-1]
    Out : 4.57
    In : arr[-1] == 4.57
    Out : False
    21 条回复    2018-11-18 00:00:37 +08:00
    ybping
        1
    ybping  
       2018-11-05 12:14:20 +08:00 via iPhone
    浮点数比较相等没意义
    zicla
        2
    zicla  
       2018-11-05 12:17:34 +08:00
    你猜 js 中 0.1+0.2 等于多少? 不是 0.3,而是 0.30000000000000004。所以楼上正解,浮点数不适合做等的比较。
    rabbbit
        3
    rabbbit  
       2018-11-05 12:24:41 +08:00
    arr = np.array([ 4.57],dtype=np.float64)
    arr[0] == 4.57 # True
    huashengshu
        4
    huashengshu  
       2018-11-05 12:28:02 +08:00   ❤️ 1
    浮点精度损失
    MinQ
        5
    MinQ  
       2018-11-05 12:29:40 +08:00 via Android
    浮点数都是相减小于 0.000001 啥就算相等
    wizardoz
        6
    wizardoz  
       2018-11-05 12:42:42 +08:00
    永远不要用两个浮点数比较相等
    XuanFei990
        7
    XuanFei990  
       2018-11-05 12:48:50 +08:00
    这个问题,在 C 语言里不就应该知道了么,,,

    难道不学 C 语言?好吧。。

    浮点数比较一般都是两数相减,小于一个误差值就可以认为是相等了。。。
    rabbbit
        8
    rabbbit  
       2018-11-05 12:54:42 +08:00
    >>> '{0:.20f}'.format(np.float32(4.57))
    '4.57000017166137695312'
    >>> '{0:.20f}'.format(np.float64(4.57))
    '4.57000000000000028422'
    >>> '{0:.20f}'.format(4.57)
    '4.57000000000000028422'
    pinews
        9
    pinews  
       2018-11-05 13:01:18 +08:00
    <?php
    $a=0.1;
    $b=0.2;
    $c=0.3;

    var_dump(bccomp(bcadd($a, $b), $c));

    ?>
    aimiyooo
        10
    aimiyooo  
       2018-11-05 13:32:54 +08:00
    浮点数不能直接比较相等,只能|a-b|<c(一个小数)来判断
    songdg
        11
    songdg  
    OP
       2018-11-05 14:21:24 +08:00
    谢谢大家的帮助,还有一个问题 arr = np.array([3.12, 3.43, 3.77, 4.15, 4.57],dtype=np.float32),brr = np.array([2.56, 2.81, 3.09, 3.39, 4.57],dtype=np.float32),那么为什么 arr[-1] == brr[-1]却是正确的。
    blindpirate
        12
    blindpirate  
       2018-11-05 14:24:22 +08:00
    “浮点数都比较没有意义”的意思是,无论相等还是不等,都没有意义。
    nekoneko
        13
    nekoneko  
       2018-11-05 14:29:18 +08:00
    @songdg 指向同一个地址吧
    neoblackcap
        14
    neoblackcap  
       2018-11-05 14:37:12 +08:00   ❤️ 1
    因为不管是 C 语言还是 Python 的浮点都是用 IEEE 754,这个没法表示准确的 10 进制小数。
    1a0ma0
        15
    1a0ma0  
       2018-11-05 14:38:31 +08:00 via iPhone
    你应该去查查浮点数在计算机里是怎么表示的。
    mario85
        16
    mario85  
       2018-11-05 15:44:51 +08:00   ❤️ 1
    @songdg
    >>> import numpy as np
    >>> arr = np.array([3.12, 3.43, 3.77, 4.15, 4.57],dtype=np.float32)
    >>> arr[-1]
    4.57
    >>> arr[-1]==4.57
    False
    >>> arr[-1]==np.float32(4.57)
    True
    Alias4ck
        17
    Alias4ck  
       2018-11-05 17:03:09 +08:00   ❤️ 2
    很简单一个问题。一个是 numpy.float32 一个是内置 float 类型不一致 一个是 numpy 的数字类型 一个是 native type
    你可以用 arr[-1].item() 转换 就可以和 native 的比对了 实际他转成 float 的数值并不是 4.57
    >>> import numpy as np
    >>> arr=np.array([3.12, 3.43, 3.77, 4.15, 4.57],dtype=np.float32)
    >>> type(arr[-1])
    <type 'numpy.float32'>
    >>> arr[-1]
    4.57
    >>> type(4.57)
    <type 'float'>
    >>> arr[-1].item()
    4.570000171661377
    >>> type(arr[-1].item())
    <type 'float'>
    >>>
    详情参考 https://stackoverflow.com/questions/9452775/converting-numpy-dtypes-to-native-python-types
    mingyun
        18
    mingyun  
       2018-11-05 23:05:41 +08:00
    songdg
        19
    songdg  
    OP
       2018-11-07 08:29:55 +08:00
    @mario85 用你的方法解决了问题,谢谢。
    necomancer
        20
    necomancer  
       2018-11-11 02:23:40 +08:00   ❤️ 1
    一般 numpy 比较的时候用 np.isclose 或者 np.allclose

    In [1]: arr = np.array([3.12, 3.43, 3.77, 4.15, 4.57],dtype=np.float32)

    In [2]: np.isclose(arr[-1], 4.57)
    Out[2]: True

    浮点数一般不直接做相等,除非 dtype 也是一样的。python 里的小数一般是 np.float64

    In [4]: arr = np.array([3.12, 3.43, 3.77, 4.15, 4.57],dtype=np.float64)

    In [5]: arr[-1] == 4.57
    Out[5]: True

    我记得 numpy 官网文档里提过建议用 np.isclose()
    songdg
        21
    songdg  
    OP
       2018-11-18 00:00:37 +08:00
    @necomancer 谢谢又学到新东西。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1097 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 21ms · UTC 18:45 · PVG 02:45 · LAX 10:45 · JFK 13:45
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.