Pages

Wednesday, 22 July 2015

Implicit Conversions

Implicit Conversions

For certain types of conversions, there is no possibility of loss of data or precision. For example, it’s easy to stuff an 8-bit value into a 16-bit type with no loss of data.
  • The language will do these conversions for you automatically. These are called implicit conversions.
  • When converting from a source type with fewer bits to a target type with more bits, the extra bits in the target need to be filled with either 0s or 1s.
  • When converting from a smaller unsigned type to a larger unsigned type, the extra most significant bits of the target are filled with 0s. This is called zero extension.
  • For conversion between signed types, the extra most significant bits are filled with the sign bit of the source expression.

Explicit Conversions and Casting

When you convert from a shorter type to a longer type, it’s easy for the longer type to hold all the bits of the shorter type. In other situations, however, the target type might not be able to accommodate the source value without loss of data.

For example, suppose you want to convert a ushort value to a byte.
  • A ushort can hold any value between 0 and 65,535.
  • A byte can only hold a value between 0 and 255.
  • As long as the ushort value you want to convert is less than 256, there won’t be any loss of data. If it is greater, however, the most significant bits will be lost.
For example, following figure shows an attempt to convert a ushort with a value of 1,365 to a byte, resulting in a loss of data. Not all the significant bits of the source value fit into the target type, resulting in an overflow and loss of data. The source value was 1,365, but the maximum ] value the target can hold is 255. The resulting value in the byte is 85 instead of 1,365.

Casting

For the predefined types, C# will automatically convert from one data type to another—but only between those types for which there is no possibility of data loss between the source type and the target type. That is, the language does not provide automatic conversion between two types if there is any value of the source type that would lose data if it were converted to the target type. If you want to make a conversion of this type, you must use an explicit conversion called a cast expression.

The following code shows an example of a cast expression.
static void Main(string[] args)
 {
  ushort sh = 10;
  byte sb = (byte)sh;
  Console.WriteLine("sb: " + sh + " = 0x{0:X}", sb);

  sh = 1365;
  sb = (byte)sh;
  Console.WriteLine("sb: " + sh + " = 0x{0:X}", sb);
 }

The output of the code in the figure shows both the decimal and hexadecimal values of the results and is the following:

sb: 10 = 0xA sb: 85 = 0x55

The checked and unchecked Operators

The checked and unchecked operators control the overflow checking context of an expression, which is placed between a set of parentheses. The expression cannot be a method. The syntax is the following:
checked ( [Expression] )
 unchecked ( Expression )
For example, the following code executes the same conversion—first in a checked operator and then in an unchecked operator.
ushort sh = 2000;
byte sb;
sb = unchecked ( (byte) sh ); // Most significant bits lost
Console.WriteLine("sb: {0}", sb);
sb = checked ( (byte) sh ); // OverflowException raised
Console.WriteLine("sb: {0}", sb);

This code produces the following output:
sb: 208
Unhandled Exception: System.OverflowException: Arithmetic operation resulted in an overflow. at Test1.Test.Main() in C:\Programs\Test1\Program.cs:line 21
  • In the unchecked context, the overflow is ignored, resulting in the value 208.
  • In the checked context, an OverflowException exception is raised.

0 comments:

Post a Comment