私はちょうど読み直していました Python 3.0 の新機能には次のように書かれています:
Round()関数の丸め戦略と戻り値の型が変更されました。正確な中間ケースは、ゼロから離れるのではなく、最も近い偶数の結果に丸められるようになりました。 (たとえば、round(2.5)は3ではなく2を返すようになりました。)
および round のドキュメント:
Round()をサポートする組み込み型の場合、値は10のマイナスnに最も近い倍数に丸められます。 2つの倍数が等しく近い場合、偶数の選択に向かって丸めが行われます。
したがって、v2.7.3:
In [85]: round(2.5)
Out[85]: 3.0
In [86]: round(3.5)
Out[86]: 4.0
私が期待していたように。ただし、今v3.2.3の下:
In [32]: round(2.5)
Out[32]: 2
In [33]: round(3.5)
Out[33]: 4
これは直観に反するようで、私が丸めについて理解している(そして人をつまずかせることにバインドされている)ことに反しています。英語は私の母国語ではありませんが、これを読むまで、丸めが何を意味するのか知っていたと思いました:-/ v3が導入されたとき、これについての議論があったに違いないと思いますが、私の検索。
ここで何が欠けていますか?
更新:@ Li-aungYipのコメント「Banker's rounding」は、検索するための正しい検索語/キーワードを提供してくれました。このSO質問を見つけました: 。 ? なので、注意深く読んでいきます。
Python 3.0の方法は、最近では標準の丸め方法と見なされていますが、一部の言語実装はまだバス上にありません。
単純な「常に0.5に切り上げる」手法では、高い数値に向かってわずかに偏りが生じます。多数の計算では、これは重要です。 Python 3.0アプローチは、この問題を排除します。
一般的に使用される丸め方法は複数あります。浮動小数点演算の国際標準であるIEEE 754では、 5つの異なる丸め方法 (Python 3.0で使用されるものがデフォルトです)を定義しています。他にもあります。
この動作は、本来あるべきほど広く知られていません。 AppleScriptは、私が正しく覚えていれば、この丸め方法の早期採用者でした。 AppleScriptのround
コマンドには実際にいくつかのオプションがありますが、IEEE 754のように偶数に丸めるのがデフォルトです。明らかにround
コマンドを実装したエンジニアは、 「学校で学んだように機能させる」ことを要求し、彼はそれを実装しました:round 2.5 rounding as taught in school
は有効なAppleScriptコマンドです。 :-)
Decimalモジュール を使用して、Py3000で取得する丸めを制御できます。
>>> decimal.Decimal('3.5').quantize(decimal.Decimal('1'),
rounding=decimal.ROUND_HALF_UP)
>>> Decimal('4')
>>> decimal.Decimal('2.5').quantize(decimal.Decimal('1'),
rounding=decimal.ROUND_HALF_EVEN)
>>> Decimal('2')
>>> decimal.Decimal('3.5').quantize(decimal.Decimal('1'),
rounding=decimal.ROUND_HALF_DOWN)
>>> Decimal('3')
ここにドキュメントから重要なメモを追加するだけです:
https://docs.python.org/dev/library/functions.html#round
注意
Floatに対するround()の動作は驚くべきものです。たとえば、round(2.675、2)は、予想される2.68ではなく2.67を返します。これはバグではありません。これは、ほとんどの小数部が浮動小数点数として正確に表現できないという事実の結果です。詳細については、浮動小数点演算:問題と制限を参照してください。
したがって、Python 3.2で次の結果が得られても驚かないでください。
>>> round(0.25,1), round(0.35,1), round(0.45,1), round(0.55,1)
(0.2, 0.3, 0.5, 0.6)
>>> round(0.025,2), round(0.035,2), round(0.045,2), round(0.055,2)
(0.03, 0.04, 0.04, 0.06)
私も最近これに問題がありました。したがって、私はこれに対処し、同じ丸め動作を与える2つの関数trueround()およびtrueround_precision()を使用するpython 3モジュールを開発しました(銀行家の丸めではなく)。これがモジュールです。コードを保存してコピーするかインポートするだけです。注:trueround_precisionモジュールは、10進数モジュールのROUND_CEILING、ROUND_DOWN、ROUND_FLOOR、ROUND_HALF_DOWN、ROUND_HALF_EVEN、ROUND_HALF_UP、ROUND_UP、およびROUND_05UPフラグに従って、必要に応じて丸め動作を変更できます(詳細については、モジュールのドキュメントを参照してください)。以下の関数については、docstringsを参照するか、ヘルプ(trueround)およびhelp(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 <[email protected]>
'''
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 <[email protected]>
'''
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)
お役に立てれば、
ナーニー
Python 3.xは、.5値を隣接する偶数に丸めます
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
ただし、必要に応じて、10進数の「バック」を常に0.5に切り上げるように変更できます。
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
4のようにさらに小数が必要な場合は、(+ 0.0000001)を追加する必要があります。
私のために働きます。
pythonでのPython 2の丸め動作3。
小数点第15位に1を追加します。 15桁までの精度。
round2=lambda x,y=None: round(x+1e-15,y)
サンプルの再現:
['{} => {}'.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']
API: https://docs.python.org/3/library/functions.html#round
州:
小数点以下n桁の精度に丸められた数値を返します。 ndigitsが省略されるかNoneの場合、入力に最も近い整数を返します。
Round()をサポートする組み込み型の場合、値は10のべき乗からndigitsを引いた値の最も近い倍数に丸められます。 2つの倍数が等しく近い場合、偶数の選択に向かって丸めが行われます(たとえば、round(0.5)とround(-0.5)は両方とも0で、round(1.5)は2です)。 ndigitsには任意の整数値が有効です(正、ゼロ、または負)。 ndigitsが省略されている場合、またはNoneの場合、戻り値は整数です。それ以外の場合、戻り値は数値と同じ型を持ちます。
一般的なPythonオブジェクト番号の場合、デリゲートを数値に丸めます。round。
注floatに対するround()の動作は驚くべきものです。たとえば、round(2.675、2)は、予想される2.68ではなく2.67を返します。これはバグではありません。これは、ほとんどの小数部が浮動小数点数として正確に表現できないという事実の結果です。詳細については、浮動小数点演算:問題と制限を参照してください。
この洞察を考えると、あなたはそれを解決するためにいくつかの数学を使用することができます
import math
def my_round(i):
f = math.floor(i)
return f if i - f < 0.5 else f+1
これで、ラウンドではなくmy_roundで同じテストを実行できます。
['{} => {}'.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']
round演算子は、値を最も近い整数値に丸めます。
例:
値がo.5より大きい場合、1に四捨五入されます
print(round(211.5554, 2)) // output is 211.56
値が0.5より小さい場合、0に四捨五入されます
print(round(211.5544, 2)) // output is 211.55