В целом операции с плавающей запятой приведут к ошибке ULP. IEEE 754 требует, чтобы результаты для большинства операций были корректными с точностью до 0,5 ULP, но могут накапливаться ошибки, что означает, что результат может быть не в пределах одного ULP от точного результата. Существуют также пределы точности, поэтому в зависимости от количества цифр в результирующих значениях вы также можете не работать со значениями одинаковых величин. Трансцендентальные функции также представляют собой notorious для введения ошибки в вычисления.
Однако, если вы используете GNU glibc, SQRT будет правильным в пределах 0,5 ULP (округленно), так что вы конкретный пример будет работать (без учета NaN
, +/-0
, +/-Inf
). Хотя, вероятно, лучше определить некоторый эпсилон в качестве допустимости ошибок и использовать его в качестве вашей привязки. Для exmaple,
bool gt(double a, double b, double eps) {
return (a > b - eps);
}
В зависимости от уровня точности вам необходимо в расчетах, вы можете также использовать long double
вместо.
Таким образом, чтобы ответить на ваши вопросы ...
а) Является ли у * у> = х гарантируется с помощью GCC компилятор?
Предполагая, что вы используете встроенные GNU glibc или SSE2, да.
b) Будет ли это работать для других операций, таких как + - */или даже std :: cos() и std :: acos()?
Предполагая, что вы используете GNU glibc и одну операцию, да. Хотя некоторые трансценденталы не гарантированы правильно округлены.
c) Есть ли лучшие способы получить верхнюю/нижнюю границу?
Вам необходимо знать, что такое допуски к ошибкам в вычислениях, и использовать их как эпсилон (который может быть больше одного ULP).
Вы запрашиваете этот конкретный случай или вообще для любого числа с плавающей запятой? NaN немедленно нарушает любую логику. –
Насколько я могу судить, стандарт не дает никаких гарантий на реализацию '' std :: sqrt'', поэтому я думаю, что ответ на этот вопрос будет зависимым от реализации. –
@MarkB Я имею в виду любое (положительное) число с плавающей запятой, 42 - просто пример. – Lux