back to blog index

It is based on the Miller-Rabin

It is based on the Miller-Rabin test for strong pseudoprimality, and it
uses pubished efficient sets of bases for primality testing based on this
test [http://math.crg4.com/primes.html].”
 

-- Solution by Steve Kass

if object_id('dbo.modMult') is not null

  drop function dbo.modMult;

go

create function dbo.modMult(

  @f1 bigint,

  @f2 bigint,

  @modulus bigint

) returns bigint as begin

    declare @result bigint;

    set @result = 0;

    --declare @sign int;

    --set @sign = sign(@f1)*sign(@f2);

    --set @f1 = abs(@f1);

    --set @f2 = abs(@f2);

    while @f2 > 0 begin

      if @f2 % 2 = 1

        set @result = (@result + @f1)%@modulus

      set @f2 = @f2/2;

      set @f1 = (@f1 + @f1) % @modulus;

    end;

    return @result--*@sign;

  end;

go

 

if object_id('dbo.modPower') is not null

  drop function dbo.modPower;

go

create function dbo.modPower(

  @base bigint,

  @exponent bigint,

  @modulus bigint

) returns bigint

  as begin

    declare @result bigint;

        set @result = 1;

        while @exponent > 0 begin

          if @exponent%2 = 1

                set @result = dbo.modMult(@result,@base,@modulus);

          set @exponent = @exponent / 2;

          set @base = dbo.modMult(@base,@base,@modulus);

        end;

        return @result;

  end

go

 

if object_id('dbo.RabinPseudoPrime') is not null

  drop function dbo.RabinPseudoPrime;

go

create function dbo.RabinPseudoPrime(

  @n bigint,

  @witness bigint

) returns bit

  as begin

  declare @s int;

  set @s = 0;

  declare @d bigint;

  set @d = @n - 1;

  while @d%2 = 0 begin

    set @s = @s + 1;

    set @d = @d/2;

  end

  if dbo.modPower(@witness,@d,@n) = 1

    return 1;

  while @d <= (@n-1)/2 begin

    if dbo.modPower(@witness,@d,@n) = @n-1

      return 1;

    set @d = @d*2;

  end;

  return 0;

end;

go

 

if object_id('dbo.fn_isprimeSK') is not null

  drop function dbo.fn_isprimeSK;

go

create function dbo.fn_isprimeSK(

  @n bigint

) returns bit as begin

  declare @result bit;

  if @n < 17

    if @n in (2, 3, 5, 7, 11, 13) return 1 else return 0;

  if right(@n,1) in ('0','2','4','6','8','5') return 0;

  if  @n%3=0 return 0;

  if  @n%7=0 return 0;

  if  @n%11=0 return 0;

  if  @n%13=0 return 0;

  set @result = dbo.RabinPseudoPrime (@n, 2);

  if @result = 0 or @n < 2047 return @result;

  set @result = dbo.RabinPseudoPrime (@n, 3);

  if @result = 0 or @n < 1373653 return @result;

  set @result = dbo.RabinPseudoPrime (@n, 5);

  if @result = 0 or @n < 25326001 return @result;

  set @result = dbo.RabinPseudoPrime (@n, 7);

  if @result = 0 or @n < 3215031751 return @result;

  if dbo.RabinPseudoPrime(@n,61) = 0 return 0;

  return dbo.RabinPseudoPrime(@n,25251)

  return @result;

end;

Again, as far as I can tell, existing fast deterministic techniques are
suited for iterative/recursive implementations and not set-based ones.
An implementation of iterative/recursive algorithms would probably be
much faster with CLR code compared to T-SQL code.

You can find more details about fast deterministic tests here:
http://en.wikipedia.org/wiki/Primality_test, and more details about the
Miller-Rabin test here: http://en.wikipedia.org/wiki/Miller-
Rabin_primality_test.

Cheers,
--
BG

End of Article

Prev. page     1 2 3 4 5 6 [7]     next page -->


You must log on before posting a comment.

If you don't have a username & password, please register now.

 

      1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31       
or

More blogs about technology,
databases, and SQL Server.