Каковы различия под капотом между round () и numpy.раунд ()?

давайте посмотрим на постоянно шокирующее круглое заявление:

>>> round(2.675,2)
2.67

Я знаю, почему раунд "терпит неудачу", это из-за двоичного представления 2.675 :

>>> import decimal
>>> decimal.Decimal(2.675)
Decimal('2.67499999999999982236431605997495353221893310546875')

чего я не понимаю, так это:почему numpy не терпит неудачу ?

>>> import numpy
>>> numpy.round(2.675,2)
2.6800000000000002

мышление

не возражайте против дополнительных нулей, это артефакт от внутреннего округления печати python, если мы посмотрим на "точные" значения, они все еще разные :

>>> decimal.Decimal(round(2.675,2))
Decimal('2.6699999999999999289457264239899814128875732421875')

>>> decimal.Decimal(numpy.round(2.675,2))
Decimal('2.680000000000000159872115546022541821002960205078125')

почему о почему numpy ведет себя ?

я сначала подумал, что numpy должен обрабатывать поплавки, используя дополнительные биты, но:

>>> decimal.Decimal(numpy.float(2.675))
Decimal('2.67499999999999982236431605997495353221893310546875')
>>> decimal.Decimal(2.675)
Decimal('2.67499999999999982236431605997495353221893310546875')
# twins !

может кто-нибудь пролить свет на то, что происходит за шторами ? Я посмотрел немного в пакете numpy в этап, но я новичок python, и я не вижу ничего слишком подозрительного.

1 ответов


один поверх разницы капота документируется:

в случаях, когда вы находитесь на полпути между числами,np.round округляет до ближайшего "четного" числа (после умножения на 10**n здесь n является вторым аргументом для соответствующего