zoukankan      html  css  js  c++  java
  • python 浮点除法

    昨天晚上久违地去打了次div2

    一年没打,挂得很惨

    早上起来试着用python写一遍唯一写出来的a题

    然后发现了一个奇怪的现象

    代码如下(为了方便观察已经改过了,不是解题的代码)

    import sys
    x=1
    y=100000000
    k=100000000
    a=k*y+k-1
    ans=a/1
    print(sys.maxsize)
    print(int(a))
    print(int(ans))

    结果如下:

    9223372036854775807
    10000000099999999
    10000000100000000

    输出的第一行是int的最大值,是为了验证异常不是由于溢出导致的。

    看到第二个输出,一个算是比较大的数字,第三个输出应当是其除以1的结果。

    用小学生的脑子想一想,任意一个数字除以1结果应当不变吧。

    但输出告诉我们,我不仅变,我还给你刚好+1。

    但如果在这里使用整除的话,第二和第三个结果是一致的。

    那么问题大约出在python的浮点数除法的算法上了。

    如果将除数改为2,可以看到第三个输出变为

    5000000050000000

    也就是说,在除法过程中依然出现了+1现象。

    如果减小量级呢?

    import sys
    x=1
    y=100000000
    k=100000000
    a=k+k-1
    ans=a/1print(sys.maxsize)
    print(int(a))
    print(int(ans))

    结果如下:

    9223372036854775807
    199999999
    199999999

    可以看到,+1现象消失了。

    那么推测,+1现象的成因是在浮点运算中为了方便较大数字运算而引入的一个一般情况下可以忽略的填补量。

    那么引入这个+1的临界范围是什么?

    使用while循环,粗略地探究一下:

    import sys
    x=1
    y=100000000
    k=100000000
    a=k+k-1
    ans=a/1;
    while a==ans:
        print(int(a))
        a*=10
        ans=a/1print(sys.maxsize)
    print(int(a))
    print(int(ans))

    结果是:

    199999999
    1999999990
    19999999900
    199999999000
    1999999990000
    19999999900000
    199999999000000
    1999999990000000
    19999999900000000
    199999999000000000
    1999999990000000000
    9223372036854775807
    19999999900000000000
    19999999900000002048

    不对劲啊,为什么是在比int范围还有大的时候才跳出循环,明明之前产生偏差的数值比范围要小。

    猜测,这个偏差的产生条件不只是数字的位数,还有其他的条件

    观察最开始的那个数据,以及1的特殊性,猜测这个+1的偏差可能和数据的末尾9的个数有关

    那么选取一个较小的9结尾的数字开始循环

    import sys
    a=199999
    ans=a/1
    while a==ans:
    print(a)
    a=a*10+9
    ans=a/1
    print(sys.maxsize)
    print(int(a))
    print(int(ans))

    结果是:

    199999
    1999999
    19999999
    199999999
    1999999999
    19999999999
    199999999999
    1999999999999
    19999999999999
    199999999999999
    1999999999999999
    9223372036854775807
    19999999999999999
    20000000000000000

    可以看到,位数与最初那个有偏差数据一样。

    实验到此结束,暂时的结论是,在被除数大到一定程度(暂定17位)且末尾有一定数量9时,在除法运算中会进行一个+1

    的填补以方便运算。

    至于这个算法具体的优化过程不得而知,想来与现在的结论应该是大相径庭吧,只能留待日后有机会再研究了。

  • 相关阅读:
    rs
    stm32f767 usoc3
    stm32f767 RTT 日志
    stm32f767 标准库 工程模板
    stm32f767 HAL 工程模板
    docker tab 补全 linux tab 补全
    docker anconda 依赖 下载 不了
    docker run 常用 指令
    linux scp 命令
    Dockerfile 常用参数说明
  • 原文地址:https://www.cnblogs.com/forever3329/p/13672917.html
Copyright © 2011-2022 走看看