Thread: negative factors of an Integer

  1. #1
    Registered User
    Join Date
    Feb 2017
    Posts
    2

    negative factors of an Integer

    Hello Guys, this is my first of many many coming posts.

    Having this code. i got negative numbers, does anyone know why?.


    Code:
    #include <stdio.h>
    
    int factors(long int b);
    
    int main () {
      long int num = 12345678987;
      long int ret;
      ret = factors(num);
    
      return 0;
    }
    
    int factors(long int b) {
        long int i;
        
        for( i=1; i <= 12345678987 ; i++ ){
            if( b % i == 0 ){
                printf( "Value is: %d\n", i);
            }
        }
    }
    Output
    Value is: 87558007
    Value is: 242072137
    Value is: 262674021
    Value is: 726 216 411
    Value is: -179740967
    Value is: -539222901

  2. #2
    Registered User
    Join Date
    Jun 2015
    Posts
    1,640
    You need to use a format of "%ld" to print a long value with printf.

    Also, you shouldn't hard-code the upper value for i. You should use b instead.

    However, your factoring routine is very inefficient!

    And you aren't actually returning anything from the function, so you should probably make the return type void.
    Last edited by algorism; 02-10-2017 at 02:08 PM.

  3. #3
    Registered User
    Join Date
    Jun 2011
    Posts
    4,513
    Are you getting any warnings when you compile?

    Code:
    main.c||In function 'main':|
    main.c|6|warning: integer constant is too large for 'long' type|
    main.c|6|warning: overflow in implicit constant conversion|
    main.c||In function 'factors':|
    main.c|16|warning: integer constant is too large for 'long' type|
    main.c|16|warning: comparison is always true due to limited range of data type|
    main.c|18|warning: format '%d' expects type 'int', but argument 2 has type 'long int'|
    The maximum size of a long int is 32 bits. Therefore the maximum value for a (signed) long int is 231 - 1 = 2147483647.

    Try using type "long long" instead.

  4. #4
    Registered User
    Join Date
    Jun 2015
    Posts
    1,640
    Quote Originally Posted by Matticus View Post
    The maximum size of a long int is 32 bits.
    On a 32-bit machine, perhaps.

  5. #5
    Registered User
    Join Date
    Jun 2011
    Posts
    4,513
    Quote Originally Posted by algorism View Post
    On a 32-bit machine, perhaps.
    That limitation is directly from the standard, Section 5.2.4.2.1:

    Quote Originally Posted by c11-draft
    - maximum value for an object of type long int
    LONG_MAX +2147483647 // 231 − 1

  6. #6
    Registered User
    Join Date
    Jun 2015
    Posts
    1,640
    Quote Originally Posted by Matticus View Post
    That limitation is directly from the standard, Section 5.2.4.2.1:
    You're misreading the standard. That's the lowest possible maximum value for a long int.
    Last edited by algorism; 02-10-2017 at 02:28 PM.

  7. #7
    Registered User
    Join Date
    Jun 2011
    Posts
    4,513
    I may have mis-interpreted the standard

    Their implementation-defined values shall be equal or greater in magnitude (absolute value) to those shown, with the same sign.
    [edit]
    Yes, you are correct.

  8. #8
    Registered User
    Join Date
    Feb 2017
    Posts
    2
    I did a little change to the code and now i got a btter result, You got me, i'm not a C programmer, i have been doing this for just 2 or 3 days, but i want to start with simple math programs.
    I read my factoring routine is very inefficient, Can you share a better routine?, i'd like to see your point of view of how to attack the problem here.
    Thanks in advance.

    Code:
    #include <stdio.h>
    
    long int factors(long int b);
    
    int main () {
      long int num = 12345678987;
      factors(num);
    
      return 0;
    }
    
    
    
    long int factors(long int b) {
         long int i;
        
        for( i=1; i <= b ; i++ ){
            if( b % i == 0 ){
                printf( "Value is: %ld\n", i);
            }
        }
    }
    BTW, this is the warning i got
    Code:
    gcc -Wall sample_factor.c
    sample_factor.c: In function ‘factors’:
    sample_factor.c:22:1: warning: control reaches end of non-void function [-Wreturn-type]
     }

  9. #9
    Registered User
    Join Date
    Jun 2015
    Posts
    1,640
    Quote Originally Posted by Matticus View Post
    I may have mis-interpreted the standard
    [edit]
    Yes, you are correct.
    Actually, now that I think about it, you're right as far as portability goes. However, gcc -Wall -W -pedantic gives me no warnings when compiling his program on my machine.

  10. #10
    Registered User
    Join Date
    Jun 2015
    Posts
    1,640
    You could do something like the following to make it a little better. However, there are much more sophisticated methods that you can read about. The following will still take forever with a large prime.

    I've also decided to use long longs for better portability.
    Code:
    #include <stdio.h>
    
    void factor(long long n) {
        printf("%lld: ", n);
    
        // remove factors of 2 so we can increment by 2 in the next loop
        for ( ; n % 2 == 0; n /= 2)
            printf("2 ");
    
        for (long long i = 3; i <= n; )
            if (n % i == 0) {
                printf("%lld ", i);
                n /= i;   // divide out the factor so n becomes smaller
            }
            else
                i += 2; // increment by 2 (but only if we didn't divide by the current i)
    
        putchar('\n');
    }
    
    int main() {
        while (1) {
            printf("Enter number to factor (0 to quit): ");
            long long n;
            scanf("%lld", &n);
            if (n == 0) break;
            factor(n);
        }
        return 0;
    }
    And note the void return type. If you're not returning anything (with a return statement) then you should make the return type void.

    EDIT: A more sophisticated algorithm is Pollard's Rho Algorithm
    (apparently used by gnu's factor program).
    Last edited by algorism; 02-10-2017 at 02:43 PM.

  11. #11
    Registered User
    Join Date
    Jun 2015
    Posts
    1,640
    The previous program I posted has a bug in that it doesn't generally print the final factor (final value of n). Also, it has an inefficiency in not being bound by the square root of n (which is why it took so long for large primes). Those are fixed below as well as changing it use unsigned long and making it take input from the command line.
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <math.h>  // sqrtl
    #include <errno.h>
    
    typedef unsigned long UL;
    
    void factor(UL n) {
        printf("%lu: ", n);
    
        for ( ; n % 2 == 0; n /= 2)
            printf("2 ");
    
        UL sq = (UL)sqrtl((long double)n);
        for (UL i = 3; i <= sq; ) {
            if (n % i == 0) {
                printf("%lu ", i);
                n /= i;
                sq = (UL)sqrtl((long double)n);
            }
            else
                i += 2;
        }
    
        if (n > 1)
            printf("%lu", n);
        putchar('\n');
    }
    
    int main(int argc, char *argv[]) {
        if (argc < 2) {
            printf("Usage: myfactor NUMBER...\n");
            exit(EXIT_FAILURE);
        }
    
        for (int i = 1; i < argc; i++) {
            char *end = NULL;
            errno = 0;
            UL n = strtoul(argv[i], &end, 10);
            if (errno == ERANGE)
                fprintf(stderr, "%s: number out of range of unsigned long\n",
                        argv[i]);
            else if (*end)
                fprintf(stderr, "%s: invalid number\n", argv[i]);
            else if (n != 0)
                factor(n);
        }
    
        return 0;
    }

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Integer remainder for negative numbers
    By StanS in forum C Programming
    Replies: 4
    Last Post: 11-23-2011, 05:41 PM
  2. Replies: 3
    Last Post: 04-18-2011, 09:15 AM
  3. Replies: 3
    Last Post: 02-19-2009, 10:32 PM
  4. Replies: 10
    Last Post: 04-05-2008, 03:21 PM
  5. negative integer?
    By cblix in forum C Programming
    Replies: 3
    Last Post: 11-09-2005, 02:08 AM

Tags for this Thread