В C или C ++ это:
(x^y)
не повышает x до степени y. Выполняет побитовую исключающую-или-операцию .Вот почему ваша первая реализация не дает правильного ответа.
В C или C ++ арифметический оператор по модулю:
%
определен только для целочисленных аргументов ,Даже если вы передаете целые числа в функцию __pow()
, возвращаемый результат этой функции - double
(т. Е. Величина с плавающей запятой, а не целое число).
Я не знаю,детали математики, которые вам нужно выполнить, но если вы приведете результат __pow
к int
(например), эта ошибка компиляции исчезнет. Это может или не может быть действительным для любой арифметики, которую вы хотите выполнить .(Например, вы можете привести его к «длинному» целому числу.)
После этого вы столкнетесь с другой ошибкой компиляции.Самый простой подход - использовать pow()
вместо __pow()
:
c_out[i] = (int)pow(m_in[i], e) % n;
Если вы на самом деле пытались использовать встроенную в CUDA fast-math , вам следует использовать __powf
not __pow
:
c_out[i] = (int)__powf(m_in[i], e) % n;
Обратите внимание, что встроенные математические функции обычно имеют пониженную точность.
Поскольку эти функции повышения мощности выполняют арифметику с плавающей запятой (даже если выпередавая целые числа) можно получить некоторые неожиданные результаты.Например, если вы повысите 5 до степени 2, можно получить 24.9999999999 вместо 25. Если вы просто приведете это к целому числу, вы получите усечение до 24. Поэтому вам может потребоваться изучить округление результата доближайшее целое число, вместо приведения.Но опять же, я не изучал математику, которую вы хотите выполнить.