C# Short and ushort Types

Understand the short and ushort number types. These types use 16 bits to represent a number.
Short and ushort. The short type reduces the memory usage of integers. It represents a number in 2 bytes—16 bits—half the size of an int.Int, uint
Notes, short. Short is aliased to System.Int16. Ushort, meanwhile, is aliased to System.UInt16. Unsigned numbers cannot be negative.
System.Int16 information: short.MinValue = -32768 short.MaxValue = 32767 System.UInt16 information: ushort.MinValue = 0 ushort.MaxValue = 65535
Short example. This example uses the short type as a storage location for positive or negative integers. The short type is aliased to the System.Int16 struct.Struct

Here: The program shows the memory usage of the short type on the managed heap, and its usage on the evaluation stack as a local variable.

Increment: You can add values to a short local variable. This computation is expressed in the same way as adding numbers to integers.

Note: The evaluation stack in the execution engine stores short types in the same memory size and slots as integers.

Int16 alias: The short keyword is aliased to the "System.Int16" type. This mapping is referenced in the C# specification itself.

C# program that uses short numbers using System; class Program { static void Main() { // Demonstrates a short value type used as local variable. short number = 11; Console.WriteLine(11); number = -1; // Can be negative Console.WriteLine(number); Console.WriteLine(number == -1); // Can use == operator Console.WriteLine(number + 100); // Can use + operator Console.WriteLine(number.GetType()); Console.WriteLine(typeof(short)); Console.WriteLine(short.MinValue); Console.WriteLine(short.MaxValue); // Find the memory usage for a short value in a large array. long bytes1 = GC.GetTotalMemory(false); short[] array = new short[1000 * 1000]; array[0] = 1; long bytes2 = GC.GetTotalMemory(false); // Console.WriteLine(bytes1); // Console.WriteLine(bytes2); Console.WriteLine(((bytes2 - bytes1) / (1000 * 1000)).ToString() + " bytes per short"); } } Output 11 -1 True 99 System.Int16 System.Int16 -32768 32767 2 bytes per short
Short range. Consider the values returned by short.MinValue and short.MaxValue. The smallest number a short can hold is -32768. And the largest is 32767.
Short memory. A large array of shorts is half the physical size of a large array of ints. When a short element is read from an array, the runtime expands it to fit on the evaluation stack.

Also: Using short local variables will not reduce memory usage. It may degrade performance.

Locals: Short locals are stored in the evaluation stack as native integers. Expert .NET IL Assembler, by Serge Lidin, has many details.

Parse shorts. This program uses 2 string literals as the input data: "100" and "100000". The value 100 can be stored in a short. The value 100000 cannot be.Parse

Info: The call to short.Parse succeeds without causing an error because 100 is a valid short.

So: With the 2 calls to short.TryParse, the first call succeeds and you can use the result, but the second call returns false.

True, False
C# program that uses short.Parse and short.TryParse using System; class Program { static void Main() { const string value1 = "100"; const string value2 = "100000"; // Can use short.Parse. short sh1 = short.Parse(value1); Console.WriteLine("sh1 = {0}", sh1); // Can use short.TryParse. short sh2; if (short.TryParse(value1, out sh2)) { Console.WriteLine("sh2 = {0}", sh2); } // Returns false: short.TryParse on number too large. short sh3; if (short.TryParse(value2, out sh3)) { Console.WriteLine("sh3 = {0}", sh3); // Never reached. } } } Output sh1 = 100 sh2 = 100
Ushort example. The ushort type is a value type. This means the actual value of the variable is stored in its storage location memory.

Locals: Local ushort variables are stored on the method stack. The ushort type occupies 16 bits—it is half the size of an int value.

Typeof: The typeof operator uses an optimized reflection method to get the type pointer for an object type.

Typeof, nameof

And: The type of a ushort variable is actually a System.UInt16 type, because ushort is aliased to that type in the System namespace.

Array: We use an array of unsigned shorts. The elements in the array are always initialized to have all their bits set to zero.

Int Array
C# program that uses ushort using System; class Program { static void Main() { // Declare and initialize ushort value. ushort value1 = 1000; // This won't compile: // value1 = -1; // Write value. Console.WriteLine(value1); // Write type of ushort. Console.WriteLine(typeof(ushort)); // Alternative syntax for declaring a ushort value. UInt16 value2 = 1000; // Write value. Console.WriteLine(value2); // Declare a ushort array. ushort[] array1 = new ushort[2]; array1[0] = 5; // Write array elements. Console.WriteLine(array1[0]); Console.WriteLine(array1[1]); // <-- Default is zero. // Write minimum and maximum values. Console.WriteLine(ushort.MinValue); Console.WriteLine(ushort.MaxValue); } } Output 1000 System.UInt16 1000 5 0 0 <- Min 65535 <- Max
Ushort performance. If a ushort is smaller than an int, is it also faster to use? This program tests the performance of incrementing and looping with a ushort.

Version 1: The method loops over a ushort and increments one. The loop branches on a ushort (in a loop boundary test).

Version 2: This code uses int instead of ushort. It performs the same actions as the ushort method but with int.

Result: It is faster to use an int in loops and increment statements. Ushort does not help runtime speed in this test.

C# program that tests ushort performance using System; using System.Diagnostics; using System.Runtime.CompilerServices; class Program { const int _max = 1000000; static void Main() { // Version 1: use ushort method. var s1 = Stopwatch.StartNew(); for (int i = 0; i < _max; i++) { Test1(); } s1.Stop(); // Version 2: use int method. var s2 = Stopwatch.StartNew(); for (int i = 0; i < _max; i++) { Test2(); } s2.Stop(); Console.WriteLine(((double)(s1.Elapsed.TotalMilliseconds * 1000000) / _max).ToString("0.00 ns")); Console.WriteLine(((double)(s2.Elapsed.TotalMilliseconds * 1000000) / _max).ToString("0.00 ns")); } static void Test1() { ushort result = 0; for (ushort i = 0; i < 100; i++) { result++; } } static void Test2() { int result = 0; for (int i = 0; i < 100; i++) { result++; } } } Output 62.54 ns ushort method 35.68 ns int method
Ushort range. The minimum value is 0, while the maximum value is 65535. In an array of ushort length, the last offset value will be 65534.
Ushort error. At compilation time, the C# compiler uses a checked context to check for overflow of numeric variables. It tries to detect an invalid program.Checked

And: It detects the assignment of a negative constant to the ushort variable, and gives you a helpful error.

Note: This will help you avoid hard-to-find bugs later in the program's development.

Ushort error: Constant value '-1' cannot be converted to a 'ushort' ...
Ushort advantages. Because ushort is only 16 bits, it will use about one-half the memory in an array as the int or uint type. In large arrays, this can improve performance.

Note: Generally programming languages use the "int" type to indicate the integer type that is fastest for the computer to use.

BitArray. For many small values, a BitArray collection or an array of bool values is more compact than an array of ushort (or bool) values. A BitArray uses a single bit for each index.BitArrayBool Array
A summary. Short and ushort are sometimes useful. Shorts can be used like native integers as local variables. In large arrays they will save memory usage over other types.Array
© 2007-2019 Sam Allen. Every person is special and unique. Send bug reports to info@dotnetperls.com.
HomeSearch
Home
Dot Net Perls