Introduction to Real Numbers

overview

A real number is a number that displays a decimal part. This means that the number can be made of two sections separated by a symbol that is referred to as the Decimal Separator or Decimal Symbol. This symbol is different by language, country, group of languages, or group of countries. In US English, this symbol is the period as can be verified from the Regional (and Language) Settings of the Control Panel:

Regional

On both sides of the decimal symbol, digits are used to specify the value of the number. The number of digits on the right side of the symbol determines how much precision the number offers.

Both Microsoft Windows and .NET Framework provides various levels of support for real numbers.

Introduction to Floating-Point Numbers

The integers we have used so far have the main limitation of not allowing decimal values. C# provides floating values that would solve this problem. The most fundamental data type you can use for a floating-point number is called float. A variable declared as float can store real numbers that range from 3.402823e38 to 3.402823e38 in 32 bits. Here is an example:

float distance;

To let you display a floating-point number with single-precision to the console screen, both the Console.Write() and the Console.WriteLine() methods each has a syntax that takes a float argument. Their syntaxes are:

public static void Write(object value);
public static void WriteLine(object value);

A Number with Single-Precision

As seen with integers, to support real numbers, the .NET Framework provides various structures. All the structures are created in the System namespace.

To support numbers with single-precision, the .NET Framework provides a structure named Single. The Single structure is used to support the float data type of the C# language. This means that the characteristics of the float data type are defined in the Single structure. All the characteristics of we reviewed for the structures associated with integers are also available for real numbers. This includes the ability to display a value by calling one of the versions of the overloaded ToString() methods that every number-associated structure is equipped with. The operations also include the ability to parse or to to try parsing a value to produce an appropriate real number.

Characteristics of Floating-Point Numbers

The Minimum Value of a Type

Like integers, floating-point numbers have limits so they can fit in the computer memory allocated for them. As seen for the structures of integers, to let you get the lowest value that a type can hold, each number-associated structure is equipped with a field named MinValue. For the float and Single type, this field is defined as follows:

public const float MinValue = -3.40282347E+38;

To get the lowest value of a type, you can access this field. Here is an example:

using static System.Console;

WriteLine("===========================================================================================");
WriteLine("Float Minimum Value (Natural):     " + float.MinValue.ToString("N"));
WriteLine("Float Minimum Value (Exponential): " + float.MinValue.ToString("E"));
WriteLine("===========================================================================================");

This would produce:

===========================================================================================
Float Minimum Value (Natural):     -340,282,346,638,528,859,811,704,183,484,516,925,440.00
Float Minimum Value (Exponential): -3.402823E+038
===========================================================================================

Press any key to close this window . . .

The Maximum Value of a Type

To let you get the highest value that a floating-point number can hold, their structure is equipped with a field named MaxValue. For the float type, this field is defined as follows:

public const float MaxValue = 3.40282347E+38;

To get the highest value of a type, access this field. Here is an example:

using static System.Console;

WriteLine("===========================================================================================");
WriteLine("Float Minimum Value (Natural):     " + float.MinValue.ToString("N"));
WriteLine("Float Minimum Value (Exponential): " + float.MinValue.ToString("E"));
WriteLine("Float Maximum Value (Natural):     " + float.MaxValue.ToString("N"));
WriteLine("Float Maximum Value (Exponential): " + float.MaxValue.ToString("E"));
WriteLine("===========================================================================================");

This would produce:

===========================================================================================
Float Minimum Value (Natural):     -340,282,346,638,528,859,811,704,183,484,516,925,440.00
Float Minimum Value (Exponential): -3.402823E+038
Float Maximum Value (Natural):     340,282,346,638,528,859,811,704,183,484,516,925,440.00
Float Maximum Value (Exponential): 3.402823E+038
===========================================================================================

Press any key to close this window . . .

When the Value is Not-A-Number

After declaring and initializing a float (or a Single) variable, it should hold an appropriate value. If you get the variable value some other way, at one time or another, you may not know what value is stored in the memory allocated for the variable. In fact, the variable may hold a value that is not a number. To let you check whether the variable is holding a value that is not a number, the Single structure of the floating-point type is equipped with a field named NaN. To get its information, type the float data type, followed by the period operator, and followed by the NaN field. Here is an example:

using static System.Console;

floatnumber = 0D;

if( number == double.NaN )
    WriteLine("The value is not a number.");

Another technique you can use to check this characteristic is to call the IsNaN() method is the Single structure.

The Epsilon

Using one integer and one floating-point number, or with two floating-point numbers, you can perform one of the routine arithmetic operations such as the addition, the subtraction, the multiplication, or the division. When it comes to the division and if performed on two values, you can get a positive or a negative number. In highly precise calculations, you may have to deal with an approximate number whose exact value is not known. For example, the smallest positive number is called epsilon. In the Single structure, this field is named Epsilon. For the single-precision type, the epsilon is equal to 1.445.

The Negative Infinity

When dealing with real numbers, some operations produce very little or very large numbers. In algebra, the smallest conceptual number is called negative infinity (in reality, infinity is not a number but a concept). In the .NET Framework, the negative infinity is represented by a field named NegativeInfinity. To access this number, type float, followed by a period operator, followed by the name of this field.

To let you find out whether a variable holds a negative infinity value, the structures of the floating-point number is equipped with a method named IsNegativeInfinity. The syntax of this method is:

public static bool IsNegativeInfinity(float f);

The Positive Infinity

On the other extreme, the possible largest number is named positive infinity. This field is represented in the .NET Framework by the PositiveInfinity value. To access this field, type float, a period, and this field. To find out if a variable's value is a positive infinity, you can call its IsPositiveInfinity() method. The syntax of this method ise:

public static bool IsPositiveInfinity(float f);

To check whether the value of a variable is one of the infinities, you can call its IsInfinity() method. The syntax of this method is:

public static bool IsInfinity(float f);

Double-Precision Numbers

Introduction

When a variable is larger than the float can handle and requires more precision, you should declare it using either the var or the double keyword.

To let you display a floating-point number with double-precision to the console screen, both the Console.Write() and the Console.WriteLine() methods each has a syntax that takes a double argument. Their syntaxes are:

public static void Write(double value);
public static void WriteLine(double value);

Here is an example:

using static System.Console;

var number = 62834.9023;

WriteLine("Number: " + number);

This would produce:

Number: 62834.9023
Press any key to close this window . . .

A variable declared as double uses 64 bits to store very large numbers ranging from 1.79769313486232e308 to 1.79769313486232e308 with a precision of 15 or 16 digits.

A Double-Precision Number

To support numbers with double-precision, the .NET Framework provides a structure named Double. This structure is equipped with the same members as the Single structure. These include the minimum and the maximum values. Here are examples:

using static System.Console;

WriteLine("===========================================================================================");
WriteLine("Float Minimum Value (Natural):     " + float.MinValue.ToString("N"));
WriteLine("Float Minimum Value (Exponential): " + float.MinValue.ToString("E"));
WriteLine("Float Maximum Value (Natural):     " + float.MaxValue.ToString("N"));
WriteLine("Float Maximum Value (Exponential): " + float.MaxValue.ToString("E"));
WriteLine("-------------------------------------------------------------------------------------------");
WriteLine("Double Minimum Value (Natural):     " + double.MinValue.ToString("N"));
WriteLine("Double Minimum Value (Exponential): " + double.MinValue.ToString("E"));
WriteLine("Double Maximum Value (Natural):     " + double.MaxValue.ToString("N"));
WriteLine("Double Maximum Value (Exponential): " + double.MaxValue.ToString("E"));
WriteLine("===========================================================================================");

This would produce:

===========================================================================================
Float Minimum Value (Natural):     -340,282,346,638,528,859,811,704,183,484,516,925,440.00
Float Minimum Value (Exponential): -3.402823E+038
Float Maximum Value (Natural):     340,282,346,638,528,859,811,704,183,484,516,925,440.00
Float Maximum Value (Exponential): 3.402823E+038
-------------------------------------------------------------------------------------------
Double Minimum Value (Natural):     -179,769,313,486,231,570,814,527,423,731,704,356,798,070,567,525,844,996,598,917,476,803,157,260,780,028,538,760,589,558,632,766,878,171,540,458,953,514,382,464,234,321,326,889,464,182,768,467,546,703,537,516,986,049,910,576,551,282,076,245,490,090,389,328,944,075,868,508,455,133,942,304,583,236,903,222,948,165,808,559,332,123,348,274,797,826,204,144,723,168,738,177,180,919,299,881,250,404,026,184,124,858,368.00
Double Minimum Value (Exponential): -1.797693E+308
Double Maximum Value (Natural):     179,769,313,486,231,570,814,527,423,731,704,356,798,070,567,525,844,996,598,917,476,803,157,260,780,028,538,760,589,558,632,766,878,171,540,458,953,514,382,464,234,321,326,889,464,182,768,467,546,703,537,516,986,049,910,576,551,282,076,245,490,090,389,328,944,075,868,508,455,133,942,304,583,236,903,222,948,165,808,559,332,123,348,274,797,826,204,144,723,168,738,177,180,919,299,881,250,404,026,184,124,858,368.00
Double Maximum Value (Exponential): 1.797693E+308
===========================================================================================

Press any key to close this window . . .

Characteristics of a Double-Precision Value

The Epsilon

The double data type uses the same characteristics we reviewed for the float data type and its accompanying Single structure. The members of their structures are the same, Only some values are different. As we saw, the smallest positive number is the epsilon. For a double-precision type, the epsilon value is equivalent to 4.94065645841247-324.

A Better Floating-Point Number

Because the double data type provides a better result with better precision than the float, whenever you declare a variable using either the var or the float keyword and assign it a value, the compiler allocates 64 bits to store the values of the variable. If you insist on the variable being treated as float, when assigning it a value, add an f or an F suffix to the value. Here is an example:

using static System.Console;

float distance = 248.38F;

WriteLine("Distance: " + distance + " km");
WriteLine("========================");

This would produce:

Distance: 248.38 km
========================

Press any key to close this window . . .

This would produce:

Distance = 248.38km

Remember that if you declare the variable as var and want to treat it as a value with single precision, add an f or an F suffix to the value assigned to it. Here is an example:

using static System.Console;

var number = 62834.9023F;

WriteLine("Number: " + number);
WriteLine("========================");

This would produce:

Number: 62834.902
========================

Press any key to close this window . . .

On the other hand, if you want a value to be treated with double-precision, add a d or a D suffix to it. Here is an example:

using static System.Console;

var number = 62834.9023D;

WriteLine("Number: " + number);
WriteLine("========================");

This would produce:

Number: 62834.9023
========================

Press any key to close this window . . .

A Decimal Number

Introduction

To support small to extremely large numbers, the C# language provides a data type named decimal. Use that keyword to declare a variable that would hold significantly large values that can be stored in a combination of 128 bits. The values stored in a decimal variable can range from -79,228,162,514,264,337,593,543,950,335 to 79,228,162,514,264,337,593,543,950,335.

Initializing a Decimal

After declaring a decimal variable, you can initialize it with a natural number. To indicate that the variable holds a decimal value, when initializing it, add an m or an M suffix to its value.

To let you display a decimal number to the console screen, both the Console.Write() and the Console.WriteLine() methods each has a syntax that takes a decimal argument. Their syntaxes are:

public static void Write(decimal value);
public static void WriteLine(decimal value);

Here is an example:

using static System.Console;

decimal hourlySalary = 24.25M;

WriteLine("Hourly Salary = {0}", hourlySalary);
WriteLine("========================");

This would produce:

Hourly Salary = 24.25
========================

Press any key to close this window . . .

Decimal Number Support

To support numeric values with high precision, the .NET Framework provides a structure named Decimal. This structure provides the characteristics of the C#'s decimal type. The structure has the same members we reviewed for the Single and the Double structures.

Distinguishing the Floating-Point Variables

As seen in previous sections and this one, when declaring and initializing a real variable, the suffix you give to its assigned value indicates to the compiler the actual type of value and the type of memory that would be allocated for the variable:

Consider the following program:

using static System.Console;

Write("560 / 672 = ");
WriteLine(560 / 672);

The purpose of this program is to get the division of 560 by 672. This would produce:

560 / 672 = 0
Press any key to close this window . . .

Notice that, when such numbers are submitted to the program, the compiler decides that these are integers and the result produces 0. If you write such an equation and want the result to appear as a real number, you must explicitly indicate it to the compiler. One way you can do this consists of adding decimal places to at least one of the numbers. Here is an example:

using static System.Console;

WriteLine("560 / 672 = {0}", 560.00 / 672.00);
WriteLine("===============================");

This time, the compiler will conclude that the value is a floating-point number; but which one? By default, the compiler would apply the double data type. This version of the program would produce:

560 / 672 = 0.8333333333333334
===============================

Press any key to close this window . . .

If you want to indicate that the value is a float, a double, or a decimal, add the appropriate prefix to it: f, F, d, D, m, or M. Here are examples:

using static System.Console;

WriteLine("560 / 672 = {0}", 560F / 672f);
WriteLine("================================================");

This version of the program would produce:

560 / 672 = 0.8333333
================================================

Press any key to close this window . . .

The Boolean Type

Introduction

As seen in previous lessons, the bool data type is used to represent a value considered as being true or false. In the .NET Framework, the bool data type is represented by a structure named Boolean. The true value of a bool variable is represented by a field named TrueString. The false value is represented by a field named FalseString. In other words, when true (or false) is represented as a string, "true" (or "false") is the same as TrueString (or FalseString).

Parsing a Boolean Variable

You can retrieve the value of a Boolean variable from a user. To support this, the Boolean structure is equipped with a static method named Parse. The Boolean.Parse() method is declared as follows:

public static bool Parse(string value);

This method takes as argument a string. The argument must contain either the word True or the word False (case-insensitive in both cases). If the argument is passed as "True", the method returns true. If the argument is "false", this method returns false.

When calling the Boolean.Parse() method to retrieve the value of a Boolean variable, if the supplied value is "True" or "False", the compiler would process it. If the value is not valid, the program would produce an error.

To avoid the error, the Boolean structure provides the TryParse() method. Its syntax is:

public static bool TryParse(string value, out bool result);

The first argument is the value to be parsed. If that value is valid, the second argument holds the True or False value of the first.

Consider the following code:

bool alt;
bool HouseHas3Bedrooms = bool.TryParse("False", out alt);

The first argument returns True although it was passed as False. This means that, if the value of the first argument is valid, it is the second argument, not the first, that holds the result. If the first argument is not valid, the second argument returns a False value. Consider the following version of the program:

bool alt;
bool HouseHas3Bedrooms = bool.TryParse("Don't Know", out alt);

The Default Value of a Type

Introduction

In previous sections, we saw that each data type has a range of value from one minimum to a maximum. In the same way, every type has a default value. For an integer, the default value is 0. For a decimal type, the default value is 0.00. To get the default value of a type, you can use a keyword named default. When declaring a variable of a primitive type, if you want it to hold a default value based on its type, assign the default keyword to it. Here are examples:

using static System.Console;

byte bits = default;
short small = default;
int natural = default;
float single = default;
double dbl = default;
decimal dec = default;

WriteLine("Default Values");
WriteLine("-----------------------");
WriteLine("Byte Integer:     {0}", bits);
WriteLine("Small Integer:    {0}", small);
WriteLine("Natural Number:   {0}", natural);
WriteLine("Single Precision: {0}", single);
WriteLine("Double Precision: {0}", dbl);
WriteLine("Decimal Number:   {0}", dec);
WriteLine("=======================");

This would produce:

Default Values
-----------------------
Byte Integer:     0
Small Integer:    0
Natural Number:   0
Single Precision: 0
Double Precision: 0
Decimal Number:   0
=======================

Press any key to close this window . . .

Selecting the Default Value

In the above examples, we let the compiler use the default value of the variable we were declaring. In some cases, you may want the value to hold the default value of a different data type. To do this, you can use an operator named default. It is used as a function. Its syntax is:

value-type default(data-type);

Write the default operator and apply some parentheses to it. In the parentheses, write the data type whose default value you want to access. You can assign the expression to a variable. If you are declaring the variable using either the var or the dynamic keyword, you can pass any type to the default() operator. If you declare the variable using a known type, the size of the data type passed to the default() operator must be equal or less than that of the type of the variable. Here are examples:

using static System.Console;

var bits = default(decimal);
dynamic small = default(double);
int natural = default(short);
float single = default(byte);
double dbl = default(short);
decimal dec = default(int);

WriteLine("Default Values");
WriteLine("-----------------------");
WriteLine("Byte Integer:     {0}", bits);
WriteLine("Small Integer:    {0}", small);
WriteLine("Natural Number:   {0}", natural);
WriteLine("Single Precision: {0}", single);
WriteLine("Double Precision: {0}", dbl);
WriteLine("Decimal Number:   {0}", dec);
WriteLine("=======================");

This would produce:

Default Values
-----------------------
Byte Integer:     0
Small Integer:    0
Natural Number:   0
Single Precision: 0
Double Precision: 0
Decimal Number:   0
=======================

Press any key to close this window . . .

The Default Value of an Object

Like a regular variable, an object (a variable declared from a class or structure) has a default type. Normally, the default value of an object is null. To make a declared object hold a default value, assign the default operator to the object. This is also valid for strings and object variable. Here are examples:

using static System.Console;

var bits = default(decimal);
dynamic small = default(double);
int natural = default(short);
float single = default(byte);
double dbl = default(short);
decimal dec = default(int);
string? something = default;
object? obj = default;
House? prop = default;

WriteLine("Default Values");
WriteLine("-----------------------");
WriteLine("Byte Integer:     {0}", bits);
WriteLine("Small Integer:    {0}", small);
WriteLine("Natural Number:   {0}", natural);
WriteLine("Single Precision: {0}", single);
WriteLine("Double Precision: {0}", dbl);
WriteLine("Decimal Number:   {0}", dec);
WriteLine("-----------------------");
WriteLine("String:           {0}", something);
WriteLine("Object:           {0}", obj);
WriteLine("House:            {0}", prop);
WriteLine("=======================");

public class House
{
    public int Bedrooms { get; set; }
    public float Bathrooms { get; set; }
    public double MarketValue { get; set; }
}

This would produce:

Default Values
-----------------------
Byte Integer:     0
Small Integer:    0
Natural Number:   0
Single Precision: 0
Double Precision: 0
Decimal Number:   0
-----------------------
String:
Object:
House:
=======================

Press any key to close this window . . .

Setting the Default Value of a Property

We already know that, when you have created a class, before using it in a program, you must initialize its object. One way to do this is to assign a value to its property. We saw that another or better way to take care of this issue is to assign a value to each property when creating the class. Here is an example:

using static System.Console;

House? property = new();

WriteLine("House Values");
WriteLine("-----------------------");
WriteLine("Bedrooms:     {0}", property.Bedrooms);
WriteLine("Bathrooms:    {0}", property.Bathrooms);
WriteLine("Market Value: {0}", property.MarketValue);
WriteLine("=======================");

public class House
{
    public int Bedrooms { get; set; } = 3;
    public float Bathrooms { get; set; } = 2.5f;
    public double MarketValue { get; set; } = 366_580;
}

This would produce:

House Values
-----------------------
Bedrooms:     3
Bathrooms:    2.5
Market Value: 366580
=======================

Press any key to close this window . . .

The above example supposes that you know from the begining the values you want the properties to hold. In some cases you don't know or don't have those initial values. To still make sure that a property has an initial value, you can assign it the default operator when creating the class. Here are examples:

using static System.Console;

House? property = new();

WriteLine("House Values");
WriteLine("-----------------------");
WriteLine("Bedrooms:     {0}", property.Bedrooms);
WriteLine("Bathrooms:    {0}", property.Bathrooms);
WriteLine("Market Value: {0}", property.MarketValue);
WriteLine("=======================");

public class House
{
    public int Bedrooms { get; set; } = default;
    public float Bathrooms { get; set; } = default;
    public double MarketValue { get; set; } = default;
}

This would produce:

House Values
-----------------------
Bedrooms:     0
Bathrooms:    0
Market Value: 0
=======================

Press any key to close this window . . .

Previous Copyright © 2001-2026, FunctionX Friday 26 November 2021 Next