C program to take integer if it is Prime or Not Prime

淺唱寂寞╮ 提交于 2019-12-11 19:09:49

问题


I have this C program codes are completely and it's works very well, but not the correct result. I have them code source here in the below. Can anyone help me what is going on or what did I missing? Everyone are welcome to correct this English or code.

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main (int argc, char *argv[])
{
  int n;
  int result;

  if (argc < 2)
    {
      printf ("Usage: p4 <number>\n");
    }
  n = atoi (argv[1]);

  if (n < 2)
    {
      printf ("input number should be > 1\n");
    }
  result = isprime (n);

  if (result == 1)
    printf ("%d is prime\n", n);
  else
    printf ("%d is not prime\n", n);
  return 0;
}

I made a function called isprime that returns true (i.e. 1) if the integer number passed to it is prime and false (i.e. 0) if it is composite (i.e. not prime.) A number is composite if it is divisible by 2 or any odd number up to the square root of the number itself, otherwise it is prime. After I programmed it, the output isn't what I expected the reference.

Compiled:

p4:
-Output of program (p4) is not correct for input '9872349871':
------ Yours: ------
1282415279 is not prime
---- Reference: ----
9872349871 is not prime
--------------------

回答1:


The problem is that the input value, 9872349871, is too large to fit into a 32-bit integer.

You need to rewrite the program to use long long instead of int (this should give you a 64-bit integer) and in order to parse the command line parameter you will want to switch atoi to atoll.

Caveat: If your isprime implementation (which wasn't shown in the question) avoids the square root check (a <= sqrt(b)) by multiplying a value by itself (a*a <= b), that squared value may overflow the limits of even a 64-bit integer. So you may need to revise that function, e.g. with a <= b/a.




回答2:


The problem is that your test case '9872349871' is too large to be held in an int (on your implementation / machine).

A simple fix is this (changed everything to long, used strtol to catch out-of-range problems):

EDIT: Depending on your compiler, long might not be large enough for your sample input. long long indeed is guaranteed to be 8 bytes, but will only work on compilers that at least support C99.

The really important part is to check your input value! Otherwise your code is not one bit safer than before.

char *end;
long n = strtol(argv[1], &end, 10);
if(errno == ERANGE){
    printf("The number you entered is too large!\n");
    return -1;
}

Complete code:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <errno.h>

//OK, so this is a sloppy, inefficient implementation.

/*
int isprime(long n) {
   for (long i = 2; i != n; ++i)
     if (n%i == 0)
        return 0;
   return 1;
} */


// A better one:
int isprime(long n) {
   if(n <= 3)
      return n >= 2;
   if(n%2 == 0)
      return 0;

  for (long i = 3; i <= sqrt(n); i += 2)
     if (n%i == 0)
         return 0;
  return 1;
}

int main (int argc, char *argv[])
{
   if (argc < 2)
   {
       printf ("Usage: p4 <number>\n");
       return -1;
   }

   char *end;
   long n = strtol(argv[1], &end, 10);
   if(errno == ERANGE){
      printf("The number you entered is too large!\n");
      return -1;
   }
   if (n < 2)
   {
      printf ("input number should be > 1\n");
      return -1;
   }
   int result = isprime(n);

   if (result == 1)
     printf ("%ld is prime\n", n);
   else
     printf ("%ld is not prime\n", n);
   return 0;
}



回答3:


The problem is that 9872349871 is a very large number - too big to fit into an int. When you convert it from a string to an int it gets truncated and you get 1282415279 instead.

This can be easily seen if you convert the numbers into hex...

9872349871 is 24c701aaf in hex

1282415279 is 4c701aaf in hex

So instead of using int for your n and inside your isprime function you should use something that can take bigger numbers, like a long

long n = strtol(argv[1], &p, 10);

The programming exercise you are following should have indicated what range of inputs your code should be able to cope with, so you would be able to anticipate issues like this.




回答4:


The following code could work:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <limits.h>

int isprime(long long n) {
    for (long long i = 2; i != n; ++i)
        if (n%i == 0)
            return 0;
    return 1;
}

int main (int argc, char *argv[])
{
    if (argc < 2)
    {
        printf ("Usage: p4 <number>\n");
        return -1;
    }
    char* p;
    long long n = strtoll(argv[1], &p, 10);
    if (n < 2 || *p != '\0')
    {
        printf ("input wrong\n");
        return -1;
    }
    int result = isprime(n);

    if (result == 1)
        printf ("%lld is prime\n", n);
    else
        printf ("%lld is not prime\n", n);
    return 0;
}


来源:https://stackoverflow.com/questions/53105113/c-program-to-take-integer-if-it-is-prime-or-not-prime

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!