您的位置:首页 > 编程语言 > Python开发

Python练习(3):浮点数的比较和二分法

2016-03-02 15:07 501 查看

[0]浮点数在python里面是二进制的形式存储的,比如0.1,就不能找到一个有限的二进制形式来表示它,所以python会对0.1的二进制表示进行截断,造成误差,注意,误差是可以累积的!

[1]python中的print会对浮点数在10多位后进行截断,0.999999999999999999999。。。999会被输出1.这点在调试时候会造成疑惑.

[2]对浮点数进行比较的时候需要采取误差比较的办法

练习:自己写一个实数n次根的程序.

版本1:

import math
def sqroot(x,n,ellpison):
assert(x>0)##assume x is positive
ctr = 0
[low,high] = [x,1] if x<1 else [0,x]#get the approriate range for [low,high]
guess = (low + high)/2
while(ctr < 100 and abs(x - guess**n) > ellpison):
if(guess**n > x):
high = guess
else:
low = guess
ctr += 1
guess = (low + high)/2
if(ctr==100):
print('do not find the precisely enough answer')
else:
if (isinstance(x,int)and round(guess)**n == x):
guess = round(guess)
print('the approximation of the ans is :', guess)
sqroot(1,2,0.0001)


这个程序有以下要点:

[1]注意随着x的不同就要判断二分法的区间

[2]注意一些完美平方数我们应该进行检验,比如25,81等,这样可以保证获得完美平方数的精确值.

[3]ctr用来保证精度不能过于大,否则会导致程序一直循环.

[4]aseert用来保证n为偶数时必须x必须是非负数

但是这个版本还是有很多缺陷,(1)比如没有考虑到x为0的情况;(1)当x太小,ellipson的精度就会不够,比如处理1e-6的情况,我们就必须加大ellipison的精度,这样就增加的操作难度;只能处理x是正数的情况针对这些问题我做出了版本二的修改

import math
def sqroot(x,n,ellpison):
if(n%2==0):
assert(x>0)##assume x is positive
ctr = 0
ispositive = 1 if x >=0 else -1
x = abs(x)
[x,ismall] = [1/x,True] if x<1 else [x,False]
#[low,high] = [x,1] if x<1 else [0,x]
[low,high] = [0,x]
guess = (low + high)/2
while(ctr < 100 and abs(x - guess**n) > ellpison):
if(guess**n > x):
high = guess
else:
low = guess
ctr += 1
guess = (low + high)/2
if(ctr==100):
print('do not find the precisely enough answer')
else:
if (isinstance(x,int)and round(guess)**n == x):
guess = round(guess)
guess *= ispositive
print('the approximation of the ans is :', 1/guess if ismall else guess)
sqroot(-1e-6,3,0.0001)


[1]假如x<1,那么就取倒数进行计算,这样x就大于1,从而将问题转换到大于1的情况,避免了精度不够。

[2]同时提前处理了x的正负情况,在最后再将结果的正负号添加回来(利用了变量ispositive)

[3]处理了x==0的情况

。。。。。。。

当然,这个版本还有一些缺陷,我想到的有没有处理n是一个负数的情况,n是负数相当于对x取倒数,这些都不是很麻烦,但是可能还有一些因隐藏的bug,有发现的可以告知一下.

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: