匹配数字与另一个数字的最后n位数

时间:2016-03-17 23:31:55

标签: python python-2.7

我有一对数字列表,例如:

1.45 4
0.73 17
0.201 18
509 24
0.55 21

这里第二个数字是第一个值的误差。在文献中,为了方便起见,你会看到它写成1.45(4),它应该真的是1.45 +/- 0.04。我很乐意将第二个数字转换为“真实”数字。错误,即我想将上面的列表转换为:

1.45 0.04
0.73 0.17
0.201 0.018
509 24
0.55 0.21

到目前为止,我最大的成功是使用以下功能:

def gMatchError(fValue, fError):
  sExponent = -10
  while True:
    fFindDecimal = fValue*math.pow(10, sExponent)
    if fFindDecimal.is_integer():
      return fError / math.pow(10, sExponent)
    sExponent += 1  

迭代地将第一个值乘以10 ^ i,直到它是一个整数。当它是整数时,则可以将误差除以10 ^ i。

这适用于上面列出的所有数字,除了最后一个并返回0.021。我知道这是因为浮点数存储在内存中的方式的性质,即使用。 repr ()我可以看到它检查55.000000001是否是一个整数,当然,它不是。

我也尝试用

来检查
if int(fFindDecimal) == int(fFindDecimal+0.9) and int(fFindDecimal) != 0:
  return (as above)

但是当中间的0为0时,这会失败,例如在0.201的情况下。

是否有任何替代方案适用于所有情况?提前谢谢。

5 个答案:

答案 0 :(得分:1)

如您所知,十进制值通常不会完全存储为二进制浮点数。相反,我建议你在阅读时使用数字的文本版本。也许是这样的:

measure, error = input_line.split()
whole, frac = measure.split('.')
precision = len(frac)
error = float(error) / 10**precision

print measure, error

我给你留下了几个不优雅的要点:

  • 我悄悄地将错误从字符串转换为浮动...
  • ...而度量仍然是一个字符串
  • 我忽略了整数度量的情况; 整个,frac = 语句会出错。

但是,我希望这会让你很好地解决问题。

答案 1 :(得分:0)

我会使用decimal模块:

from decimal import Decimal
def gMatchError(fValue, fError):
    exp = Decimal(fValue.as_tuple().exponent)
    return Decimal("10")**exp * fError

这也处理数字,如0.500

答案 2 :(得分:0)

我会用

def get_precision(num, precision):
    if num % 1:
        precision = precision * 10 ** -len(str(num).split('.')[1])
    return precision

给予

>>> get_precision(123.456,16)
0.016
>>> get_precision(123,16)
16
>>> get_precision(12231233.1,16)
1.6

一些解释:

  • 如果数字不是整数,则num % 1条件返回true,因此包含小数点
  • len(str(num).split('.')[1])为您提供小数点后的位数

答案 3 :(得分:0)

a = ['1.45 4',
'0.73 17',
'0.201 18',
'509 24',
'0.55 21']

for i,val in enumerate(a):
    temp = val.split(' ')
    if temp[0].find('.') != -1:
        dec_place = temp[0].find('.')
        tenth_power = temp[0][dec_place+1:]
        # divide the second number by 10 to the power of number of digits after the decimal
        # in the first number
        temp[1] = str(float(temp[1])/(10**(len(tenth_power))))
    # separate first and second value by space
    temp[0] +=' '
    # combine first and second value to a single string
    a[i] = ''.join(temp)

print(a)

输出:

['1.45 0.04', '0.73 0.17', '0.201 0.018', '509 24', '0.55 0.21']

答案 4 :(得分:0)

我将从第一个数字的字符串表示中确定精度(例如,您无法区分10.0与浮点变量的10.00)。使用正则表达式,您可以使用组获取不同的元素。

VALUES = (
  '1.45 4',
  '0.73 17',
  '0.201 18',
  '509 24',
  '0.55 21',
)

import re
REGEX = re.compile( r"(\d+(\.(\d+))?)\s(\d+)" )

for v in VALUES:
  m = REGEX.match(v)
  if m.group(3) is not None:
    nd = len(m.group(3))   # nb of decimals in first number          
    d = 0.1 ** nd
    n2 = float(m.group(4)) * d
    print "{n1} {n2:{nd}}".format(n1=m.group(1), n2=n2, nd=nd)
  else:
    print v

打印

1.45 0.04
0.73 0.17
0.201 0.018
509 24
0.55 0.21