Home > Guides > Programming > .NET and Windows Programming

Toggle Open Guide Table of ContentsGuide Contents

Close Table of ContentsGuide Contents

Close Table of Contents

Numeric Types in the .NET Framework

Last updated Apr 1, 2005.

The .NET Framework defines several numeric types, all of which have their place in .NET programs. As you might expect, some types are more useful than others. In addition, not all .NET languages support all of the .NET Framework types. The Common Language Specification (CLS) defines a base set of numeric types that all languages must support. Support for the other numeric types is up to the language implementors.

.NET languages often have their own names for the built-in .NET types. For example, the .NET System.Int32 type defines a 32 bit signed integer. In C#, this type is called int. In Visual Basic .NET, this type is called Integer.

If you're writing classes in C# that you want to make available to other .NET languages, you have to ensure that you use only CLS compliant numeric types. For example, if you exported a method that takes an sbyte or System.SByte parameter, that method would not be easily usable by Visual Basic .NET programs. What your class uses internally is a different matter: you're free to use any available type within your classes so long as the non-CLS-compliant types aren't exposed in the class's public or protected interfaces.

Note that the above is "just" a convention. Neither the C# compiler nor anything else in the .NET runtime or build tools will prevent you from including non-compliant types in your interfaces.

Integer Types

The Framework defines many different integer types, most of which correspond to native machine-level types. The only exception is System.Int64, which on 32 bit processors is implemented as a structure of two 32 bit words.

The table below shows the integer types defined by the .NET Framework, and also shows their corresponding C# and Visual Basic .NET names. Note that some of the types are not directly supported by Visual Basic .NET.

.NET Type

C# Type

Visual Basic Type

Description

System.Byte

byte

Byte

An unsigned one-byte value, 0 through 255.

System.SByte

sbyte

 

A signed one-byte value, -128 through 127.

System.Int16

short

Short

A signed two-byte value, -32768 through 32767.

System.UInt16

ushort

 

An unsigned two-byte value, 0 through 65535.

System.Int32

int

Integer

A signed 4-byte value, -2,147,483,648 through 2,147,483,647.

System.UInt32

uint

 

An unsigned 4-byte value, 0 through 4,294,967,295.

System.Int64

long

Long

A signed 64-bit integer value -9,223,372,036,854,775,808 through 9,223,372,036,854,775,807.

System.UInt64

ulong

 

An unsigned 64-bit integer, value 0 through 18,446,744,073,709,551,615.

With the exception of Byte, Visual Basic does not directly support unsigned numbers. And, oddly, it doesn't support a signed 8-bit type.

Floating-point Types

The .NET Framework defines these two floating-point numeric types:

System.Single

float

Single

A 32-bit floating-point number that can hold values -3.402823e38 to 3.402823e38. Precision is 7 digits.

System.Double

double

Double

An 8-byte floating-point number with a range of -1.79769313486232e308 to 1.79769313486232e308, and 15 or 16 digits of precision.

Fixed-point Type

The System.Decimal type is a kind of hybrid between an integer and a floating-point number. It is a 128-bit (16-byte) data structure that can exactly represent values ranging from -79,228,162,514,264,337,593,543,950,335 to negative 79,228,162,514,264,337,593,543,950,335, with up to 29 significant digits. The C# name for this type is decimal. In Visual Basic it's Decimal.

The Decimal type is a structure that consists of a 1-bit sign, a 96-bit integer, and a scaling factor that specifies where to put the decimal point. The scaling factor is a number from 0 to 28, representing the number 10 raised to that power, which is used to divide the 96-bit integer. So, if the integer number is 12 and the scaling factor is 1, then the value represented is 12 divided by 101, or 1.2.

The beauty of this type is that it can exactly represent decimal values—something that's especially important when working with currency values. Whereas floating-point numbers are approximations (albeit very close approximations), decimal values are exact. For example, if you use a floating-point type to add and subtract currency values, eventually you'll end up with a number that has more than just two decimal places. You might end up with 349.999997, for example.

If you use a Decimal type to add currency values, you'll always end up with two decimal places.

Consider, for example, this simple program:

[C#]

double d = 1.37;
double sum = 0;
for (int i = 0; i < 1000; i++)
 sum += d;
Console.WriteLine(sum);

[Visual Basic]

Dim d As Double = 1.37
Dim sum As Double = 0
Dim i As Integer
For i = 1 To 1000
 sum = sum + d
Next
Console.WriteLine(sum)

Now everybody knows that 1.37 times 1,000 is 1370, right? Would it surprise you to find that the output from the program above is 1369.99999999998?

If you rewrote that program, changing Double to Decimal (and double to decimal in the C# program), you'd get the answer that you expected: 1370.00.

You might think that being off by only .00000000002 is no big deal, and in many cases you'd be right. However, that small program only does 1,000 calculations. If I change the program to run 100,000,000 times, the result is 137000000.185918. If you've ever worked in a bank, you'll know that auditors can go wild about 19 cents, even if it's just a fraction of 137 million dollars. Floating-point error can accumulate much faster than in this example, depending on the numbers that you're adding. If you want exact representations of decimal numbers, you should use the Decimal type.

Discussions

Copies of the array?
Posted Dec 23, 2008 03:40 PM by luige21
1 Replies
Hi
Posted Dec 5, 2008 05:10 AM by ajay2000bhushan
2 Replies
You have no clue.
Posted Jun 10, 2008 03:28 PM by theinternetmaster
1 Replies

Make a New Comment

You must log in in order to post a comment.

Related Resources

Jim Mischel"Highly unlikely" does not mean "impossible"
By Jim MischelJuly 18, 2009 No Comments

One of my programs crashed the other day in a very unexpected place.  A call to System.Threading.ConcurrentQueue.TryDequeue (from the Parallel Extensions to .NET) resulted in an OverflowException being thrown.  Investigation revealed a pretty serious bug in the System.Random constructor.

It's Here; Put Away Your Pre-Conceptions on What an OS Must Be: Part II
By John TraenkenschuhMay 24, 2009 No Comments

In the last blog in this series, Traenk relates his first experiences with computers and with coding.  But now, some years have passed. . .

It's Here; Put Away Your Pre-Conceptions on What an OS Must Be: Part I
By John TraenkenschuhMay 24, 2009 No Comments

Traenk relates his past experience with Operating Systems that goes back 25 years, ok, more than that but he ain't tellin'

See More Blogs

Informit Network