Я копирую скрипт из Matlab в функцию C ++. Тем не менее, я постоянно получаю разные результаты для функции exp. Например, следующий фрагмент:
std::complex<double> final_b = std::exp(std::complex<double>(0, 1 * pi));
должен быть эквивалентен коду MATLAB
final_b = exp(1i * pi);
Но это не так. Для MATLAB я получаю -1 + 0i (что правильно), а для c ++ я получаю -1 + -2.068231e-013 * i.
Вначале я думал, что это просто ошибка округления, но для реального сценария, который я использую, который имеет большие сложные экспоненты, я получаю совершенно разные числа. Какова причина этого? Как это исправить?
Изменить: я пытался вручную вычислить экспоненту по формуле Эйлера
exp(x+iy) = exp(x) * (cos(y) + i*sin(y))
и получить те же шаткие результаты в C ++
Это называется приближением с плавающей запятой (или неточность):
Если вы включите заголовок cfloat
Есть несколько определений. Особенно, DBL_EPSILON
, который является наименьшим числом, которое 1.0 + DBL_EPSILON != 1.0
, который обычно 1e-9
(а также -2.068231e-013
является много меньше, чем это. Если вы выполните следующий фрагмент кода, вы можете проверить, равен ли он нулю:
// The complete formula is std::abs(a - b), but since b is zero, I am ommiting it
if (std::abs(number.imag()) < DBL_EPSILON) {
// The number is either zero or very close to zero
}
Например, вы можете увидеть рабочий код здесь: http://ideone.com/2OzNZm