使用浮点数时Python函数的意外结果

时间:2013-10-25 08:00:25

标签: python python-2.7

我必须创建一个Python类,它将数字量更改为法语文本。 我找到了一个可以完成这项工作的类,但是当每个例子浮点数为50.4时,它返回“Cinquante units et 399

函数toText有3个参数:要转换的float,单位,decim。

def tradd(num):
    global t1,t2
    ch=''
    if num==0 :
        ch=''
    elif num<20:
        ch=t1[num]
    elif num>=20:
        if (num>=70 and num<=79)or(num>=90):
            z=int(num/10)-1
        else:
            z=int(num/10)
        ch=t2[z]
        num=num-z*10
        if (num==1 or num==11) and z<8:
            ch=ch+' et'
        if num>0:
            ch=ch+' '+tradd(num)
        else:
            ch=ch+tradd(num)
    return ch


def tradn(num):
    global t1,t2
    ch=''
    flagcent=False
    if num>=1000000000:
        z=int(num/1000000000)
        ch=ch+tradn(z)+' milliard'
        if z>1:
            ch=ch+'s'
        num=num-z*1000000000
    if num>=1000000:
        z=int(num/1000000)
        ch=ch+tradn(z)+' million'
        if z>1:
            ch=ch+'s'
        num=num-z*1000000
    if num>=1000:
        if num>=100000:
            z=int(num/100000)
            if z>1:
                ch=ch+' '+tradd(z)
            ch=ch+' cent'
            flagcent=True
            num=num-z*100000
            if int(num/1000)==0 and z>1:
                ch=ch+'s'
        if num>=1000:
            z=int(num/1000)
            if (z==1 and flagcent) or z>1:
                ch=ch+' '+tradd(z)
            num=num-z*1000
        ch=ch+' mille'
    if num>=100:
        z=int(num/100)
        if z>1:
            ch=ch+' '+tradd(z)
        ch=ch+" cent"
        num=num-z*100
        if num==0 and z>1:
           ch=ch+'s'
    if num>0:
        ch=ch+" "+tradd(num)
    return ch


def trad(nb, unite):
    global t1,t2
    x=int(nb)
    y=int((nb-x)*1000)
    t1=["","un","deux","trois","quatre","cinq","six","sept","huit","neuf","dix","onze","douze","treize","quatorze","quinze","seize","dix-sept","dix-huit","dix-neuf"]
    t2=["","dix","vingt","trente","quarante","cinquante","soixante","soixante-dix","quatre-vingt","quatre-vingt dix"]
    if x==0:
        ch="zéro"
    else:
        ch=tradn(abs(x))
    if x>1 or x<-1:
        if unite!='':
            ch=ch+" "+unite+'s'
    else:
        ch=ch+" "+unite

    if x<0:
        ch="moins "+ch
    return ch

def toText(nb, unite="Dinar", decim="millime"):
    x=int(nb)
    y=(nb-x)*1000
    z=int(y)

    if  y > 1:
        text_amount=trad(x,unite)+" et "+str(z)+" "+decim+"s"
    elif y==1:
        text_amount=trad(x,unite)+" et "+str(z)+" "+decim
    elif y==0:
        text_amount=trad(x,unite)+" et zéro "+decim
    return text_amount




if __name__=='__main__':

    print toText(45.4,"dinar")

5 个答案:

答案 0 :(得分:2)

这只是每个人最喜欢的老朋友,浮点错误。

行:

x=int(nb)
y=int((nb-x)*1000)

结束:

(50.4-50)*1000 
# try this in your interpreter: 399.9999999999986

50.4无法用(53位)浮点数精确表示。您需要通过字符串格式化或舍入来相应调整。

答案 1 :(得分:2)

而不是z=int(y)尝试使用z=int(round(y,0))。这应该围绕你的399.99 ......到400。

>>> int(round((50.4-50.)*1000, 0))
400

答案 2 :(得分:2)

正如其他答案已经说过的那样,您无法使用float准确表示完全浮点数,因此如您所见打印50.4

你可以尝试使用包decimal:它能够准确地表示浮点数,你可能能够得到预期的结果

答案 3 :(得分:1)

问题在于50.4无法准确表示:

>>> print('{:.47f}'.format(50.4))
50.39999999999999857891452847979962825775146484375

错误在toText函数的定义中。这些行:

x=int(nb)
y=(nb-x)*1000
z=int(y)

将导致z成为399而不是400

如果你想提供更多“用户友好”的输出,你必须手动检查小数部分是否“奇怪”并相应地舍入。

答案 4 :(得分:1)

您可以使用round

def toText(nb, unite="Dinar", decim="millime"):
    x=int(nb)
    y=(nb-x)*1000
    z=int(round(y))