Я бы, наверное, проверил это так, потому что моя политика заключается в том, чтобы быть параноиком в отношении точности математических функций:
double root = sqrt(z);
int introot = floor(root + 0.5); // round to nearby integer
if ((introot * introot) == z) { // integer arithmetic, so precise
cout << introot << " == sqrt(" << z << ")\n";
}
double
может точно представлять все целые числа, которые нас интересуют (для этогоДело в том, что в большинстве реализаций он может точно представлять все значения int
).Он также обладает достаточной точностью, чтобы различать sqrt(x)
и sqrt(x+1)
для всех целых чисел, которые нас интересуют.sqrt (10000) - sqrt (9999) - 0,005, поэтому нам нужно всего 5 знаков после запятой, чтобы избежать ложных срабатываний, поскольку нецелочисленный квадратный корень не может быть ближе к целому числу.Поэтому хорошая реализация sqrt
может быть достаточно точной, чтобы (int)root == root
сам по себе справился бы с этой задачей.
Однако в стандарте не указана точность sqrt
и других математических функций.В C99 это явно указано в 5.2.4.2.2 / 5: я не уверен, что C89 или C ++ делают это явно.Так что я не хочу исключать, что результат может быть из-за ульпи или около того.int(root) == root
даст ложный отрицательный результат, если sqrt(7744)
получится как 87.9999999999999-иш
Кроме того, есть гораздо большие числа, где sqrt
не может быть точным (в пределах предела того, что может double
)представлять точно).Поэтому я думаю, что легче написать дополнительные две строки кода, чем написать комментарий, объясняющий, почему я думаю, что математические функции будут точными в том случае, если я забочусь о: -)