views:

146

answers:

4

In C++ we can make primitives unsigned. But they are always positive. Is there also a way to make unsigned negative variables? I know the word unsigned means "without sign", so also not a minus (-) sign. But I think C++ must provide it.

+3  A: 

No. unsigned can only contain nonnegative numbers.

If you need a type that only represent negative numbers, you need to write a class yourself, or just interpret the value as negative in your program.

(But why do you need such a type?)

KennyTM
So, if I really want this, I will need to create my own class and do some operator overloading to simulate a negative number?
Martijn Courteaux
@KennyTM: If I want to use as less as possible memory.
Martijn Courteaux
@Martijn: It sounds like premature optimization. How many such numbers you need? What's the range of those numbers?
KennyTM
@Martijn Signed and unsigned numbers are the same size; it's just the range of possible values that changes
Michael Mrozek
@Martijn: A signed number uses *a single bit* to represent sign. A single bit is not going to make or break memory usage.
Thanatos
Martijin you should use signed numbers with some asserts to check their negativity.
Klaim
@Martijn: You won't save any memory at all doing this.
DeadMG
+2  A: 

unsigned integers are only positive. From 3.9.1 paragraph 3 of the 2003 C++ standard:

The range of nonnegative values of a signed integer type is a subrange of the corresponding unsigned integer type, and the value representation of each corresponding signed/unsigned type shall be the same.

The main purpose of the unsigned integer types is to support modulo arithmetic. From 3.9.1 paragraph 4:

Unsigned integers, declared unsigned, shall obey the laws of arithmetic modulo 2n where n is the number of bits in the value representation of that particular size of integer.

You are free, of course, to treat them as negative if you wish, you'll just have to keep track of that yourself somehow (perhaps with a Boolean flag).

Brian Neal
A: 

I think you are thinking it the wrong way.

If you want a negative number, then you must not declare the variable as unsigned.

If your problem is the value range, and you want that one more bit, then you could use a "bigger" data type (int 64 for example...).

Then if you are using legacy code, creating a new struct can solve your problem, but this is that way because of your specific situation, C++ shouldn't handle it.

Diego Pereyra
A: 

Don't be fooled by the name: unsigned is often misunderstood as non-negative, but the rules for the language are different... probably a better name would have been "bitmask" or "modulo_integer".

If you think that unsigned is non-negative then for example implicit conversion rules are total nonsense (why a difference between two non-negative should be a non-negative ? why the addition of a non-negative and an integer should be non-negative ?).

It's very unfortunate that C++ standard library itself fell in that misunderstanding because for example vector.size() is unsigned (absurd if you mean it as the language itself does in terms of bitmask or modulo_integer). This choice for sizes has more to do with the old 16-bit times than with unsigned-ness and it was in my opinion a terrible choice that we're still paying as bugs.

6502
What benefit does making vector.size() signed give? It can never return a negative value. Exactly what bugs arise because of signed/unsigned? It's a pretty simple concept to deal with.
DeadMG
The most common bug I observed is iterating from 0 to vector.size()-1 that for an empty vector is a huge number.Other possible bugs arise from the fact that a - b > 0 is not the same as a > b.Note that all this happens because unsigned for C++ means more or less "element of Z[n]" (Z[n] = integers modulo n) and has nothing to do with the sign. In your opinion does make sense that the number of elements in a vector is an element of that ring ?Unsigned ints are IMO indeed very useful... but NOT as quantities.
6502