Gigi233 发表于 2023-2-7 23:04:49

python作业018 为什么我这样是不对的呀

编写一个程序,求解 100~999 之间的所有水仙花数。

for i in range(100,1000):
    a=i//100
    b=i//10-a*10
    c=(i/10-i//10)*10
    if a**3+b**3+c**3==i:
      print(i)

为什么这样只能得出一个答案370?
该怎么改呢?

ba21 发表于 2023-2-7 23:19:32

这么分解

a=i//100       分解出百位
b=i//10%10分解出十位
c=i%10    分解出个位

isdkz 发表于 2023-2-7 23:19:47

本帖最后由 isdkz 于 2023-2-7 23:24 编辑

小数的运算是会存在溢出的问题的

问题就出在 c
>>> i = 567
>>> a=i//100
>>> b=i//10-a*10
>>> c=(i/10-i//10)*10
>>> a
5
>>> b
6
>>> c
7.000000000000028
>>> 56.7 - 56
0.7000000000000028

把 c 换成别的就好,比如 i % 10 ,不要涉及到小数的运算,或者小数的运算用 decimal

for i in range(100,1000):
    a=i//100
    b=i//10-a*10
    c=i % 10
    if a**3+b**3+c**3==i:
      print(i)



from decimal import Decimal
for i in range(100,1000):
    a=i//100
    b=i//10-a*10
    c=(Decimal(str(i/10))-i//10)*10
    if a**3+b**3+c**3==i:
      print(i)

ZIXINGps 发表于 2023-2-7 23:48:48

bug:
c的赋值里出了问题,你自己可以试着单独打印一下c,会发现只有0和5结尾的数才会得到正常的c,其他的会得到像1.9999999999999993(实际上是2)这样不准确的答案
而100-999中的水仙花数只有370是0结尾的
原因在第8课数字类型上的浮点数部分,浮点数的加减计算不准确,这个是Python本身的特性

修改:
可以用第8课提到的decimal模块或者干脆直接重写避免浮点数相减的情况

比如:
c = i - a * 100 - b * 10
原数-百位-十位
直接换一种不涉及浮点数的写法,从根源上解决问题{:10_282:}

decimal模块的做法:
c = (decimal.Decimal(str(i/10))-decimal.Decimal(str(i//10)))*10
decimal.Decimal()可以通过传入字符串的形式得出精确的浮点数,这一点在第8课讲过
把浮点数用Decimal变精确就不会出错了

把c的赋值改完之后就能得到正确的答案了
希望能有所帮助XD

Gigi233 发表于 2023-2-8 00:08:01

ZIXINGps 发表于 2023-2-7 23:48
bug:
c的赋值里出了问题,你自己可以试着单独打印一下c,会发现只有0和5结尾的数才会得到正常的c,其他的 ...

明白了,太感谢你了!
页: [1]
查看完整版本: python作业018 为什么我这样是不对的呀