2015-12-28 2 views
0

Я переключался с Matlab на IPython. В IPython, если мы умножим 3.1 на 2.1, следующий результат:Избегание небольших числовых ошибок при использовании IPython

In [297]: 

3.1 * 2.1 
Out[297]: 
6.510000000000001 

Существует небольшой ошибки округления. Это не большая проблема, но это немного раздражает. Я предполагаю, что он появился при преобразовании десятичных чисел в двоичные числа и наоборот, правильно?

Однако в Numpy массива, результат правильно:

>>> np.array([3.1 * 2.1]) 
array([ 6.51]) 

В Matlab командной строки, а также результат правильно:

>> 3.1 * 2.1 

ans = 

    6.5100 

выше ошибка округления в выглядит Python раздражает. Есть ли способ избежать этой ошибки в интерактивном режиме python или в IPython?

+0

Как правило, вам нужно просто использовать библиотеки, если вам нужна точность с плавающей запятой, но лет u может просто вынуть десятичную точку, выполнить умножение, а затем вставить десятичную точку в ваш вывод. Для вашего примера вы бы сделали 31 * 21 = 651, и поскольку вы умножили оба числа на 10, а 10 * 10 равнялись 100, оно становится 6.51 – Natecat

+1

Это не ошибка округления. На дисплее 'ipython' отображается только десятичная точка, чем две другие. – hpaulj

+0

@hpaulj I * будет * называть его округлой ошибкой, так как 3.1 \ * 2.1 действительно равно 6.51 в нормальной математике. Вы правы в том смысле, что разница в внешнем виде между numpy и плаваниями Python не имеет смысла, хотя обе страдают от этой неточности. –

ответ

3

не NumPy результат не более точен, чем чисто Python один - точка Неточность плавающей просто скрыта от вас, потому что, по умолчанию, Numpy печатает меньше десятичных разрядов результата:

In [1]: float(np.array([3.1 * 2.1])) 
Out[1]: 6.510000000000001 

Вы можете управлять как numpy отображает числа с плавающей запятой, используя np.set_printoptions. Например, для печати 16 знаков после запятой, а не обычные 8:

In [2]: np.set_printoptions(precision=16) 

In [3]: np.array([3.1 * 2.1]) 
Out[3]: array([ 6.5100000000000007]) 

В IPython вы можете также использовать %precision магию, чтобы контролировать количество десятичных знаков, которые отображаются при довольно-печать нормального Python поплавок:

In [4]: %precision 8 
Out[4]: u'%.8f' 

In [5]: 3.1 * 2.1 
Out[5]: 6.51000000 

Обратите внимание, что это чисто косметическое - значение 3.1 * 2.1 все равно будет равно 6.5100000000000006750155990..., а не 6.51.

2

В Octave, клон MATLAB, я могу показать те далекие десятичные:

octave:12> printf("%24.20f\n", 3.1*2.1) 
    6.51000000000000067502 

Они также представляют ваши numpy.array

In [6]: np.array([3.1*2.1]).item() 
Out[6]: 6.510000000000001 

даже термины компонента включают этот вид округления:

octave:13> printf("%24.20f\n", 3.1) 
    3.10000000000000008882 
octave:14> printf("%24.20f\n", 2.1) 
    2.10000000000000008882 
Смежные вопросы