python 浮点除法
2024-10-21 22:52:40
昨天晚上久违地去打了次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
的填补以方便运算。
至于这个算法具体的优化过程不得而知,想来与现在的结论应该是大相径庭吧,只能留待日后有机会再研究了。
最新文章
- docker 数据卷 权限
- Java集合系列:-----------08HashMap的底层实现
- 深入理解Java虚拟机之读书笔记一 自动内存管理机制
- CC150 - 11.6
- TCP数据流稳定性--TCP分片,重组及乱序
- Python sequence (序列)
- XtraBackup原理3
- JS常用的标准函数
- C#设置richtextbox某一段文本颜色
- DevOps之归纳总结
- Lucene入门案例一
- C#使用Spire.Doc Word for .Net读写Word
- MySQL经典查询场景
- Js调用asp.net后台代码
- 位运算符&;与、或|、异或^
- 机器学习笔记(6):多类逻辑回归-使用gluon
- Android中两个Activity之间简单通信
- A Theoretical Analysis of Feature Pooling in Visual Recognition
- .NET编译过程
- 20155231 cho2 课下作业
热门文章
- SpringCloud基本认知
- centos/rockylinux/proxmoxve重置root密码 以及 在#bash 下 重启
- spring boot2 jpa分页查询百万级数据内存泄漏
- tensorboard 2.0可视化 —浏览器中输入http://ip:6006 - 无法访问此网站——有效解决
- 【OBS Studio】使用 VLC 视频源播放视频报错:Unhandled exception: c0000005
- Andorid 悬浮窗的适配指北
- nginx配置文件过大导致起不来
- Ingress限流
- linux 查看端口号是否对外开放,并开放端口号
- cc1