当前位置: 首页 > 面试题库 >

用python很好地表示浮点数

许黎明
2023-03-14
问题内容

我想将浮点数表示为四舍五入到一定位数的字符串,并且从不使用指数格式。本质上,我想显示任何浮点数并确保它“看起来不错”。

这个问题有几个部分:

  • 我需要能够指定有效位数。
  • 有效位数必须是可变的,而字符串格式化运算符不能做到这一点。[编辑]我已经改正了;字符串格式化操作符可以做到这一点。
  • 我需要将其四舍五入到一个人期望的方式,而不是像1.999999999999

我想出了一种方法来完成此任务,尽管它看起来像是一轮工作,而且还不是很完美。(最大精度为15个有效数字。)

>>> def f(number, sigfig):
    return ("%.15f" % (round(number, int(-1 * floor(log10(number)) + (sigfig - 1))))).rstrip("0").rstrip(".")

>>> print f(0.1, 1)
0.1
>>> print f(0.0000000000368568, 2)
0.000000000037
>>> print f(756867, 3)
757000

有一个更好的方法吗?为什么Python对此没有内置函数?


问题答案:

似乎没有内置的字符串格式化技巧,它使您可以(1)打印浮点数的第一个有效数字出现在小数点后15位,以及(2)不使用科学计数法。这样就可以进行手动字符串操作了。

在下面,我使用该decimal模块从浮点数中提取十进制数字。该float_to_decimal函数用于将浮点数转换为Decimal对象。明显的方法decimal.Decimal(str(f))是错误的,因为str(f)会丢失大量数字。

float_to_decimal从十进制模块的文档中删除。

一旦将十进制数字作为整数元组获得,下面的代码就可以完成以下工作:截取所需数量的有效数字,如果需要,将其四舍五入,将数字连成字符串,在符号上加钉,然后将小数点,并在适当的时候向左或向右零。

在底部,您会发现一些我用来测试该f功能的案例。

import decimal

def float_to_decimal(f):
    # http://docs.python.org/library/decimal.html#decimal-faq
    "Convert a floating point number to a Decimal with no loss of information"
    n, d = f.as_integer_ratio()
    numerator, denominator = decimal.Decimal(n), decimal.Decimal(d)
    ctx = decimal.Context(prec=60)
    result = ctx.divide(numerator, denominator)
    while ctx.flags[decimal.Inexact]:
        ctx.flags[decimal.Inexact] = False
        ctx.prec *= 2
        result = ctx.divide(numerator, denominator)
    return result

def f(number, sigfig):
    # http://stackoverflow.com/questions/2663612/nicely-representing-a-floating-point-number-in-python/2663623#2663623
    assert(sigfig>0)
    try:
        d=decimal.Decimal(number)
    except TypeError:
        d=float_to_decimal(float(number))
    sign,digits,exponent=d.as_tuple()
    if len(digits) < sigfig:
        digits = list(digits)
        digits.extend([0] * (sigfig - len(digits)))    
    shift=d.adjusted()
    result=int(''.join(map(str,digits[:sigfig])))
    # Round the result
    if len(digits)>sigfig and digits[sigfig]>=5: result+=1
    result=list(str(result))
    # Rounding can change the length of result
    # If so, adjust shift
    shift+=len(result)-sigfig
    # reset len of result to sigfig
    result=result[:sigfig]
    if shift >= sigfig-1:
        # Tack more zeros on the end
        result+=['0']*(shift-sigfig+1)
    elif 0<=shift:
        # Place the decimal point in between digits
        result.insert(shift+1,'.')
    else:
        # Tack zeros on the front
        assert(shift<0)
        result=['0.']+['0']*(-shift-1)+result
    if sign:
        result.insert(0,'-')
    return ''.join(result)

if __name__=='__main__':
    tests=[
        (0.1, 1, '0.1'),
        (0.0000000000368568, 2,'0.000000000037'),           
        (0.00000000000000000000368568, 2,'0.0000000000000000000037'),
        (756867, 3, '757000'),
        (-756867, 3, '-757000'),
        (-756867, 1, '-800000'),
        (0.0999999999999,1,'0.1'),
        (0.00999999999999,1,'0.01'),
        (0.00999999999999,2,'0.010'),
        (0.0099,2,'0.0099'),         
        (1.999999999999,1,'2'),
        (1.999999999999,2,'2.0'),           
        (34500000000000000000000, 17, '34500000000000000000000'),
        ('34500000000000000000000', 17, '34500000000000000000000'),  
        (756867, 7, '756867.0'),
        ]

    for number,sigfig,answer in tests:
        try:
            result=f(number,sigfig)
            assert(result==answer)
            print(result)
        except AssertionError:
            print('Error',number,sigfig,result,answer)


 类似资料:
  • 问题内容: 您好,我在Python中使用字典来存储一些城市及其人口,例如: 现在,如果我使用命令,则会得到结果: 相反,如果我使用命令,则会得到的初始输入。 我对你的问题是如何的和变成和分别?所有这些信息是如何产生的?以及为什么将其存储在此处,因为我的初始输入表明我至少在我所知的范围内不需要这些额外的信息。 问题答案: 在Python 3.1中已对此进行了更改。在新页面上: Python现在使用D

  • 浮点是C语言中定义的实现,因此没有任何保证。 我们的代码需要可移植,我们正在讨论是否可以在协议中使用IEEE754浮动。出于性能考虑,如果我们在发送或接收数据时不必在定点格式之间来回转换,那就太好了。 虽然我知道平台和架构之间在或的大小上可能存在差异。但我似乎找不到任何关于和的具体信息。 到目前为止,我发现在big endian平台上字节顺序可能会颠倒。虽然有些平台不支持浮点运算,但包含和的代码甚

  • 我有一个要在GoogleMap上显示为标记的LatLng点列表。我目前正在通过以下方式计算适合我所有点的相机视图: > 首先,我用我所有的点计算一个LatLngBound。 然后我使用适当的方法: 更新提供了对我所有观点的良好视图,并添加了一些很好的填充。 问题 我想为paddingTop、paddingBottom、padding左和paddingright应用不同的值。也就是说,我两边都没有,

  • 问题内容: 我很困惑为什么在这种情况下python为什么要添加一些额外的十进制数,请帮助解释 问题答案: 浮点数是一个近似值,它们不能精确存储十进制数。因为它们试图仅用64位表示很大范围的数字,所以它们必须在某种程度上近似。 意识到这一点非常重要,因为它会导致一些怪异的副作用。例如,你可能会非常合理认为,十批的总和会。尽管这似乎合乎逻辑,但在浮点数方面也是错误的: 您可能会认为。浮点世界再次不同意

  • 与十进制相似,二进制数也可以表示浮点。现在我读到它可以有类似的浮动 :,:,:...等等。但是,例如,0.1(十进制)如何用二进制表示? 另外,给定一个十进制浮点数,如何将其转换为十进制等价物(假设它不是那么简单)。 编辑:所以我知道更好的问题应该是;如何将十进制浮点转换为二进制?现在我知道我们乘以小数部分,直到它变成零。现在很有可能两个浮点可以有相同的表示,对吗?

  • 问题内容: 谁能解释模运算符在Python中如何工作?我不明白为什么。 问题答案: 其实,这是不正确的3.5 % 0.1是0.1。你可以很容易地测试一下: 实际上,在大多数系统上是。但是,在某些版本的Python上是: 现在,你可能想知道为什么是而不是。这是由于通常的浮点舍入问题。如果你还没有阅读每位计算机科学家应该知道的有关浮点运算的知识,那么你应该-至少是对此问题的简要概述。 还需要注意的是3