11 out of 19 rated this helpful - Rate this topic

Int32 Structure

Updated: June 2010

Represents a 32-bit signed integer.

Namespace:  System
Assembly:  mscorlib (in mscorlib.dll)
[SerializableAttribute]
[ComVisibleAttribute(true)]
public struct Int32 : IComparable, IFormattable, 
	IConvertible, IComparable<int>, IEquatable<int>

Int32 is an immutable value type that represents signed integers with values ranging from negative 2,147,483,648 (which is represented by the Int32.MinValue constant) through positive 2,147,483,647 (which is represented by the Int32.MaxValue constant). The .NET Framework also includes an unsigned 32-bit integer value type, UInt32, which represents values that range from 0 to 4,294,967,295.

Instantiating an Int32 Value

You can instantiate an Int32 value in several ways:

  • You can declare an Int32 variable and assign it a literal integer value that is within the range of the Int32 data type. The following example declares two Int32 variables and assigns them values in this way.

    int number1 = 64301;
    int number2 = 25548612;
    
    
    
  • You can assign the value of an integer type whose range is a subset of the Int32 type. This is a widening conversion that does not require a cast operator in C# or a conversion method in Visual Basic.

    sbyte value1 = 124;
    short value2 = 1618;
    
    int number1 = value1;
    int number2 = value2;
    
    
    
  • You can assign the value of a numeric type whose range exceeds that of the Int32 type. This is a narrowing conversion, so it requires a cast operator in C# and a conversion method in Visual Basic if Option Strict is on. If the numeric value is a Single, Double, or Decimal value that includes a fractional component, the handling of its fractional part depends on the compiler performing the conversion. The following example performs narrowing conversions to assign several numeric values to Int32 variables.

    long lNumber = 163245617;
    try {
       int number1 = (int) lNumber;
       Console.WriteLine(number1);
    }
    catch (OverflowException) {
       Console.WriteLine("{0} is out of range of an Int32.", lNumber);
    }
    
    double dbl2 = 35901.997;
    try {
       int number2 = (int) dbl2;
       Console.WriteLine(number2);
    }   
    catch (OverflowException) {
       Console.WriteLine("{0} is out of range of an Int32.", dbl2);
    }
    
    // The example displays the following output:
    //       163245617
    //       35902
    
    
    
  • You can call a method of the Convert class to convert any supported type to an Int32 value. This is possible because Int32 supports the IConvertible interface. The following example illustrates the conversion of an array of Decimal values to Int32 values.

    decimal[] values= { Decimal.MinValue, -1034.23m, -12m, 0m, 147m,
                        199.55m, 9214.16m, Decimal.MaxValue };
    int result;
    
    foreach (decimal value in values)
    {
       try {
          result = Convert.ToInt32(value);
          Console.WriteLine("Converted the {0} value '{1}' to the {2} value {3}.",
                            value.GetType().Name, value,
                            result.GetType().Name, result);
       }
       catch (OverflowException) {
          Console.WriteLine("{0} is outside the range of the Int32 type.",
                            value);
       }   
    }                                  
    // The example displays the following output:
    //    -79228162514264337593543950335 is outside the range of the Int32 type.
    //    Converted the Decimal value '-1034.23' to the Int32 value -1034.
    //    Converted the Decimal value '-12' to the Int32 value -12.
    //    Converted the Decimal value '0' to the Int32 value 0.
    //    Converted the Decimal value '147' to the Int32 value 147.
    //    Converted the Decimal value '199.55' to the Int32 value 200.
    //    Converted the Decimal value '9214.16' to the Int32 value 9214.
    //    79228162514264337593543950335 is outside the range of the Int32 type.
    
    
    
  • You can call the Parse or TryParse method to convert the string representation of an Int32 value to an Int32. The string can contain either decimal or hexadecimal digits. The following example illustrates the parse operation by using both a decimal and a hexadecimal string.

    string string1 = "244681";
    try {
       int number1 = Int32.Parse(string1);
       Console.WriteLine(number1);
    }
    catch (OverflowException) {
       Console.WriteLine("'{0}' is out of range of a 32-bit integer.", string1);
    }
    catch (FormatException) {
       Console.WriteLine("The format of '{0}' is invalid.", string1);
    }
    
    string string2 = "F9A3C";
    try {
       int number2 = Int32.Parse(string2,
                                System.Globalization.NumberStyles.HexNumber);
       Console.WriteLine(number2);
    }
    catch (OverflowException) {
       Console.WriteLine("'{0}' is out of range of a 32-bit integer.", string2);
    }
    catch (FormatException) {
       Console.WriteLine("The format of '{0}' is invalid.", string2);
    }
    // The example displays the following output:
    //       244681
    //       1022524
    
    
    

Performing Operations on Int32 Values

The Int32 type supports standard mathematical operations such as addition, subtraction, division, multiplication, subtraction, negation, and unary negation. Like the other integral types, the Int32 type also supports the bitwise AND, OR, XOR, left shift, and right shift operators.

You can use the standard numeric operators to compare two Int32 values, or you can call the CompareTo or Equals method.

Representing an Int32 as a String

The Int32 type provides full support for standard and custom numeric format strings. (For more information, see Formatting Overview, Standard Numeric Format Strings, and Custom Numeric Format Strings.)

To format an Int32 value as an integral string with no leading zeros, you can call the parameterless ToString() method. By using the "D" format specifier, you can also include a specified number of leading zeros in the string representation. By using the "N" format specifier, you can include group separators and specify the number of decimal digits to appear in the string representation of the number. By using the "X" format specifier, you can represent an Int32 value as a hexadecimal string. The following example formats the elements in an array of Int32 values in these four ways.

int[] numbers = { -1403, 0, 169, 1483104 };
foreach (int number in numbers) {
   // Display value using default formatting.
   Console.Write("{0,-8}  -->   ", number.ToString());
   // Display value with 3 digits and leading zeros.
   Console.Write("{0,11:D3}", number);
   // Display value with 1 decimal digit.
   Console.Write("{0,13:N1}", number);
   // Display value as hexadecimal.
   Console.Write("{0,12:X2}", number);
   // Display value with eight hexadecimal digits.
   Console.WriteLine("{0,14:X8}", number);
}   
// The example displays the following output:
//    -1403     -->         -1403     -1,403.0    FFFFFA85      FFFFFA85
//    0         -->           000          0.0          00      00000000
//    169       -->           169        169.0          A9      000000A9
//    1483104   -->       1483104  1,483,104.0      16A160      0016A160


You can also format an Int32 value as a binary, octal, decimal, or hexadecimal string by calling the ToString(Int32, Int32) method and supplying the base as the method's second parameter. The following example calls this method to display the binary, octal, and hexadecimal representations of an array of integer values.

int[] numbers = { -146, 11043, 2781913 };
Console.WriteLine("{0,8}   {1,32}   {2,11}   {3,10}", 
                  "Value", "Binary", "Octal", "Hex");
foreach (int number in numbers) {
   Console.WriteLine("{0,8}   {1,32}   {2,11}   {3,10}", 
                     number, Convert.ToString(number, 2), 
                     Convert.ToString(number, 8), 
                     Convert.ToString(number, 16));
}      
// The example displays the following output:
//       Value                             Binary         Octal          Hex
//        -146   11111111111111111111111101101110   37777777556     ffffff6e
//       11043                     10101100100011         25443         2b23
//     2781913             1010100111001011011001      12471331       2a72d9


Working with Non-Decimal 32-Bit Integer Values

In addition to working with individual integers as decimal values, you may want to perform bitwise operations with integer values, or work with the binary or hexadecimal representations of integer values. Int32 values are represented in 31 bits, with the thirty-second bit used as a sign bit. Positive values are represented by using sign-and-magnitude representation. Negative values are in two's complement representation. This is important to keep in mind when you perform bitwise operations on Int32 values or when you work with individual bits. In order to perform a numeric, Boolean, or comparison operation on any two non-decimal values, both values must use the same representation.

All members of this type are thread safe. Members that appear to modify instance state actually return a new instance initialized with the new value. As with any other type, reading and writing to a shared variable that contains an instance of this type must be protected by a lock to guarantee thread safety.

Windows 7, Windows Vista, Windows XP SP2, Windows XP Media Center Edition, Windows XP Professional x64 Edition, Windows XP Starter Edition, Windows Server 2008 R2, Windows Server 2008, Windows Server 2003, Windows Server 2000 SP4, Windows Millennium Edition, Windows 98, Windows CE, Windows Mobile for Smartphone, Windows Mobile for Pocket PC, Xbox 360, Zune

The .NET Framework and .NET Compact Framework do not support all versions of every platform. For a list of the supported versions, see .NET Framework System Requirements.

.NET Framework

Supported in: 3.5, 3.0, 2.0, 1.1, 1.0

.NET Compact Framework

Supported in: 3.5, 2.0, 1.0

XNA Framework

Supported in: 3.0, 2.0, 1.0

Date

History

Reason

June 2010

Revised extensively.

Information enhancement.

Did you find this helpful?
(1500 characters remaining)
Community Content Add
Annotations FAQ
Note the differences in implementation of Int32 behavior for overflows!

This is a gotcha regarding all integral types in .NET but will most likely surface in your code in an Int32 just because it's used so often.

What do you think will happen when you try to put a number that is too big into an Int32 (as an example... the same rule applies for any number type ie Int16, Int64, UInt32, etc)? I expect something like an Overflow exception... well, if you write in VB that is what will happen... in C# it wont!

The short reason why this is is that the VB compiler will emit the Intermediate Language OpCode Add.Ovf (if you say add to a number) which is the code that makes the runtime throw an exception if the number is too large for it's type (an Int32 limit is +- 2,147,483,647) so if you had 2,147,483,647 in an Int32 and add one to it, code compiled by the VB compiler will throw an System.OverflowException. If the code is compiled in C#, it won't do anything! the number will just be wrong!

Before you start ragging on C# all you VB developers.... think about how often you care about overflows.... I can safely say that I almost NEVER do. All my for loops are like in the range of hundreds usually. Well, if I wrote the for loop in VB, every time through where it adds one its going to check for overflow. I KNOW it will never overflow, but the runtime is going to check everytime anyway. So the philosophy of C# which comes from the C family. C++ acts the same way in regards to overflows. Note that checking for overflow takes more clock cycles so C# has opted for performance by default while VB has opted for be-safe by default. This makes sense considering the philosophy and intent behind both languages, but makes dealing with overflows really problematic.

C# CAN check for overflows if you want it to. you can make it act like VB (ALWAYS check for overflows) with the /Checked+ compiler switch. OR you can check for individual var overflows with the 'checked' operator thusly:

try
{
checked
{
System.Int32 checkedTooBig = int32Max * int32Max;
}
}
catch (System.OverflowException)
{
DoSomething();
}


This has the really odd byproduct that if you consume a library written in VB your numbers will throw overflow exceptions when you call into it. If you consume a library written in C# you don't really know if your numbers will throw overflow exceptions or not since it depends on how it was compiled (i.e. did the compile with the /checked+ switch) or if they used the 'checked' operator on an individual operation.

This is a great example of the problems related to language interop in my opinion. C# developers can write C# code without checked math operations that will NOT throw exceptions on overflow. This code is CLSCompliant. VB developers can then use this library, but they won't get what they expect! The same is true the other direction. C# developers might expect that overflows NOT throw exceptions, but if they consume an assembly written in VB overflow exeptions would occur. To make matters worse, without looking directly at the intermediate language, you have NO idea when you are consuming an assembly if the overflow throws an exception or not.

Moreover, you can't be paranoid and just check all your external assembly calls like this:

try
{
checked // this won't check the method call for overflow even though it looks like it would
{
ExternalLibraryMethodThatDoesMath(myInt32);
}
}
catch(System.OverflowException)
{
}

because the checked operator's only function in life is to tell the compiler to emit the correct OpCode to check for overflows or not. It's can't apply an overflow check to a 'Call' OpCode... So you can't check to make sure the ExternalLibraryMethodThatDoesMath() will throw an exception on overflow...it's entirely dependent on how that assembly was compiled.



I was curious what the behavior would be in SQL Server 2005 so I tried it in Management Studio. I opened a table and modifed a field of type "INT" to 2,147,483,648 (2,147,483,647 + 1) and thankfully it produced an error "Invlaid value for cell". So I guess if you're a C# user, you still have a safety net to prevent you from storing bad numeric data.


using System;

using System;

// The Point class is derived from System.Object.
class Point
{
public int x, y;

public Point(int x, int y)
{
this.x = x;
this.y = y;
}

public override bool Equals(object obj)
{
// If this and obj do not refer to the same type, then they are not equal.
if (obj.GetType() != this.GetType()) return false;

// Return true if x and y fields match.
Point other = (Point) obj;
return (this.x == other.x) && (this.y == other.y);
}

// Return the XOR of the x and y fields.
public override int GetHashCode()
{
return x ^ y;
}

// Return the point's value as a string.
public override String ToString()
{
return String.Format("({0}, {1})", x, y);
}

// Return a copy of this point object by making a simple field copy.
public Point Copy()
{
return (Point) this.MemberwiseClone();
}
}

public sealed class App {
static void Main()
{
// Construct a Point object.
Point p1 = new Point(1,2);

// Make another Point object that is a copy of the first.
Point p2 = p1.Copy();

// Make another variable that references the first Point object.
Point p3 = p1;

// The line below displays false because p1 and p2 refer to two different objects.
Console.WriteLine(Object.ReferenceEquals(p1, p2));

// The line below displays true because p1 and p2 refer to two different objects that have the same value.
Console.WriteLine(Object.Equals(p1, p2));

// The line below displays true because p1 and p3 refer to one object.
Console.WriteLine(Object.ReferenceEquals(p1, p3));

// The line below displays: p1's value is: (1, 2)
Console.WriteLine("p1's value is: {0}", p1.ToString());
}
}

// This code example produces the following output:
//
// False
// True
// True
// p1's value is: (1, 2)
//