Почему is.NET-сложный тип сломан?
Я был поражен, обнаружив, что тип данных System.Numerics.Complex
в .NET не дает математически точных результатов.
Complex.Sqrt(-1) != Complex.ImaginaryOne
Вместо (0, 1) я получаю (6.12303176911189 E-17, 1), что очень похоже на ошибку округления.
Теперь я понимаю, что арифметика с плавающей запятой иногда приводит к подобным результатам, но обычно использование целых чисел позволяет избежать ошибок округления. Почему эта, казалось бы, основная операция дает заведомо неверный результат?1 ответ:
Посмотрите на декомпилированный метод
Sqrt
.public static Complex Sqrt(Complex value) { return Complex.FromPolarCoordinates(Math.Sqrt(value.Magnitude), value.Phase / 2.0); }
На самом деле существует ошибка округления, вызванная использованием полярных координат и радианов.
value.Phase / 2.0
вернет pi/2, которое не является точно представимым числом. При преобразовании из полярных координат (1, pi/2) ошибка округления становится видимой, когда реальная координата приближается к нулю.