C# Numeric Types - byte, sbyte, short, ushort, int, uint, long, ulong
By Stephen Armstrong // November 11, 2019
An overview of numeric types and how they can be used.
Depending on your requirements and memory concerns, you can choose from various numeric types to store numbers in C#.
The following table displays numeric types, their size, and their minimum and maximum values.
If you are unfamiliar with the term, “signed” means the number can be a negative value and “unsigned” only accepts zero or positive values.
Type | Size | Minimum Value | Maximum Value |
---|---|---|---|
sbyte | 8-bit (signed) | -128 | 127 |
byte | 8-bit (unsigned) | 0 | 255 |
short | 16-bit (signed) | -32768 | 32767 |
ushort | 16-bit (unsigned) | 0 | 65535 |
int | 32-bit (signed) | -2147483648 | 2147483647 |
uint | 32-bit (unsigned) | 0 | 4294967295 |
long | 64-bit (signed) | -9223372036854775808 | 9223372036854775807 |
ulong | 64-bit (unsigned) | 0 | 18446744073709551615 |
Below is a quick overview of each type.
sbyte/byte
If you’ve ever played an old-school Japanese RPG and wondered why the character attributes have a maximum value of 255 then wonder no more – the developers stored those values as bytes.
These are 8-bit values, making them the smallest type available.
If you are creating a game with a huge number of characters and/or attributes, and you are worried about the impact on memory, then consider using them.
short/ushort
This type supports enough values to cover common in-game variables such as health, player level, and damage.
However, as games get bigger and more “epic”, then these values may be better represented with values into the hundreds of thousands if not millions. In that case I would use int.
int/uint
Int will probably be the most common type that you use in your game. Its minimum and maximum values should be more than enough to contain every in-game variable (such as health, damage, and high scores).
long/ulong
This is by far the largest type and to be honest it’s overkill for most games.
To put the maximum long value into context, 9223372036854775807 milliseconds equals more than 292471208 years.
Errors and overflow
If you attempt to create one of these types that exceeds their respective minimum/maximum values, you will receive an error.
However, if during your game you add/subtract from a type and this causes the value to exceed the minimum/maximum, then the value will loop.
For example: an int with the value of 2147483647 will become -2147483647 if you add 1, and a byte with the value of 0 will become 246 if you subtract 10.
This looping is called “overflow”.
Avoiding overflow
My recommendation for avoiding overflow is quite simple: choose a number type with a large value range and set your own limits.
A good example of this is player health:
// Current health
int currentPlayerHealth = 5000;
// Health thresholds
int minimumPlayerHealth = 0;
int maximumPlayerHealth = 9999;
// As this is an int (can be positive or negative), it can be used to heal or damage the player
// Feel free to change this value to test the code
int healthToModify = 450374;
// Modify the current player's health
currentPlayerHealth += healthToModify;
System.Console.WriteLine("Health after being modified: {0}", currentPlayerHealth);
// Check if the player is dead/knocked out (below the minimum)
if (currentPlayerHealth < minimumPlayerHealth)
{
// Health has exceeded the minimum value and should be reset to minimum
currentPlayerHealth = minimumPlayerHealth;
// Add your player death (respawn/game over) code here
}
// Check if the player’s health exceeds maximum
if (currentPlayerHealth > maximumPlayerHealth)
{
// Health has exceeded the maximum value and should be reset to maximum
currentPlayerHealth = maximumPlayerHealth;
}
System.Console.WriteLine("Health after checking: {0}", currentPlayerHealth);
In this context, you would need to also ensure that the range of potential damage is limited, and also for health packs to be limited in their effect as well.
Summary
This article was a simple review of various numeric types used in C# and how they can be used in the context of making video games.
Like with a lot of elements in programming, there is no “right” answer and you shouldn’t feel like you’re doing it “wrong” based on the numeric types you use.
Use whatever works for you, and as long as it “works” and doesn’t impact performance then it’s all good.