Показать сообщение отдельно
  #1 (permalink)  
Старый 30.09.2019, 20:49
Новичок на форуме
Отправить личное сообщение для Добрый_Серый_Волк Посмотреть профиль Найти все сообщения от Добрый_Серый_Волк
 
Регистрация: 20.08.2017
Сообщений: 3

Возведение в степень по модулю. Что не так?
Здравствуйте, гениальный математик, просматривающий тему.
Помогите починить мою бедную, сломанную голову и дайте совет что может быть не так и как должно быть ТАК.
Имеем набор функций, собранных из разных уголков интернета(изложенных мной) и предназначенных для возведения большого числа в большую степень по модулю:
/*1 - способ "справа налево. Представляем степень в виде двоичного числа и в зависимости от нуля или единицы творим всякую фигню."*/
     const PowToModFromWiki = (base, pow, mod) =>{
                let step = pow.toString(2).split('').map(Number);
                let result = 1;
                for(let i=step.length-1;i>0;i--){
                      result =(result * base**step[i])%mod;
                      base = (base**2)%mod;
                }
                return (result*base)%mod;
            }
            
   /*2 - способ упрощение степени. Возводим базу в квадрат, делим степень пополам*/ 
      const anotherPowToMod = (base, pow, mod) => {
                let temp = 1;
                while (pow>2){
                    if (!(pow%2)) {
                        base = base**2%mod;
                        pow/=2;
                    }
                    else {
                        pow--;
                        temp =(temp * base)%mod;
                    }
                }
                return (temp * (base**pow % mod))%mod;
            }
            
  /*3 - рекурсивное быстрое возведение в степень. Ненавижу рекурсию*/     
        const recursePowToMod = (base, pow, mod) => {
                const bynPow = (base, pow) =>{
                    if (pow == 1) return base;  
                    if (pow%2 == 0) {
                    let temp = bynPow(base, pow/2);
                    return temp**2%mod;
                        } else return bynPow(base, pow-1)*base%mod;
                }
                return bynPow (base, pow); 
            }
            
   /*4 - школьный метод, самый простой. Без комментариев.*/    
     const tooDumbPowToMod = (base, pow, mod) => {
                let result = 1;
                for(let i=0; i<pow; i++) {
                    result = result * base % mod;
                }
                return result;
            }

И все бы хорошо - при малых значениях базы, степени и модуля они возвращают одинаковое (правильное) значение.
Но, с ростом вводимых значений они начинают чудить: 1 и 2 возвращают одно значение 3 иногда как 1 и 2, а иногда свое; 4 - держится дольше всех, на 9-10 значных числах, ломаясь.
Вот, к примеру входные значения:366142356 1447804911 219020071
(вероятно)Правильный ответ - 38504623
Ответить с цитированием