Task: Factors of a Mersenne number




Go: package main

import (
    "fmt"
    "math"
)



const qlimit = 2e8

func main() {
    mtest(31)
    mtest(67)
    mtest(929)
}

func mtest(m int32) {
    
    
    
    
    if m < 4 {
        fmt.Printf("%d < 4.  M%d not tested.\n", m, m)
        return
    }
    flimit := math.Sqrt(math.Pow(2, float64(m)) - 1)
    var qlast int32
    if flimit < qlimit {
        qlast = int32(flimit)
    } else {
        qlast = qlimit
    }
    composite := make([]bool, qlast+1)
    sq := int32(math.Sqrt(float64(qlast)))
loop:
    for q := int32(3); ; {
        if q <= sq {
            for i := q * q; i <= qlast; i += q {
                composite[i] = true
            }
        }
        if q8 := q % 8; (q8 == 1 || q8 == 7) && modPow(2, m, q) == 1 {
            fmt.Printf("M%d has factor %d\n", m, q)
            return
        }
        for {
            q += 2
            if q > qlast {
                break loop
            }
            if !composite[q] {
                break
            }
        }
    }
    fmt.Printf("No factors of M%d found.\n", m)
}


func modPow(b, p, m int32) int32 {
    pow := int64(1)
    b64 := int64(b)
    m64 := int64(m)
    bit := uint(30)
    for 1<<bit&p == 0 {
        bit--
    }
    for {
        pow *= pow
        if 1<<bit&p != 0 {
            pow *= b64
        }
        pow %= m64
        if bit == 0 {
            break
        }
        bit--
    }
    return int32(pow)
}








Ada: with Ada.Text_IO;

with Is_Prime;

procedure Mersenne is
   function Is_Set (Number : Natural; Bit : Positive) return Boolean is
   begin
      return Number / 2 ** (Bit - 1) mod 2 = 1;
   end Is_Set;

   function Get_Max_Bit (Number : Natural) return Natural is
      Test : Natural := 0;
   begin
      while 2 ** Test <= Number loop
         Test := Test + 1;
      end loop;
      return Test;
   end Get_Max_Bit;

   function Modular_Power (Base, Exponent, Modulus : Positive) return Natural is
      Maximum_Bit : constant Natural := Get_Max_Bit (Exponent);
      Square      : Natural := 1;
   begin
      for Bit in reverse 1 .. Maximum_Bit loop
         Square := Square ** 2;
         if Is_Set (Exponent, Bit) then
            Square := Square * Base;
         end if;
         Square := Square mod Modulus;
      end loop;
      return Square;
   end Modular_Power;

   Not_A_Prime_Exponent : exception;

   function Get_Factor (Exponent : Positive) return Natural is
      Factor : Positive;
   begin
      if not Is_Prime (Exponent) then
         raise Not_A_Prime_Exponent;
      end if;
      for K in 1 .. 16384 / Exponent loop
         Factor := 2 * K * Exponent + 1;
         if Factor mod 8 = 1 or else Factor mod 8 = 7 then
            if Is_Prime (Factor) and then Modular_Power (2, Exponent, Factor) = 1 then
               return Factor;
            end if;
         end if;
      end loop;
      return 0;
   end Get_Factor;

   To_Test : constant Positive := 929;
   Factor  : Natural;
begin
   Ada.Text_IO.Put ("2 **" & Integer'Image (To_Test) & " - 1 ");
   begin
      Factor := Get_Factor (To_Test);
      if Factor = 0 then
         Ada.Text_IO.Put_Line ("is prime.");
      else
         Ada.Text_IO.Put_Line ("has factor" & Integer'Image (Factor));
      end if;
   exception
      when Not_A_Prime_Exponent =>
         Ada.Text_IO.Put_Line ("is not a Mersenne number");
   end;
end Mersenne;