Search code examples
pari-gp

Pari/GP compare integer with real


I want to test if an integer is a perfect power in Pari-gp. The test sqrt(n)==floor(sqrt(n)) works fine for testing squares, but it fails for every other power: sqrtn(n,k)==floor(sqrtn(n,k)) with k >=3.

I think it maybe since one number is real and the other one is integer. Still the test works for squares. What am I doing wrong?


Solution

  • Prime powers have factorizations involving only one base (the prime factor itself). So a better way to perform the test would be:

    isPrimePower(x) = {
      matsize(factor(x))[1]==1
    }
    

    Here's a test for the first 10 numbers:

    for(i=0,10,print(i,"->",isPrimePower(i)))
    0->1  (yes, p^0)
    1->0
    2->1  (yes, 2^1)
    3->1  (yes, 3^1)
    4->1  (yes, 2^2)
    5->1  (yes, 5^1)
    6->0
    7->1  (yes, 7^1)
    8->1  (yes, 2^3)
    9->1  (yes, 3^3)
    10->0
    

    For composite bases, I'll have to assume you mean that a perfect power factors into some single base raised to an exponent e >= 2. Otherwise any n = n^1. Even now we have corner case of 1 since 1=1^k.

    isPerfectPower(x) = { 
      local(e);
      if(x==1, return(0));
      factors = factor(x);
      e = factors[1,2];
      if(e < 2, return(0));
      for(i=2,matsize(factors)[1],
          if(factors[i,2] != e, return(0));
      );
      return(1);
    }
    

    And the test again:

    > for(i=1,20,print(i,"->",isPerfectPower(i)))
    1->0
    2->0
    3->0
    4->1
    5->0
    6->0
    7->0
    8->1
    9->1
    10->0
    11->0
    12->0
    13->0
    14->0
    15->0
    16->1
    17->0
    18->0
    19->0
    20->0