Как повысить int или long до степени C ++ - PullRequest
4 голосов
/ 17 августа 2011

Тривиальный вопрос: мне просто интересно, если кто-то хочет поднять int или long в силу другого int или long, делает ли

(long)std::pow((double)a,(double)b)

достаточно, или мне нужно

(long)(0.5 + std::pow((double)a,(double)b))

Ответы [ 7 ]

5 голосов
/ 17 августа 2011

Есть два соображения.Первый - округление из-за неточности представлений с плавающей точкой;это не будет проблемой в этом случае, потому что целые числа прекрасно представимы, пока число битов меньше, чем биты значащих и в плавающей запятой.Если long равно 32 битам, а double значимо и равно 53 битам, как обычно, проблем не будет.

Вторым соображением является точность самой функции pow.Если есть вероятность, что оно окажется ниже, чем фактическое значение, добавление 0,5 для округления результата - единственный способ обеспечить правильный результат.

Ожидаемый результат от pow всегда будет целым числомтак что нет никакого вреда в добавлении 0,5.Я бы порекомендовал эту версию.

3 голосов
/ 17 августа 2011

Второй пример может быть более подходящим, поскольку он округляет результат до ближайшего целого числа, а не усекает его.

3 голосов
/ 17 августа 2011

Вы должны написать свою собственную функцию.Таким образом вы сами справитесь с переполнением, и вам не придется беспокоиться об ошибках округления.

Но из двух я бы использовал второе.

2 голосов
/ 17 августа 2011

Почему бы просто не использовать цикл. В любом случае не может быть более 31/63 целочисленных умножений без переполнения.

1 голос
/ 17 августа 2011

Сначала достаточно одного, но вам нужно проверить значение результата дважды перед приведением, так как оно может быть намного больше, чем максимальное значение long.

0 голосов
/ 17 августа 2011

Этого должно быть достаточно:

static_cast<long>(std::pow(static_cast<double>(a), b));

Вы должны понимать, что это будет переполнено при больших значениях b.

0 голосов
/ 17 августа 2011

Ваш первый пример действителен.Однако для ясности было бы лучше использовать static_cast<>() вместо броска в стиле c.Второй пример, который вы опубликовали, дал бы неверный результат для небольших значений и является излишним.

...