addition modulo 2^32 with unsigned ints (integer constant too large)

This is a discussion on addition modulo 2^32 with unsigned ints (integer constant too large) within the C Programming forums, part of the General Programming Boards category; Hello all, I have recently started to implement the SHA-256 checksum algorithm in C as an education exercise. I was ...

  1. #1
    Registered User
    Join Date
    Jun 2007
    Location
    Rome, NY
    Posts
    24

    Lightbulb addition modulo 2^32 with unsigned ints (integer constant too large)

    Hello all,

    I have recently started to implement the SHA-256 checksum algorithm in C as an education exercise. I was moving along quite well until I reached the point where I needed to perform addition modulo 2^32 on a number of 32-bit words.

    Basically, I am storing these 32-bit chunks and I need to perform this addition modulo 2^32 as stated in the specification.

    The code:
    Code:
    #define BOUND 0x100000000    /* 2^32 */
    
    unsigned int schedule[blocks][64];
    
    ...
    unsigned int temp = (F4(schedule[i][j-2]) + schedule[i][j-7]) % BOUND;
    temp = (temp + ((F3(schedule[i][j-15]) + schedule[i][j-16]) % BOUND)) % BOUND;
    
    schedule[i][j] = temp;
    The compiler prints the following warning for the code using the modulus operator:

    sha_256.c:246: warning: integer constant is too large for ‘long’ type

    F3 and F4 are functions defined by the specification which rotate and shift the bits of a 32-bit word. I know I am supposed to be storing this into 32-bits, but if I mod 2^32 apparently this won't work.

    Can someone help me see what I am not understanding with the specification and/or my code? I suppose theoretically I could be summing (2^32-1) or a similarly large number, but that would just cause problems when i store the value. I am not sure exactly why this is a problem.

    Thanks for looking!

    (hopefully I explained everything enough, if not, let me know as I am sure you will)

  2. #2
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Posts
    23,027
    2^32 is one number too large for a 32-bit integer to hold.
    Either you must use 2^32 - 1 or use a 64-bit integer.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  3. #3
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,185
    And more to the point, if you are using 32-bit unsigned integers, you are doing arithmetic modulo 2^32 anyway (since overflow of unsigned is guaranteed to work that way).

  4. #4
    Registered User
    Join Date
    Jun 2007
    Location
    Rome, NY
    Posts
    24
    Well, the following test program results in the same warning. Here I am storing the result of the modulus operation on an unsigned long long, which on my system is 64 bytes.

    Code:
    #include <stdio.h>
    #define BOUND 0x100000000  /* 2^32 */
    
    int main (int argc, char* argv[]) {
      unsigned long long temp = 256 &#37; BOUND;
    
      printf("sizeof(unsigned long long) = %d\n", sizeof(unsigned long long));
      printf("result: %lld\n", temp);
    
      return 0;
    }
    Now you can run that program fine apparently, but it still compiles with this damn warning.

    Code:
    [tja@Linux 17:55:49] ~/Programs/sha ]$ gcc -Wall -o test test.c
    test.c: In function ‘main’:
    test.c:5: warning: integer constant is too large for ‘long’ type
    [tja@Linux 17:56:58] ~/Programs/sha ]$ ./test
    sizeof(unsigned long long) = 8
    result: 256
    EDIT: tabstop, I think you hit the nail on the head. Wow, it seems I was lost in a storm of confusion. I see clearly now that simply summing the unsigned integers will give me my overflow and thus, addition modulo 2^32. While reading the specifications I took what they were saying quite literally. Thanks for the replies...its funny how you can overlook something simple like this.
    Last edited by BooBoo808; 05-31-2008 at 05:02 PM.

  5. #5
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,185
    The warning is coming from the fact that a "plain old number" in the text of your program must be an int, so the literal "0x100000000" in your code must be an int, but it doesn't fit. To force the compiler to treat it as a long long, you must make it "0x100000000LL". Of course, it doesn't matter here, since we don't need it anyway, but for future reference.

  6. #6
    Registered User
    Join Date
    Jun 2007
    Location
    Rome, NY
    Posts
    24
    Thanks for the replies though! However, I wish I would have realized what I was doing myself!

    EDIT: Good info! Thanks again!

  7. #7
    Registered User
    Join Date
    Oct 2001
    Posts
    2,129
    Code:
      unsigned long long temp = 256 % BOUND;
    
      printf("sizeof(unsigned long long) = %d\n", sizeof(unsigned long long));
      printf("result: %lld\n", temp);
    %lld is for signed long longs. Use %llu is for unsigned long longs.

    sizeof returns size_t. To print that in C99, use %zu. In C89, cast to unsigned long and use %lu.

    A postfix of ULL to integer literals makes an unsigned long long.

  8. #8
    Registered User
    Join Date
    Jun 2007
    Location
    Rome, NY
    Posts
    24
    Well, I actually got the program working after my blunders. Learned quite a bit in the process.

    At first I thought debugging the program was going to be a nightmare, but then one simple fix gave me the correct hash values. I had to use htonl() to force big-endian storage of the data.

    Thanks a lot for the tips though!

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Please STICKY this- vital to MSVC 6 dev - BASETSD.h
    By VirtualAce in forum Game Programming
    Replies: 11
    Last Post: 03-15-2005, 09:22 AM
  2. build errors migrated from dx9b to dx9c sdk
    By reanimated in forum Game Programming
    Replies: 4
    Last Post: 12-17-2004, 07:35 AM
  3. Writing structure in a unsigned char array
    By nasir_sidd in forum C++ Programming
    Replies: 1
    Last Post: 12-10-2002, 04:09 AM
  4. Color Variety
    By Unregistered in forum C++ Programming
    Replies: 7
    Last Post: 10-23-2002, 10:17 AM
  5. can someone check this out and let me know ?
    By javaz in forum C Programming
    Replies: 5
    Last Post: 01-21-2002, 02:13 PM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21