Вы должны либо использовать np.arange(5210, 5220) / 10
или np.linspace(521, 522, 10, endpoint=False)
, но прочитать весь ответ.
Часть вашего кода является неправильной, но не так, как вы мышление.
Операции с плавающей точкой имеют ошибку округления. Это является фундаментальным для чисел с плавающей запятой и фундаментальным ограничением попыток выполнять вычисления с действительными числами на компьютерах с ограниченными ресурсами. Даже символьные c вычисления не исправят ситуацию - когда выражение невозможно символически упростить, вы в конечном итоге просто строите гигантские деревья выражений вместо того, чтобы фактически что-либо вычислять.
Простое присутствие ошибки округления в вашем вывод не означает, что вы сделали что-то не так. Кроме того, ошибка округления уже присутствовала в выводе arange
, просто скрыта настройками печати по умолчанию NumPy - она не была введена в вызове tolist
. При любом даже немного нетривиальном вычислении с плавающей точкой вы никогда не устраните все ошибки округления.
Даже результат, который выглядит как [521. , 521.1, 521.2, 521.3, 521.4, 521.5, 521.6, 521.7, 521.8, 521.9]
, на самом деле будет иметь ошибку округления, потому что действительное число 521.1 на самом деле не представляется в двоичном виде плавающая запятая. Большинство чисел, которые выглядят так, как будто они в этом списке, не могут быть представлены в двоичной форме с плавающей точкой. (64-разрядный) float 521.1
на самом деле 521.1000000000000227373675443232059478759765625
, но большинство языков программирования не отображают точное значение по умолчанию.
Часть вашего кода, которая действительно неверна, использование arange
с входами с плавающей запятой. arange
не согласуется с входными данными с плавающей запятой, поскольку в зависимости от ошибки округления он может содержать больше или меньше элементов, чем ожидалось. Например,
np.arange(1, 1.3, 0.1)
возвращает
array([1. , 1.1, 1.2, 1.3])
вместо
array([1. , 1.1, 1.2])
из-за ошибки округления с плавающей точкой при вычислении длины результата.
Кроме того, из-за некоторых странных решений о реализации, arange
с входными данными с плавающей запятой имеет гораздо большую ошибку округления, чем должна, даже когда он получает правильный выходной размер.
np.linspace
разработан, чтобы избежать проблем с arange
. Он принимает выходной размер в качестве аргумента напрямую, вместо того, чтобы вычислять его из шага, и имеет явный параметр для включения или выключения правильной конечной точки. Это позволяет избежать ошибки округления при вычислении выходного размера, если вы сами не представите его, вычислив выходной размер с плавающей запятой. np.linspace
также имеет меньшую погрешность округления, чем arange
при вычислении выходных элементов. Не гарантируется минимальная ошибка округления - например, np.linspace(0, 3, 148)[::49].tolist()
показывает избыточную ошибку округления - но это намного лучше, чем с плавающей точкой arange
.
np.arange(5210, 5220) / 10
использует arange
с целочисленными аргументами и делит потом. Эта опция имеет только один источник ошибки округления, деление на 10. Это деление гарантировано IEEE 754 spe c, чтобы быть правильно округленным , в результате чего результаты будут округлены до плавающей запятой значения, наиболее близкие к идеальным действительным числам деления. Эта опция гарантирует наименьшую ошибку округления, в некоторых случаях превышая linspace
. Например, np.arange(148) / 49
бьет np.linspace(0, 3, 148)
в ошибке округления.