473,809 Members | 2,712 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

When you need an integral type. . .


When you simply want to store a number, what integral type do you use?

For instance, let's say we have the following in a Poker game:

struct Card
{
enum Suit { Hearts, Diamonds, Spades, Clubs } suit;

int value;
};
Looking at the "value" variable above, it's range needs to be 0 to 51.

How many people would use an "int"? How many people would use an
"unsigned char"?

Upon first thought, I would presume that the most appropriate choice
would be "unsigned char", as the number shall always be positive, and it
has sufficient range.

I myself always use unsigned integral types unless I strictly need a
signed type. For instance:

unsigned GetDaysInMonth( unsigned month );

Nonetheless, I see that a lot of people use "int" everywhere, even when
the number shouldn't ever be negative.

Is it too pedantic to use an "unsigned char" to store the card's numeric
value? If so why?

Basically, what makes you choose a particular integral type?

Lastly, do you ever use an enum to get the desired range, as in:

enum CardValue { Ace = 1, King = 13 };
-Tomás
Mar 27 '06 #1
10 2906
Tomás wrote:
When you simply want to store a number, what integral type do you use?

For instance, let's say we have the following in a Poker game:

struct Card
{
enum Suit { Hearts, Diamonds, Spades, Clubs } suit;

int value;
};
Looking at the "value" variable above, it's range needs to be 0 to 51.
Make it an 'int'. Make sure your program is easy to change. If you ever
encounter a reason to change the int, you might then observe these
rationales:

- CPUs often - but not always - process ints faster than smaller things

- an 'enum' will be slightly more typesafe, and will only contain
enough bits to count to 51.
Is it too pedantic to use an "unsigned char" to store the card's numeric
value? If so why?
If you feel like writing that, write it. Then make sure you can change it in
the future. Software design is not about carving marble.
Basically, what makes you choose a particular integral type?
The less I have to think about such low-level things, the more energy I can
devote to a program's structure and behavior.

C++ is a high-level language with low-level modes that are available when
you need.
Lastly, do you ever use an enum to get the desired range, as in:

enum CardValue { Ace = 1, King = 13 };


For most card games, the names of the cards are just that - names. The Queen
doesn't run the palace while the King's away, or whatever real Queens and
Kings do. So the name "Queen", the picture, and such, should be attributes
of an array at index 12.

Your system, however, doesn't allow CardValue to be typesafe for any cards
besides Ace and King.

--
Phlip
http://www.greencheese.org/ZeekLand <-- NOT a blog!!!
Mar 27 '06 #2
In article <7i************ ******@news.ind igo.ie>,
"Tomás" <NU**@NULL.NULL > wrote:
When you simply want to store a number, what integral type do you use?

For instance, let's say we have the following in a Poker game:

struct Card
{
enum Suit { Hearts, Diamonds, Spades, Clubs } suit;

int value;
};
Looking at the "value" variable above, it's range needs to be 0 to 51.

How many people would use an "int"? How many people would use an
"unsigned char"?

Upon first thought, I would presume that the most appropriate choice
would be "unsigned char", as the number shall always be positive, and it
has sufficient range.

I myself always use unsigned integral types unless I strictly need a
signed type. For instance:

unsigned GetDaysInMonth( unsigned month );

Nonetheless, I see that a lot of people use "int" everywhere, even when
the number shouldn't ever be negative.

Is it too pedantic to use an "unsigned char" to store the card's numeric
value? If so why?
First, the pros disagree as to whether using unsigned types just because
"it will never be less than 0" is a good idea. For example, the FAQ
says: "It's probably a good idea to use unsigned integers for variables
that are always >= 0... The main reason for this is it requires less
code, at least if you are careful to check your ranges." whereas
Stroustrup says: "Attempts to ensure that some values are positive by
declaring variables unsigned will typically be defeated by the implicit
conversion rules."

When the pro's don't agree, it's probably a religious issue, like brace
placement. That said, I use 'int' unless I specifically need another
type. If I remember right, the size of int is decreed by the standard to
be the "most natural" type for the system, ie likely the fastest.
Basically, what makes you choose a particular integral type?
If int doesn't cut it, I change to a type that does.
Lastly, do you ever use an enum to get the desired range, as in:

enum CardValue { Ace = 1, King = 13 };


No. Although I have been known to create a class that holds an int but
doesn't allow that int to equal certain values.
--
Magic depends on tradition and belief. It does not welcome observation,
nor does it profit by experiment. On the other hand, science is based
on experience; it is open to correction by observation and experiment.
Mar 27 '06 #3

Tomás wrote:
When you simply want to store a number, what integral type do you use?

For instance, let's say we have the following in a Poker game:

struct Card
{
enum Suit { Hearts, Diamonds, Spades, Clubs } suit;

int value;
};
Looking at the "value" variable above, it's range needs to be 0 to 51.

How many people would use an "int"? How many people would use an
"unsigned char"?

Upon first thought, I would presume that the most appropriate choice
would be "unsigned char", as the number shall always be positive, and it
has sufficient range.

<snip>

Apologies for asking such a basic point but will it not be better to
use a bit field in this case ? If the range is going to stay 51 or lets
say someone invents a new card game which uses a pack of 2 cards, isn't
using a bit field going to be better than using a char or an unsigned
int ?

Again apologies for being slightly OT but just had this query in mind.
Hope the experts won't mind asking such a basic query.

Mar 28 '06 #4
First choice int, second choice char. Don't use the unsigned version.

It is idiomatic.

Opalinski
op****@gmail.co m
http://www.geocities.com/opalpaweb/

Mar 28 '06 #5
Me
Tomás wrote:
When you simply want to store a number, what integral type do you use?
A lot of it is context dependent. If I need to store an array index,
it's always size_t, if I need to store a coordinate it will be
typedeffed to whatever the graphics library I use picks, etc. If it
doesn't matter (as long as the minimum guaranteed range fits), I'll
stick with unsigned int unless I really need negative integers. If I
*really* care about packing, I'll consider the smaller types.
For instance, let's say we have the following in a Poker game:

struct Card
{
enum Suit { Hearts, Diamonds, Spades, Clubs } suit;

int value;
};
Looking at the "value" variable above, it's range needs to be 0 to 51.
To me, it looks like the range needs to be 0 to 12.
How many people would use an "int"? How many people would use an
"unsigned char"?
I would use an unsigned int and get rid of the suit variable since you
can calculate it with the / operator. I might also consider adding
sentinel values because they come in handy sometimes.
Upon first thought, I would presume that the most appropriate choice
would be "unsigned char", as the number shall always be positive, and it
has sufficient range.

I myself always use unsigned integral types unless I strictly need a
signed type. For instance:

unsigned GetDaysInMonth( unsigned month );
Sounds like something I would do. But this is just working around the
fact that C++ sucks. If the constexpr proposal is accepted, it will
finally let you add an integer to an enum and return the enum **but
have it work at compile time if you feed it integral constant
expressions**.
Nonetheless, I see that a lot of people use "int" everywhere, even when
the number shouldn't ever be negative.
But of these examples:
- how many of the programmers would you consider expert worthy?
- how would this code fair on non-nice platforms like the DS9000?
- is this code defensive against (theoretical) changes by the C/C++
standards committee, non-standards conforming compilers, or weird
compiler extensions? For example if they decide change the value
preserving promotion rules to unsigned preserving.
- how localized is this? If it only affects (lets say) 2 functions,
then you're seeing a good programmer at work. But if it affects a much
larger amount of code (worst being if it affects more than 1
translation unit), this programmer either is ignorant or lazy.

Even C is guilty of this kind of stupidity. As the standard evolved:

- you have strcpy which copies the string as an unsigned char, but 0 as
a plain char is allowed to have more than one object representation on
certain platforms. Whoops.
- some functions return (unsigned) char converted to int, what if
(unsigned) char's range is larger? Whoops.
- etc.
Is it too pedantic to use an "unsigned char" to store the card's numeric
value? If so why? Basically, what makes you choose a particular integral type?
For this example, I'd either use unsigned char or unsigned int
depending on how I'm feeling that day (and today, I'm in an unsigned
int kind of mood). The biggest drawback of using unsigned char is that
the character types are the magic "alias all type", so if you use a
pointer or reference of a character type, the compiler has to work
harder to prove it doesn't alias other variables or else you end up
with poorer code generated.
Lastly, do you ever use an enum to get the desired range, as in:

enum CardValue { Ace = 1, King = 13 };


Sometimes, but locally. I find it's much better to use member functions
that calculates this stuff because you can change the implementation
later on without affecting much code. But like I said above, C++ would
be much better with something like constexpr so the main problem with
the above approach gets eliminated.

Mar 28 '06 #6
On Mon, 27 Mar 2006 20:54:27 GMT, "Tomás" <NU**@NULL.NULL > wrote:

When you simply want to store a number, what integral type do you use?

For instance, let's say we have the following in a Poker game:

struct Card
{
enum Suit { Hearts, Diamonds, Spades, Clubs } suit;

int value;
};
Looking at the "value" variable above, it's range needs to be 0 to 51.

<...>

I would use:

struct Card {
enum Suite { Hearts, Diamonds, Spades Clubs } suite;
enum FaceValue {Ace=1, Jack=11, Queen=12, King=13 } faceValue;
int value {return (faceValue-Ace)+(King*suit e);}
};

Or shouldn't I?

Zara
Mar 28 '06 #7

Tomás wrote:
When you simply want to store a number, what integral type do you use?
int
For instance, let's say we have the following in a Poker game:

struct Card
{
enum Suit { Hearts, Diamonds, Spades, Clubs } suit;
That can be just
enum Suit { Hearts, Diamonds, Spades, Clubs };

int value;
};
Looking at the "value" variable above, it's range needs to be 0 to 51.
Not 0 to 12?
How many people would use an "int"? How many people would use an
"unsigned char"?
I wouldn't use unsigned char. I wouldn't use unsigned anything.
Upon first thought, I would presume that the most appropriate choice
would be "unsigned char", as the number shall always be positive, and it
has sufficient range.
Personally, the question of "what's the smallest type I can get away
with" wouldn't even occur to me until I'd proved there was a memory
problem. But if using the smallest type possible is your goal, then a
char type is the most appropriate. Presumably you're using the smallest
type possible because you want to minimise memory footprint and you
don't mind if execution speed is compromised. And memory footprint must
be a serious enough concern that you're prepared to go away from the
idiomatic natural type.

I don't know why you would use unsigned just because the number shall
always be positive. That's by no means universally accepted as good
practice. What do you think it gains you? If you write the code
correctly, you can use a signed type and no negative values will end up
stored in it. If you write a bug in the code that tries to store a
negative number, using an unsigned type won't always protect you.
I myself always use unsigned integral types unless I strictly need a
signed type. For instance:

unsigned GetDaysInMonth( unsigned month );

Nonetheless, I see that a lot of people use "int" everywhere, even when
the number shouldn't ever be negative.
Because unsigned types do not protect both ends of the range. They
sometimes protect the bottom end of the range and offer no protection
at the top end of the range. I never need that sort of incomplete
protection. If I need to police the values at all, I need to police
them properly. So I'll use a different technique. Your Suit enum above
is a simple example. Why did you choose an enum for that instead of an
unsigned char that holds the values 0, 1, 2 and 3? There's also the
problem that unsigned arithmetic doesn't do what you expect if you
subtract the number of days in March from the number of days in
February.
Is it too pedantic to use an "unsigned char" to store the card's numeric
value? If so why?
I think so, for the reasons above. YMMV.
Basically, what makes you choose a particular integral type?
int unless and until I have either:
proof that memory usage is unacceptable, in which case I'd use a
smaller type, or
proof that the values I'm using don't fit inside int, in which case
I'd use long.

usinged only for bit twiddling.
Lastly, do you ever use an enum to get the desired range, as in:

enum CardValue { Ace = 1, King = 13 };


If you just need the min and max values, I wouldn't use an enum,
because you aren't enumerating anything. Simply define two constants.

const int MinimumCardValu e = 1;
const int MaximumCardValu e = 13;

Gavin Deane

Mar 28 '06 #8
Geo

Tomás wrote:
When you simply want to store a number, what integral type do you use?

For instance, let's say we have the following in a Poker game:

struct Card
{
enum Suit { Hearts, Diamonds, Spades, Clubs } suit;

int value;
};
Looking at the "value" variable above, it's range needs to be 0 to 51.

How many people would use an "int"? How many people would use an
"unsigned char"?

Upon first thought, I would presume that the most appropriate choice
would be "unsigned char", as the number shall always be positive, and it
has sufficient range.

I myself always use unsigned integral types unless I strictly need a
signed type. For instance:

unsigned GetDaysInMonth( unsigned month );

Nonetheless, I see that a lot of people use "int" everywhere, even when
the number shouldn't ever be negative.

Is it too pedantic to use an "unsigned char" to store the card's numeric
value? If so why?

Basically, what makes you choose a particular integral type?

Lastly, do you ever use an enum to get the desired range, as in:

enum CardValue { Ace = 1, King = 13 };
-Tomás


If you feel you need this level of type safety, perhaps you should
consider writting it in Ada :)

Mar 28 '06 #9

"Daniel T." <po********@ver izon.net> skrev i meddelandet
news:po******** *************** *******@news.ve rizon.net...
In article <7i************ ******@news.ind igo.ie>,
"Tomás" <NU**@NULL.NULL > wrote:
When you simply want to store a number, what integral type do you
use?

For instance, let's say we have the following in a Poker game:

struct Card
{
enum Suit { Hearts, Diamonds, Spades, Clubs } suit;

int value;
};
Looking at the "value" variable above, it's range needs to be 0 to
51.

How many people would use an "int"? How many people would use an
"unsigned char"?

Upon first thought, I would presume that the most appropriate
choice
would be "unsigned char", as the number shall always be positive,
and it
has sufficient range.

I myself always use unsigned integral types unless I strictly need
a
signed type. For instance:

unsigned GetDaysInMonth( unsigned month );

Nonetheless, I see that a lot of people use "int" everywhere, even
when
the number shouldn't ever be negative.

Is it too pedantic to use an "unsigned char" to store the card's
numeric
value? If so why?
First, the pros disagree as to whether using unsigned types just
because
"it will never be less than 0" is a good idea. For example, the FAQ
says: "It's probably a good idea to use unsigned integers for
variables
that are always >= 0... The main reason for this is it requires less
code, at least if you are careful to check your ranges." whereas
Stroustrup says: "Attempts to ensure that some values are positive
by
declaring variables unsigned will typically be defeated by the
implicit
conversion rules."


The problem is that nothing stops you from assigning a negative value
to an unsigned variable. Then what?!

When the pro's don't agree, it's probably a religious issue, like
brace
placement. That said, I use 'int' unless I specifically need another
type. If I remember right, the size of int is decreed by the
standard to
be the "most natural" type for the system, ie likely the fastest.


Right. If you don't have some *very* specific requirements, an int
will do.

And who says that speed is important here? Or space? :-)
Bo Persson
Mar 28 '06 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

3
6247
by: Dave | last post by:
Hello all, Suppose you have an unsigned integral type T. It's not one of the built-in types, but rather typedefed off of one of the built-in unsigned integral types (but we don't know which one). I want to find the maximum value for this type. This seems to work just fine: static_cast<T>(-1)
10
2277
by: Niels Dekker (no reply address) | last post by:
Is it possible for a standard compliant C++ compiler to have ( sizeof(short) < sizeof(int) ) and ( sizeof(short) == sizeof((short)0 + (short)0) ) ? Regards, Niels Dekker http://www.xs4all.nl/~nd/dekkerware
14
2875
by: Mike Hewson | last post by:
Have been researching as to why: <example 1> class ABC { static const float some_float = 3.3f; }; <end example 1>
36
2913
by: Song Yun Zhao | last post by:
Hi, Just wondering what are the dis/advantages of using uint vs int. When would be the best time to use it? Personally I don't use uint that much, but I like to optimize my code and make it as effective as possible. So I feel that using an int where only an uint is needed is a waste. e.g. something like (int i = 0; i < 100; i++)
9
4961
by: Fred Ma | last post by:
Hello, I've been trying to clear up a confusion about integer promotions during expression evaluation. I've checked the C FAQ and C++ FAQ (they are different languages, but I was hoping one would clear up the confusion), as well as googling groups and the web. The confusion is that for a binary operator,
16
5157
by: TTroy | last post by:
Hello, I'm relatively new to C and have gone through more than 4 books on it. None mentioned anything about integral promotion, arithmetic conversion, value preserving and unsigned preserving. And K&R2 mentions "signed extension" everywhere. Reading some old clc posts, I've beginning to realize that these books are over-generalizing the topic. I am just wondering what the difference between the following pairs of terms are: 1)...
18
1760
by: Susan Rice | last post by:
I'm comparing characters via return(str1 - str2); and I'm having problems with 8-bit characters being treated as signed instead of unsigned integers. The disassembly is using movsx eax,byte ptr to load my character in to EAX register. I need it to use movzx.
1
2847
by: Neelesh Bodas | last post by:
Can somebody please explain the fine difference between these two clauses of the standard: 4.5 (Integral promotions) 4. An rvalue of type bool can be converted to an rvalue of type int, with false becoming zero and true becoming one 4.7 (Integral conversions) 4. If the source type is bool, the value false is converted to zero
18
1471
by: William Ahern | last post by:
I'm writing an unpack function which uses "c", "h", "l", "q" format tokens to specify the type of the integral object pointer. To support fixed-width types, a la <stdint.h>, another format specifier, "i", can be prefixed with the width--8, 16, 32, 64, etc. Then, a jump table is used to branch to the native type conversion based on the size of the native type. (This is distinct from specifying the number of input bits to consume in the...
0
9601
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
10635
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
10115
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
1
7653
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
5550
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
5687
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
4332
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
3861
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
3013
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.