C# Numeric Types

C# Numeric Types

1 - C# Numeric Types

C# has the predefined numeric types.

There are three types of predefined numeric types:

  • signed Integral
  • unsigned Integral
  • real number, number with decimal parts
01. C# Integral-signed

Predefined Integral-signed numeric types in C#:

C# typeSystem typeSuffixSizeRange
sbyteSByteNo Suffix8 bits-2^7 to 2^7 -1
shortInt16No Suffix16 bits-2^15 to 2^15-1
intInt32No Suffix32 bits-2^31 to 2^31-1
longInt64L64 bits-2^63 to 2^63-1
02. C# Integral-unsigned

Predefined Integral-unsigned numeric types in C#:

C# typeSystem typeSuffixSizeRange
byteByteNo Suffix8 bits0 to 2^8 -1
ushortUInt16No Suffix16 bits0 to 2^16-1
uintUInt32U32 bits0 to 2^32-1
ulongUInt64UL64 bits0 to 2^64-1 
03. C# Real

Predefined real numeric types in C#:

C# typeSystem typeSuffixSizeRange
floatSingleF32 bits+/- (~10^-45 to 10^38)
doubleDoubleD64 bits+/- (~10^-324 to 10^308)
decimalDecimalM128 bits+/- (~10^-28 to 10^28)

The decimal type is typically used for financial calculations.

 

2 - C# Numeric Literals

Integral literals can use decimal or hexadecimal notation.

Hexadecimal is denoted with the 0x prefix.

For example:

int x = 17;
long y = 0x8F;

Real literals can use decimal and/or exponential notation.

For example:

double d = 1.5;
double million = 1E06;

*** You can insert an underscore anywhere inside a numeric literal to make it more readable:

int million = 1_000_000;

*** You can specify numbers in binary with the 0b prefix:

var b = 0b1010_1001_1110_1101_1010_1101;

Example:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace HelloWorld
{
    class Program
    {
     
        static void Main(string[] args)
        {
            int x = 127;
            long y = 0x7F;
            Console.WriteLine(x);
            Console.WriteLine(y);

            double d = 1.5;
            double million = 1E06;

            Console.WriteLine(d);
            Console.WriteLine(million);
            Console.ReadLine();
        }
    }
}

Output:

C# Numeric Literals

 

3 - C# Numeric literal type inference

C# compiler infers a numeric literal to be either double or an integral type:

  • If the literal contains a decimal point or the exponential symbol (E), it is a double.
  • Then it check if the value can be fit in an type in the following list:int, uint, long, and ulong.

For example:

  • 1.0 will be double by default since it has decimal part.
  • 4 is a int type.

The following code outputs the inferred type for each literal:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace HelloWorld
{
    class Program
    {
     
        static void Main(string[] args)
        {
            Console.WriteLine(1.0.GetType());  // (double)
            Console.WriteLine(1E06.GetType());  // Double (double)
            Console.WriteLine(1.GetType());  // Int32 (int)
            Console.WriteLine(0xF0000000.GetType());  // UInt32 (uint)
            Console.WriteLine(0x100000000.GetType());  // Int64 (long)
            Console.ReadLine();
        }
    }
}

Output:

C# Numeric literal type inference

4 - C# Numeric suffixes

Numeric suffixes explicitly define the type of a literal.

You can set a literal type by using suffix.

By default 1.0 is inferred as double by C# compiler, if you want to make it float type, you can add F as suffix.

Suffixes can be either lower or uppercase. and are as follows:

CategoryC# typeExample
Ffloatfloat f = 1.0F;
Ddoubledouble d = 1D;
Mdecimaldecimal d = 1.0M;
Uuintuint i = 1U;
Llonglong i = 1L;
ULulongulong i = 1UL;

F and M suffixes are the most useful and should always be applied when specifying float or decimal literals.

Without the F suffix, the following line would not compile, because 4.5 would be inferred to be of type double, which has no implicit conversion to float:

float f = 4.5F; 

The same principle is applied for a decimal literal:

decimal d = -1231.13M; // Will not compile without the M suffix.

Example:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace HelloWorld
{
    class Program
    {
     
        static void Main(string[] args)
        {
            Console.WriteLine(1.0.GetType());  // (double)
            Console.WriteLine(1E06.GetType());  // Double (double)
            Console.WriteLine(1.GetType());  // Int32 (int)
            Console.WriteLine(0xF0000000.GetType());  // UInt32 (uint)
            Console.WriteLine(0x100000000.GetType());  // Int64 (long)
            Console.WriteLine(1.0F.GetType());
            Console.WriteLine(1E06F.GetType());
            Console.WriteLine(1U.GetType());
            Console.ReadLine();
        }
    }
}

Output:

C# Numeric suffixes

5 - C# Numeric Conversions

01. C# Integral to integral conversions

Converting between integral types:

Integral type conversions are implicit if the destination type can represent every possible value of the source type.

Otherwise, an explicit conversion is required.

For example:

int x = 1;           // int is a 32-bit integer
long y = x;          // Implicit conversion to 64-bit integral type
short z = (short)x;  // Explicit conversion to 16-bit integral type
02. C# Floating-point to floating-point conversions

A double can represent every possible value of a float.

A float point value can be implicitly converted to a double.

Assign double type to float type must be explicit.

03. C# Floating-point to integral conversions

All integral types may be implicitly converted to all floating-point types:

int i = 5;
float f = i;

The reverse conversion must be explicit:

int i2 = (int)f;

*** When you cast from a floating-point number to an integral, any fractional portion is truncated(lost).

Note:

  • During casting from a floating-point number to an integral type, fractional portion is truncated and no rounding is performed.
  • System.Convert has methods to round floating point values while converting between various numeric types.
  • Implicitly converting a integral type to a floating-point type preserves magnitude but may occasionally lose precision.

Example:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace HelloWorld
{
    class Program
    {
     
        static void Main(string[] args)
        {
            int i1 = 100000001;
            float f = i1;     // Magnitude preserved, precision lost
            int i2 = (int)f;

            Console.WriteLine(i1);
            Console.WriteLine(f);
            Console.WriteLine(i2);
            Console.ReadLine();
        }
    }
}

Output:

C# Floating-point to integral conversions

6 - C# Decimal conversions

A decimal value can represent every possible integral-type value in C#.

All integral types can be implicitly converted to the decimal type.

All other numeric conversions to and from a decimal type must be explicit.

 

7 - C# Type Conversion Methods

C# provides the following built-in type conversion methods:

  • ToBoolean: Converts a type to a Boolean value, where possible.
  • ToByte: Converts a type to a byte.
  • ToChar: Converts a type to a single Unicode character, where possible.
  • ToDateTime:Converts a type (integer or string type) to date-time structures.
  • ToDecimal: Converts a floating point or integer type to a decimal type.
  • ToDouble: Converts a type to a double type.
  • ToInt16: Converts a type to a 16-bit integer.
  • ToInt32: Converts a type to a 32-bit integer.
  • ToInt64: Converts a type to a 64-bit integer.
  • ToSbyte: Converts a type to a signed byte type.
  • ToSingle: Converts a type to a small floating point number.
  • ToString: Converts a type to a string.
  • ToType: Converts a type to a specified type.
  • ToUInt16: Converts a type to an unsigned int type.
  • ToUInt32: Converts a type to an unsigned long type.
  • ToUInt64: Converts a type to an unsigned big integer.

The following example converts various value types to string type:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace HelloWorld
{
    class Program
    {   
        static void Main(string[] args)
        {
            int i = 75;
            float f = 53.005f;
            double d = 2345.7652;
            bool b = true;

            Console.WriteLine(i.ToString());
            Console.WriteLine(f.ToString());
            Console.WriteLine(d.ToString());
            Console.WriteLine(b.ToString());
            Console.ReadLine();
        }
    }
}

Output:

C# Type Conversion Methods