Python3.x舍入行为

Python3.x舍入行为,python,python-3.x,rounding,Python,Python 3.x,Rounding,我刚刚重读,上面写着: round()函数的舍入策略和返回类型已更改。 精确的中间情况现在取而代之的是四舍五入到最接近的偶数结果 从零开始。(例如,round(2.5)现在返回2,而不是1。) (三) 及 文件包括: 对于支持round()的内置类型,值舍入为 幂减n的最接近10的倍数;如果两个倍数是 同样接近,舍入是朝着均匀的选择进行的 因此,在v2.7.3下: In [85]: round(2.5) Out[85]: 3.0 In [86]: round(3.5) Out[86]: 4.0

我刚刚重读,上面写着:

round()函数的舍入策略和返回类型已更改。 精确的中间情况现在取而代之的是四舍五入到最接近的偶数结果 从零开始。(例如,round(2.5)现在返回2,而不是1。) (三)

及 文件包括:

对于支持round()的内置类型,值舍入为 幂减n的最接近10的倍数;如果两个倍数是 同样接近,舍入是朝着均匀的选择进行的

因此,在v2.7.3下:

In [85]: round(2.5)
Out[85]: 3.0

In [86]: round(3.5)
Out[86]: 4.0
In [32]: round(2.5)
Out[32]: 2

In [33]: round(3.5)
Out[33]: 4
如我所料。但是,现在在v3.2.3下:

In [85]: round(2.5)
Out[85]: 3.0

In [86]: round(3.5)
Out[86]: 4.0
In [32]: round(2.5)
Out[32]: 2

In [33]: round(3.5)
Out[33]: 4
这似乎违反直觉,与我的理解相反 四舍五入(必然会绊倒人们)。英语不是我的母语,而是英语 在我读到这篇文章之前,我以为我知道舍入是什么意思 在引入v3时,一定有一些关于 但我在搜索中找不到一个好的理由

  • 有人知道为什么会变成这样吗
  • 有没有其他主流编程语言(例如,C、C++、java、perl、…)这样做(对我不一致)舍入? 我错过了什么

    更新:@Li aungYip关于“银行取整”的评论给了我正确的搜索词/关键字,我发现了这样一个问题:,所以我会仔细阅读。

    Python 3的方式(称为“”或“银行取整”)被认为是这些天的标准取整方法,尽管有些语言实现还没有出现在总线上

    简单的“”技术会导致略微偏向较高的数字。对于大量的计算,这可能非常重要。Python 3.0方法消除了这个问题

    常用的四舍五入方法不止一种。IEEE 754是浮点数学的国际标准,定义了(Python 3.0使用的是默认值)。和


    这种行为并不像应有的那样广为人知。如果我没记错的话,AppleScript是这种舍入方法的早期采用者。提供了多个选项,但在IEEE 754中,向偶数方向舍入是默认值。显然,执行
    舍入
    命令的工程师受够了“让它像我在学校学到的那样工作”的所有要求,他只执行了:
    学校教的2.5舍入
    是一个有效的AppleScript命令。:-)

    您可以使用以下命令控制Py3000中的舍入:


    我最近也遇到了这个问题。因此,我开发了一个python 3模块,该模块有两个函数trueround()和trueround_precision(),它们解决了这个问题,并给出了小学时使用的相同舍入行为(不是银行家舍入)。这是模块。只需保存代码并将其复制或导入即可。注意:trueround_precision模块可以根据需要根据十进制模块中的ROUND_天花板、ROUND_DOWN、ROUND_地板、ROUND_HALF_DOWN、ROUND_HALF_偶数、ROUND_HALF_UP、ROUND_UP和ROUND_05; UP标志更改舍入行为(有关更多信息,请参阅该模块文档)。对于下面的函数,请参阅docstring或使用帮助(trueround)和帮助(trueround_precision)(如果复制到解释器中)以获取进一步的文档

    #! /usr/bin/env python3
    # -*- coding: utf-8 -*-
    
    def trueround(number, places=0):
        '''
        trueround(number, places)
    
        example:
    
            >>> trueround(2.55, 1) == 2.6
            True
    
        uses standard functions with no import to give "normal" behavior to 
        rounding so that trueround(2.5) == 3, trueround(3.5) == 4, 
        trueround(4.5) == 5, etc. Use with caution, however. This still has 
        the same problem with floating point math. The return object will 
        be type int if places=0 or a float if places=>1.
    
        number is the floating point number needed rounding
    
        places is the number of decimal places to round to with '0' as the
            default which will actually return our interger. Otherwise, a
            floating point will be returned to the given decimal place.
    
        Note:   Use trueround_precision() if true precision with
                floats is needed
    
        GPL 2.0
        copywrite by Narnie Harshoe <signupnarnie@gmail.com>
        '''
        place = 10**(places)
        rounded = (int(number*place + 0.5if number>=0 else -0.5))/place
        if rounded == int(rounded):
            rounded = int(rounded)
        return rounded
    
    def trueround_precision(number, places=0, rounding=None):
        '''
        trueround_precision(number, places, rounding=ROUND_HALF_UP)
    
        Uses true precision for floating numbers using the 'decimal' module in
        python and assumes the module has already been imported before calling
        this function. The return object is of type Decimal.
    
        All rounding options are available from the decimal module including 
        ROUND_CEILING, ROUND_DOWN, ROUND_FLOOR, ROUND_HALF_DOWN, ROUND_HALF_EVEN, 
        ROUND_HALF_UP, ROUND_UP, and ROUND_05UP.
    
        examples:
    
            >>> trueround(2.5, 0) == Decimal('3')
            True
            >>> trueround(2.5, 0, ROUND_DOWN) == Decimal('2')
            True
    
        number is a floating point number or a string type containing a number on 
            on which to be acted.
    
        places is the number of decimal places to round to with '0' as the default.
    
        Note:   if type float is passed as the first argument to the function, it
                will first be converted to a str type for correct rounding.
    
        GPL 2.0
        copywrite by Narnie Harshoe <signupnarnie@gmail.com>
        '''
        from decimal import Decimal as dec
        from decimal import ROUND_HALF_UP
        from decimal import ROUND_CEILING
        from decimal import ROUND_DOWN
        from decimal import ROUND_FLOOR
        from decimal import ROUND_HALF_DOWN
        from decimal import ROUND_HALF_EVEN
        from decimal import ROUND_UP
        from decimal import ROUND_05UP
    
        if type(number) == type(float()):
            number = str(number)
        if rounding == None:
            rounding = ROUND_HALF_UP
        place = '1.'
        for i in range(places):
            place = ''.join([place, '0'])
        return dec(number).quantize(dec(place), rounding=rounding)
    
    #/usr/bin/env蟒蛇3
    #-*-编码:utf-8-*-
    def trueround(数量、位置=0):
    '''
    trueround(数量、位置)
    例子:
    >>>trueround(2.55,1)==2.6
    真的
    使用无导入的标准函数为
    四舍五入,使trueround(2.5)=3,trueround(3.5)=4,
    trueround(4.5)=5等。但是,请谨慎使用。这一点仍然存在
    浮点数学也有同样的问题。返回对象将
    如果places=0,则输入int;如果places=>1,则输入float。
    number是四舍五入所需的浮点数
    places是以“0”为整数舍入的小数位数
    默认值,它将实际返回我们的整数。否则,一个
    浮点将返回到给定的小数位。
    注意:如果精度为真,则使用trueround_precision()
    需要浮动
    GPL2.0
    纳尼·哈肖的文案
    '''
    地点=10**(地点)
    四舍五入=(整数(数字*位置+0.5,如果数字>=0,则为-0.5))/place
    如果四舍五入==int(四舍五入):
    四舍五入=整数(四舍五入)
    返回四舍五入
    def trueround_精度(数字、位置=0,舍入=无):
    '''
    trueround_精度(数字、位置、舍入=向上舍入一半)
    使用中的“十进制”模块对浮点数使用真精度
    python,并假定在调用之前已导入模块
    这个功能。返回对象的类型为Decimal。
    十进制模块提供了所有舍入选项,包括
    圆顶,圆顶,圆顶,圆顶,圆顶,圆顶,圆顶,圆顶,
    四舍五入,四舍五入,四舍五入。
    示例:
    >>>trueround(2.5,0)=十进制('3')
    真的
    >>>trueround(2.5,0,向下四舍五入)=十进制('2')
    真的
    数字是一个浮点数或一个字符串类型,其中包含一个数字
    采取行动的依据。
    places是要舍入的小数位数,默认值为“0”。
    注意:如果将类型float作为第一个参数传递给函数,则
    将首先转换为str类型以进行正确的舍入。
    GPL2.0
    纳尼·哈肖的文案
    '''
    从十进制输入十进制为dec
    从十进制输入到四舍五入
    从十进制输入四舍五入上限
    从十进制输入向下四舍五入
    从十进制输入四舍五入
    从十进制输入向下四舍五入
    从十进制输入四舍五入半偶数
    从十进制输入四舍五入
    从十进制输入四舍五入
    如果类型(数字)=类型(浮点()):
    编号=str(编号)
    如果舍入==无:
    四舍五入=四舍五入
    地点='1'
    因为我
    
    round2=lambda x,y=None: round(x+1e-15,y)
    
    assert round(0.5) == 0
    assert round(1.5) == 2
    assert round(2.5) == 2
    
    import decimal
    
    assert decimal.Decimal('0.5').to_integral_value() == 0
    assert decimal.Decimal('1.5').to_integral_value() == 2
    assert decimal.Decimal('2.5').to_integral_value() == 2
    
    decimal.getcontext().rounding = decimal.ROUND_HALF_UP
    
    assert decimal.Decimal('0.5').to_integral_value() == 1
    assert decimal.Decimal('1.5').to_integral_value() == 2
    assert decimal.Decimal('2.5').to_integral_value() == 3
    
    i = int(decimal.Decimal('2.5').to_integral_value()) # to get an int
    assert i == 3
    assert type(i) is int
    
    in: Decimal(75.29 / 2).quantize(Decimal('0.01'), rounding=ROUND_HALF_UP)
    in: round(75.29 / 2, 2)
    out: 37.65 GOOD
    
    in: Decimal(85.55 / 2).quantize(Decimal('0.01'), rounding=ROUND_HALF_UP)
    in: round(85.55 / 2, 2)
    out: 42.77 BAD
    
    in: round(75.29 / 2 + 0.00001, 2)
    out: 37.65 GOOD
    in: round(85.55 / 2 + 0.00001, 2)
    out: 42.78 GOOD
    
    ['{} => {}'.format(x+0.5, round(x+0.5)) for x in range(10)]
    
    ['0.5 => 0', '1.5 => 2', '2.5 => 2', '3.5 => 4', '4.5 => 4', '5.5 => 6', '6.5 => 6', '7.5 => 8', '8.5 => 8', '9.5 => 10']
    
    import math
    def my_round(i):
      f = math.floor(i)
      return f if i - f < 0.5 else f+1
    
    ['{} => {}'.format(x + 0.5, my_round(x+0.5)) for x in range(10)]
    ['0.5 => 1', '1.5 => 2', '2.5 => 3', '3.5 => 4', '4.5 => 5', '5.5 => 6', '6.5 => 7', '7.5 => 8', '8.5 => 9', '9.5 => 10']
    
    def roundup(input):   
       demo = input  if str(input)[-1] != "5" else str(input).replace("5","6")
       place = len(demo.split(".")[1])-1
       return(round(float(demo),place))
    
    >>> x = roundup(2.5)
    >>> x
    3.0  
    >>> x = roundup(2.05)
    >>> x
    2.1 
    >>> x = roundup(2.005)
    >>> x
    2.01 
    
    n = 0.1 
    round(2.5 + n)
    
    >>> round(2 + n)
    >>> 2
    
    >>> round(2.1 + n)
    >>> 2
    
    >>> round(2.2 + n)
    >>> 2
    
    >>> round(2.3 + n)
    >>> 2
    
    >>> round(2.4 + n)
    >>> 2
    
    >>> round(2.5 + n)
    >>> 3
    
    >>> round(2.6 + n)
    >>> 3
    
    >>> round(2.7 + n)
    >>> 3
    
    >>> round(2.8 + n)
    >>> 3
    
    >>> round(2.9 + n)
    >>> 3
    
    >>> round(3 + n)
    >>> 3
    
    import math
    print(math.ceil(2.5))
    > 3