我想计算一些浮点数的平均总和。但我得到了奇怪的结果

I want to calculate the average sum of some floats. But I got strange results

提问人:SteviaDaddy 提问时间:7/26/2022 最后编辑:robniSteviaDaddy 更新时间:7/28/2022 访问量:231

问:

因此,我要求用户提供一些带有循环的数字输入。 之后,对输入进行处理,数学结果与使用计算器完成的实际数学运算略有不同。 它是否将 0 中断值作为输入并以某种方式搞砸了我的平均值?

values = []
while True:
  m = float(input("Number of shares?, 0 for Exit: "))
  n = float(input("Total price of purchase?, 0 for Exit:"))
  if m == 0:
      break
  if n == 0:
      break
  values.append(m)
  sum = n/m

print(sum)
python 用户输入 浮动精度

评论


答:

-1赞 robni 7/27/2022 #1

第一件事:

我假设,你想保存一笔交易的奖金(股票*价格),把这个数字放在数组值中,然后你想从你的数组中计算平均数字。你的代码不会这样做。

sum = n/m # calculates **only** n / m and saves it **only** in the variable sum.
# You overwrite sum every loop.

试试这个:

values = []
while True:
  m = float(input("Number of shares?, 0 for Exit: ")) # Caution! It's not a good idea to use a float here!
  n = float(input("Total price of purchase?, 0 for Exit:")) # Caution! It's not a good idea to use a float here!
  if m == 0:
      break
  if n == 0:
      break
  values.append(n * m) # append the price of the transaction into values

print( sum(values) / len(values) ) # gives you the average prize per transaction

谨慎!示例:给定 m = 1.1 和 n = 1.1,并且只有一个事务。输出为 1.21000000000000002!

为什么?

简短的回答:

避免使用浮点数。请改用双打。如果您正在处理货币,永远不要使用浮点数/双倍数。在 python 中,如果您需要更高的精度,您可以使用十进制

长答案:

您正在尝试使用浮点数进行计算。 大多数现代编程语言使用标准 IEEE_754-1985 来存储浮点数。在 IEEE-754 中,某些数字无法精确表示为浮点数。因为它是二进制结构。例如,数字 0.1

1.0 作为浮点数是:

0 01111111 00000000000000000000000

第一位代表符号。如果它为,则该数字为正数。如果是,则为负数。

-1.0:

1 01111111 00000000000000000000000

符号位后面的 8 位是指数。 指数位后面的 23 位是尾数。

如果我们在尾数中最重要的部分有一个会发生什么

0 01111111 10000000000000000000000

我们现在有一个 1.0 + 2^-1。那是 1.5。

什么是:

0 01111111 01000000000000000000000

我们现在有一个 1.0 + 2^-2。那是 1.25。

1.1 是:

0 01111111 00011001100110011001101

1.0 + 2^-4 + 2^-5 + 2^-8 + 2^-9 + 2^-12 + 2^-13 + 2^-16 + 2^-17 +2^-20 + 2^-21 + 2^-23

那是:1.10000002384185791015625 单精度约为 1.10000000。

可以使用双精度。双精度包含 64 位。1 表示符号,11 表示指数,52 位表示尾数。但 0.1 仍然只是一个近似数字,而不是确切的 0.1。

溶液

from decimal import Decimal

values = []
while True:
  m = Decimal(input("Number of shares?, 0 for Exit: "))
  n = Decimal(input("Total price of purchase?, 0 for Exit:"))
  if m == 0:
      break
  if n == 0:
      break
  values.append(n * m)

average = sum(values) / len(values) 
print(average) 

评论

0赞 SteviaDaddy 7/28/2022
似乎两位数而不是浮点数不是问题。这是因为我正在编写多个数值输入,但仅对输入的最后 2 个输入进行平均计算。我编写的代码不会存储用户的所有输入,而只考虑最后 2 个。
1赞 robni 7/28/2022
事实上,您的代码存储了所有输入。但你不使用它。您正在计算 n / m 并将其相加。循环结束后:您正在打印最后一个总和