Почему is.NET-сложный тип сломан?


Я был поражен, обнаружив, что тип данных System.Numerics.Complex в .NET не дает математически точных результатов.

Complex.Sqrt(-1) != Complex.ImaginaryOne

Вместо (0, 1) я получаю (6.12303176911189 E-17, 1), что очень похоже на ошибку округления.

Теперь я понимаю, что арифметика с плавающей запятой иногда приводит к подобным результатам, но обычно использование целых чисел позволяет избежать ошибок округления. Почему эта, казалось бы, основная операция дает заведомо неверный результат?
1 8

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) ошибка округления становится видимой, когда реальная координата приближается к нулю.