Thread: Using unsigned int troubles

  1. #1
    Registered User
    Join Date
    Jul 2012
    Posts
    87

    Using unsigned int troubles

    I'm trying to build simple open addressing via linear probing hash tables where I store phone numbers for keys of string names. I am using a tested and tried string hash function called FNV. I'm using g++ compiler that came with CodeBlocks IDE and when I compile, it complains w/ this message:warning: this decimal constant is unsigned only in ISO C90

    Code:
    unsigned fnv_hash ( string key, int len )
    {
       unsigned h = 2166136261;
       int i;
     
       for ( i = 0; i < len; i++ )
         h = ( h * 16777619 ) ^ key[i];
     
       return h;
    }
    
    int main()
    {
       int phonebook_1[10] = {0,0,0,0,0,0,0,0,0,0};//always initialize size since specific compilers say its ok so don't get comfy w/ bad practices
        
        int size_1 = 10;
        
        string name_1 = "Cooke";
    
       int bucket = fnv_hash ( name_1, size_1 );
       
       phonebook_1[bucket] = 1234567;
    
      return 0;
    }

    Here is the src: Eternally Confuzzled - The Art of Hashing

    BTW: when I type in g++ -v, it shows the gcc version:
    gcc version 4.4.1 (TDM-2 mingw32)
    Last edited by monkey_c_monkey; 07-10-2012 at 08:40 PM.

  2. #2
    Registered User
    Join Date
    May 2009
    Posts
    4,183
    To get rid of the warning change this line.
    Code:
    unsigned h = 2166136261;
    To
    Code:
    unsigned h = 2166136261U;
    An integer constant ending with L mean long int
    UL means Unsigned Long Int
    U seems to mean Unsigned Int. (I never used just an U, before)

    ULL can mean Unsigned Long Long; but it might not be supported on all Compilers and I am not sure if it is standard.

    Tim S.
    "...a computer is a stupid machine with the ability to do incredibly smart things, while computer programmers are smart people with the ability to do incredibly stupid things. They are,in short, a perfect match.." Bill Bryson

  3. #3
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by stahta01
    ULL can mean Unsigned Long Long; but it might not be supported on all Compilers and I am not sure if it is standard.
    It is standard, but unlikely to be supported by all compilers at this time.

    Of course, don't forget LL, which is also standard but unlikely to be supported by all compilers at this time. It stands for "laserlight". I mean "long long".
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  4. #4
    Registered User
    Join Date
    Jul 2012
    Posts
    87
    This might sound trivial, but if a value is unsigned, does that mean it can represent 2^32 distinct binary values which is: 4,294,967,296 so why does the compiler complain. The suffix of 'U' to add on works btw, thanks for that, and does compiler complain b/c 2166136261 in binary exceeds 32 bits?

  5. #5
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,612
    The reason suffixes exist is so that numerical expressions can be the right type. This is just a rationalization, but there is no way to tell a big signed integer expression from an unsigned one without the suffix. It's also a good heuristic that you can use to point out mistakes: If the type of the expression will be signed, huge numbers will overflow the type, and the behavior is implementation defined for signed numbers. Along with other logical errors.

    The compiler just wants you to be careful and it's a good thing.

  6. #6
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by monkey_c_monkey View Post
    This might sound trivial, but if a value is unsigned, does that mean it can represent 2^32 distinct binary values which is: 4,294,967,296 so why does the compiler complain. The suffix of 'U' to add on works btw, thanks for that, and does compiler complain b/c 2166136261 in binary exceeds 32 bits?
    You need to understand that a number can either be signed or unsigned. Regardless of choice, a 32-bit variable can hold 2^32 distinct values. That's just basic algebra.
    The problem is that when we want signed numbers, we must reserve one bit for the sign, essentially. So the "range" of the variable will be "halved."
    So, when you type 2166136261, which is 811C 9DC5 in hex, the compiler sees that it cannot be represented by 31 bits (the largest number would be 8000 0000 - 1).
    The compiler does not know whether this is a 63-bit number or an unsigned 32-bit number. You have to tell the compiler whether you meant an unsigned 32-bit number (uses 32 bits to store the number) or a signed 64-bit number (uses 63 bits to store the number, plus 1 for the sign).
    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.

  7. #7
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Quote Originally Posted by Elysia View Post
    Regardless of choice, a 32-bit variable can hold 2^32 distinct values. That's just basic algebra.
    What you say is true for most 32 bit integral types (signed or unsigned) but is not true for all 32-bit types.

    The algebra actually says that a 32-bit variable can hold at most 2^32 distinct values. Consider the fact that some 32 bit floating point representations (a typical float type in cases where sizeof(float) is 4) reserve some bits to represent NaN (not a number), infinities, and some error conditions. Struct types that have a 32 bit representation (for example, a struct that contains small number of char or short variables) may have padding.

    Admittedly, I've yet to see a 32-bit integral type, whether signed or unsigned, that does not use all 32 bits to represent values.
    Quote Originally Posted by Elysia View Post
    The problem is that when we want signed numbers, we must reserve one bit for the sign, essentially. So the "range" of the variable will be "halved."
    That depends on what you mean by "range". If you mean that std::numeric_limits<int>::max() is approximately std::numeric_limits<unsigned>::max()/2 then you are correct.

    However, "range" usually refers to something representative of an interval from (in this context) a minimum value to a maximum value of a type. For example, the range of a type might be represented as the difference between maximum and minimum value. Mathematically, the range of a 32-bit signed type will be equal to the range of a 32-bit unsigned type (assuming no reserved bits, etc in the representations).
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  8. #8
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    What I mean, is simply that a number is that 32 bits long can hold 2^32 different combinations. Now, computers interpret these different combinations differently, sometimes even treating two different combinations as the same thing (+/- 0).
    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.

  9. #9
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,612
    Find me any integer that has an ambiguous bit pattern. I don't think it can be done.

    Zero is not an example. All representations of negative numbers reserve a pattern for zero; in two's complement it is all bits 0. In fact if you start with 0U and do
    ~0U + 1 (the normal way of doing it in two's complement)
    you get all bits 0 again because the sum wraps around.

  10. #10
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Now that you say it, it might be difficult in two's complement, but not one's complement.
    Well, let's just say that it isn't a requirement that all unique combinations of the binary representation must map to a unique number representation.
    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.

  11. #11
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,612
    I guess that's what I wanted you to say.
    (-0) should not even be a number, but in ones' complement it is, and it certainly isn't the same number.

  12. #12
    Registered User
    Join Date
    Jul 2012
    Posts
    87
    but there is no way to tell a big signed integer expression from an unsigned one without the suffix.
    quote from whiteflags.

    But if I use unsigned h, isn't that enough of a clue to tell compiler I am working w/ unsigned, so I'm still not getting the purpose of including suffix U.

  13. #13
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Yes, and no.
    It tells the compiler that the type of your variable is unsigned int, but it tells the compiler nothing about the type of your number. Some compilers, however, are smart enough to figure it out by themselves.
    Nevertheless, if you don't use proper suffixes, you may find that the code does not do what you want.
    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.

  14. #14
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,612
    But if I use unsigned h, isn't that enough of a clue to tell compiler I am working w/ unsigned, so I'm still not getting the purpose of including suffix U.
    No it really isn't. Declaring unsigned h means that the resulting type of the variable will be unsigned. The compiler is free to do an implicit conversion from signed to unsigned. If you want to avoid that, use suffixes. You should want to avoid implicit conversions anyway.
    Last edited by whiteflags; 07-12-2012 at 04:07 PM.

  15. #15
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Ah yes, prime example:
    float f = 1 / 2;
    What is the result?
    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.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. unsigned int and unsigned long
    By codewriter in forum C Programming
    Replies: 16
    Last Post: 03-22-2012, 02:24 PM
  2. Replies: 2
    Last Post: 10-06-2009, 09:37 AM
  3. Converting unsigned long array to unsigned char array
    By delvec28 in forum C Programming
    Replies: 2
    Last Post: 09-07-2009, 08:53 PM
  4. unsigned int and unsigned long int
    By -EquinoX- in forum C Programming
    Replies: 43
    Last Post: 03-05-2008, 05:17 PM
  5. Replies: 7
    Last Post: 02-08-2008, 06:31 PM