Я представил такое же решение проблемы для онлайн-судьи на разных компиляторах для C++. В gcc (4.3.2) я получил WA, тогда как те же решения, когда они были отправлены на gcc (4.8.1), получили TLE.
Является ли это тем, что 4.3.2 работает быстрее, но я думаю, что последние версии с более высокими показателями производительности должны превзойти предыдущие или это аномалии с плавающей запятой в двух компиляторах, потому что проблема требует вычисления n-го корня из 64-битного числа, и я использую длинные двойные и длинные длинные типы данных с функцией pow.I использовал что-то вроде:
long long root,n;
long double rad,rcnd;
root = (long long)pow(rad,rcnd); where rcnd = 1.0/n;
Две версии одной и той же элементарной функции, такие как pow()
требуют, чтобы каждый был точным, чтобы> 0.5ULP иногда приводил к разным результатам с теми же аргументами.
Стандарты C и C++ не ограничивают точность на pow()
. Правильная реализация будет пытаться быть точным до 1ULP, но это все еще оставляет возможность ответа не быть лучшим и отличается от ответа другой 1-ULP-точной функции pow()
. На самом деле, несколько вопросов на этом сайте вызваны функциями pow()
, которые (в) точнее более чем 1ULP, однако это может быть уродливым и, несмотря на то, что доступным для поставщика неточной функцией является ginormous.
Короче говоря: если вы используете pow()
, вычисления могут различаться между двумя компиляторами, хотя компиляторы имеют одни и те же характеристики реализации (размер int, endianness,...). Если вы используете pow()
в численно неустойчивом вычислении, конечные результаты могут отличаться произвольно.
Обычным решением для воспроизводимых результатов является предоставление вашей собственной функции pow()
. Однако, если различие вызвано численно неустойчивыми вычислениями, это не устраняет проблему с корнем: результат, теперь воспроизводимый, может все еще быть бессмысленным.