Newbie problems learning C++

Posted by Ready on Wed 09 Jun 2004 04:17 PM — 10 posts, 37,848 views.

#0
Hi i've only just started learning C++ and i've already come up against a problem. While learning about identifiers i've noticed on the site im learning from that it mentions ranges. being signed and unsigned.
I am 100% new and I'm not quite sure what it means by this or even what it means by range could someone enlighten me please?
USA #1
In a nutshell, signed and unsigned ONLY apply to numeric identifiers (ie, int or long). Signed identifiers can be negative and used for normal math functions. Unsigned identifiers are only positive and have somewhat obvious implication for math functions (try subtracting with unsigned ints sometime :P). Unsigned is typically used when you need more positive number range than signed would give you but you dont want as much range as the next larger identifier type would give you - or if you already use the largest identifier and its still not quite big enough.


--example because this is confusing to read--
short -32k to 32k
unsigned short 0 to 64k
Amended on Wed 09 Jun 2004 05:59 PM by Meerclar
USA #2
Another very important use for an unsigned integer is to signify that whatever you are dealing with is only ever positive. This is important for instance for sizes and lengths - size and length (of structures, strings, whatever) can never be negative so making it unsigned is how you enforce that. Of course, somebody can still screw up and subtract something pushing your number into the negative i.e. some incredibly huge number. For instance, with an unsigned short if you did 0 - 1 you will obtain something around 64k. (If you care about the exact value, it is 2^16 - 1 = 65535)
Amended on Wed 09 Jun 2004 09:48 PM by Nick Gammon
Australia Forum Administrator #3
Quote:

... try subtracting with unsigned ints sometime ...


You can subtract, you just can't get a negative result. This will be OK:


unsigned int i = 20;
unsigned int j;

j = i - 10;


However subtract more, and you get something like this:


#include <stdio.h>
int main (void)
  {

  unsigned int i = 20;
  unsigned int j;

  j = i - 30;

  printf ("j = %u.\n", j);

  return 0;
  }


Compiling this and testing it gives:


j = 4294967286.


Probably not what you are expecting. :)
USA #4
Although it doesnt really matter except it might save a little typing, generally if you use unsigned then the int is implied unless you specify otherwise. Thus:

unsigned int x;

and

unsigned x;

are exactly the same. Also, for thoughts on how this might be applicable to muds is vnums. I still wonder why vnums were put as int (and sh_int in many cases) when none of the rooms were supposed to be negative. In the ZMP codebase (http://www.sourceforge.net/projects/zmp) I used an unsigned simply because I don't want my room numbers going negative, ever. Also, the reason I didnt use something bigger like a long is because the world will be small since it is geared totally around the Zoids and their teams.

Just some thoughts for you. :)
USA #5
Easy: -1 is a very convenient way of representing an invalid vnum, whereas with an unsigned int you often have the problem of what to use as "invalid vnum". Do you use 0, or the maximum value? Either way you're removing a potentially valid vnum.

Of course my solution to this problem was to make the vnum no longer a number but a C++ structure with methods and an internal field to test validity... :-)
#6
So let me get this straight.....


Signed intergers are used for mathmatical equations etc, but cos they go into the minus their largest positive number is quite small.
so....
Unsigned intergers are used when its not a mthmaticall equation etc. as then you can have a higher positive number like with vnums.

Am I getting this?

Then what Ksilyan is saying is that with Muds you need high Vnums and so need unsigned intergers, but then when you set an invalid vnum you would be using up a perfectly good vnum and so he made the vnum a C++ structure to get around this.

Forgive me for going over it again but I'm new and I just want to make sure I get everything right.
#7
Also just to make sure data types are used to store your variables, and they tell your computer what to store the variables as. Right?
USA #8
Quote:
Signed intergers are used for mathmatical equations etc, but cos they go into the minus their largest positive number is quite small.

Well, "small" is relative - with a signed 32 bit integer the range is roughly -2^31 to 2^31, i.e. more or less -2,147,483,648 to 2,147,483,648 (I am most likely one or two off, can't be bothered). So yes, small is relative; 2 *billion* in either direction really isn't that small for vnums!

I don't think you really need unsigned integers for vnums, unless of course you're planning on having more than 2 billion rooms (uh-huh :P). There seems to be this myth about how integers are "small" but mostly that's because people don't understand how it all works.

Quote:
Then what Ksilyan is saying is that with Muds you need high Vnums and so need unsigned intergers, but then when you set an invalid vnum you would be using up a perfectly good vnum and so he made the vnum a C++ structure to get around this.

No, that's not what I said... You don't need vnums *that* high. If you're using 16-bit shorts, then yes, you do; but if you're actually using integers, leaving the sign bit is fine and in fact very convenient for representing invalid vnums (-1).

The C++ structure I made was out of convenience, a somewhat "cleaner" version of the vnum. My vnums are two-piece, "unsigned short.unsigned short", with a third field (bool) to indicate "valid" or not. The idea is to make the notion of valid independent of the value, and to make programming with them easier and more convenient. Also, having a struct like this also helps a great deal in ensuring type safety (e.g. you can only assign vnums to vnums, you can only compare vnums, etc.), which C++ is much better at than C.

Quote:
Also just to make sure data types are used to store your variables, and they tell your computer what to store the variables as. Right?

I guess that's one way of putting it. I would prefer saying that they tell the program what is contained in the variable, e.g. a c-style struct has a grouping of fields, a class has variables and methods, etc.
Australia Forum Administrator #9
Quote:

Signed intergers are used for mathmatical equations etc, but cos they go into the minus their largest positive number is quite small.


No, their largest positive number is not "quite small" it is simply 1/2 of what you can store in an unsigned number, because you have used one bit for the sign. You can see the differences if you look in the file limits.h:

  • INT_MIN

    Minimum value for a variable of type int. –2147483648
  • INT_MAX

    Maximum value for a variable of type int. 2147483647
  • UINT_MAX

    Maximum value for a variable of type unsigned int. 4294967295 (0xffffffff)


Notice how the maximum value for unsigned int is twice the value for a signed int? That is because one of the 32 bits used to store the number is used to show if it is negative or not. However I would not say that 2147483647 is "quite small".

Whether or not you use the numbers for maths really depends on the application. For instance, you probably don't carry -3 swords on you, however banks normally show a balance you owe to them as negative. eg. if you have -$200 on your bank statement it means you owe them $200.

As for "wasting a vnum" by using unsigned ints you are throwing away a possible 2147483647 vnums (all the negative ones) just so you can use -1 to represent an invalid vnum. Seems a bigger waste to me to have 2147483647 that you cannot use, rather than using (say) 0 as an invalid vnum. That is only "wasting" one of them.

However unless you are planning to have 2,147,483,647 (over 2 billion) rooms, then it is pretty academic.