C# Numeric Value

C# Numeric Value

1 - C# 8-Bit and 16-Bit Integrals

The 8- and 16-bit integral types are: byte, sbyte, short, and ushort.

C# implicitly converts them to larger types as required.

*** This can cause a compile-time error when trying to assign the result back to a small integral type:

short x = 1, y = 1; 
short z = x + y; // Compile-time error 
  • x and y are implicitly converted to int so that the addition can be performed.
  • The result is also an int, which cannot be implicitly cast back to a short.

To make this compile, we must add an explicit cast:

short z = (short) (x + y);

 

2 - C# Float and Double Special Values

Floating-point types have special values to deal with the results of certain operations.

These special values are:

  • NaN (Not a Number),
  • +Infinity,
  • -Infinity, and
  • -0

The float and double types have constants for NaN, +Infinity, and -Infinity.

The constants that represent special values for double and float are as follows:

Special valueDouble constantFloat constant
NaNdouble.NaNfloat.NaN
+infinitydouble.PositiveInfinityfloat.PositiveInfinity
-infinitydouble.NegativeInfinityfloat.NegativeInfinity
-0-0.0-0.0f

For example, you can output the value of Negative Infinity in double:

Console.WriteLine (double.NegativeInfinity);   // -Infinity

Rule:

** Dividing a nonzero number by zero results in an infinite value.

For example:

Console.WriteLine ( 1.0 / 0.0); // Infinity 
Console.WriteLine (-1.0 / 0.0); // -Infinity 
Console.WriteLine ( 1.0 / -0.0); // -Infinity 
Console.WriteLine (-1.0 / -0.0); // Infinity

** Dividing zero by zero, or subtracting infinity from infinity, results in a NaN. 

For example:

Console.WriteLine ( 0.0 / 0.0); // NaN 
Console.WriteLine ((1.0 / 0.0) - (1.0 / 0.0)); // NaN

** When using ==, a NaN value is never equal to another value, even another NaN value:

Console.WriteLine (0.0 / 0.0 == double.NaN); // False  

** To test whether a value is NaN, you must use the float.IsNaN or double.IsNaN method:

Console.WriteLine (double.IsNaN (0.0 / 0.0)); // True

** When using object.Equals, however, two NaN values are equal:

Console.WriteLine (object.Equals (0.0 / 0.0, double.NaN)); // True 

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 / 0.0);                  //  Infinity
            Console.WriteLine(-1.0 / 0.0);                  // -Infinity
            Console.WriteLine(1.0 / -0.0);                  // -Infinity
            Console.WriteLine(-1.0 / -0.0);                  //  Infinity
            Console.WriteLine(0.0 / 0.0);                  //  NaN
            Console.WriteLine((1.0 / 0.0) - (1.0 / 0.0));   //  NaN
            Console.WriteLine(0.0 / 0.0 == double.NaN);    // False
            Console.WriteLine(double.IsNaN(0.0 / 0.0));   // True
            Console.WriteLine(object.Equals(0.0 / 0.0, double.NaN));   // True
            Console.ReadLine();
        }
    }
}

Output:

C# Float and Double Special Values

 

3 - C# double Versus decimal

  • double is useful for scientific computations.
  • decimal is useful for financial computations.
  • double value is Base 2 in Internal representation.
  • decimal value is Base 10 in Internal representation.
  • double value has Special values such as +0, -0, +Infinity, -Infinity, and NaN.
  • decimal does not have any special values.

*** During the calculation, decimal is slower than double.

 

4 - C# Data Type Conversions

The following table summarizes all the data type convert options:

TaskFunctionsExamples
Parsing base 10 numbersParse
TryParse
double d = double.Parse ("3.5");
int i;
bool ok = int.TryParse ("3", out i);
Parsing from base 2, 8, or 16Convert.ToIntegral
int i = Convert.ToInt32 ("1E", 16);
Formatting to hexadecimalToString 
string hex = 45.ToString ("X");
Lossless numeric conversionImplicit cast
int i = 23;
double d = i;
Truncating numeric
conversion
Explicit cast
double d = 23.5;
int i = (int) d;
Rounding numeric conversion
(real to integral)
Convert.ToIntegral
double d = 23.5;
int i = Convert.ToInt32 (d);

 

5 - C# Boxing and Unboxing

01 - C# object Type

object or System.Object is the ultimate base class for all types.

Any type can be upcast to object.

The following code creates a class Stack to provide a First-In-Last_Out data structure.

public class Stack {
    int position; 
    object[] data = new object[10];
    public void Push (object obj) { data[position++] = obj; }
    public object Pop() { return data[--position]; } 

} 

Because Stack works with the object type, we can Push and Pop any type to and from the Stack.

Stack stack = new Stack(); 
stack.Push ("CSS"); 
string s = (string) stack.Pop(); // Downcast, so explicit cast is needed 
Console.WriteLine (s);

*** When casting between a value type and object, the CLR must perform the process of boxing and unboxing.

02. C# Boxing

Boxing is the process of converting a value-type to a reference-type, which can be either the object class or an interface.

In the following code, we box an int into an object:

int x = 1;
object obj = x;           // Box the int
03. Unboxing

Unboxing is the operation of casting the object back to the original value type:

int y = (int)obj;         // Unbox the int

Unboxing requires an explicit cast.

C# throws an InvalidCastException if the value type does not match the object type.

For instance, the following throws an exception, because long does not exactly match int:

object obj = 19;           // 19 is inferred to be of type int
long x = (long) obj;      // InvalidCastException

You change the above code to the following:

object obj = 9;
long x = (int) obj;

The following code shows how to unbox a double value to int:

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)
        {
            object obj = 4.5;  // 4.5 is inferred to be of type double
            int x = (int)(double)obj; // x is now 4

            Console.WriteLine(x);
            Console.ReadLine();
        }
    }
}

Output:

C# Boxing and Unboxing