C# Double Type

Value Double

Double keyword

Double is an 8-byte numeric type. It is used to store very large and very small values. It also stores fractional values such as 1.5 and negative values such as -1.5. It requires more memory than an int. It is one of the more useful number types in the C# language.

Keywords

This C# example program demonstrates the double type. Double is an 8-byte number.

Example

Note

The double type can be declared in much the same way as an int type: you use the 'double' type in the declaration, and can assign it using the assignment operator (=). It offers fractional values. Further it can accommodate very large and very small numbers.

This is because its encoding uses eight bytes, which is twice the number of bytes in an int. The additional four bytes provide more representations in the type. We show that the double is aliased (mapped) to the System.Double struct.

Program that uses double type [C#]

using System;

class Program
{
    static void Main()
    {
	// Use double type.
	double number = 1.5;
	Console.WriteLine(number);
	number = -1; // Can be negative
	Console.WriteLine(number);
	Console.WriteLine(number == -1); // Can use == operator
	Console.WriteLine(number + 100); // Can use + operator
	Console.WriteLine(number.GetType());
	Console.WriteLine(typeof(double));
	Console.WriteLine(double.MinValue);
	Console.WriteLine(double.MaxValue);

	// Find the memory usage for a double value.
	long bytes1 = GC.GetTotalMemory(false);
	double[] array = new double[1000 * 1000];
	array[0] = 1;
	long bytes2 = GC.GetTotalMemory(false);
	Console.WriteLine("{0} bytes per double", ((bytes2 - bytes1) / (1000 * 1000)));
    }
}

Output

1.5
-1
True
99
System.Double
System.Double
-1.79769313486232E+308
1.79769313486232E+308
8 bytes per double

Parameters

Programming tip

For developers concerned with performance, the double type has some drawbacks. When you pass a double as an argument, it is received as a formal parameter. This typically requires the bits to be copied into another memory location for the parameters. If you use an integer, only four bytes will be copied; if you use a double, eight bytes. The extra copying will impact performance.

Parse and TryParse

double.Parse and double.TryParse are static methods, meaning you call them on the "double" type. The difference between the two methods is that double.Parse throws exceptions, while double.TryParse does not. Here we see an example that demonstrates the different strings double.Parse methods can deal with.

Program that uses double.Parse [C#]

using System;

class Program
{
    static void Main()
    {
	//
	// Usage of double.Parse on various input strings.
	//
	string[] tests = new string[]
	{
	    "1,000.00",  // <-- This is 1000
	    "1.000",     // <-- This is 1
	    "0.201",     //
	    "00.001",    // <-- This is 0.001
	    "-0.01",     // <-- This is -0.01
	    "500000000", // <-- Five-hundred million
	    "0.0"        // <-- 0
	};

	foreach (string test in tests)
	{
	    double value = double.Parse(test);
	    Console.WriteLine(value);
	}

	//
	// Usage of double.TryParse on various unusual inputs
	//
	string[] unusuals = new string[]
	{
	    "NaN",              // <-- This can be parsed.
	    "MaxValue",         // <-- This fails.
	    "NegativeInfinity",
	    "Programmer",
	    "0.01-0.02",
	    "    0"             // <-- This succeeds and is 0.
	};

	foreach (string unusual in unusuals)
	{
	    double value;
	    if (double.TryParse(unusual, out value)) // Returns bool
	    {
		Console.WriteLine("Valid: {0}", value);
	    }
	}
    }
}

Output

1000
1
0.201
0.001
-0.01
500000000
0
Valid: NaN
Valid: 0
String type

Overview. The example contains two string arrays and two loops. The first loop uses double.Parse on each string, and no exceptions are thrown because the strings are valid numbers. These strings are typical doubles you will want to parse.

Second loop. The second loop in the example above contains unusual input. Four of the six input strings are not parsed. In those cases, double.TryParse returns false, but does not throw.

Tester-doer pattern. The double.TryParse method is an instance of the tester-doer pattern. This pattern describes methods that see if some action can be done before actually doing it. This removes the possibility of a parsing error. Using double.TryParse will enhance performance if you deal with lots of invalid input.

Tester-Doer Pattern TryParseFormat illustration

Correctly parsed strings. You can have numbers with commas for thousands, excess decimal places with zeros, excess leading zeros, negative signs, large numbers such as 500 million, zero with a decimal, and spaces surrounding the digits.

Note: The Convert.ToDouble method, when called with the string parameter overload, simply calls double.Parse internally after a null check. Therefore, this method is not useful. However, Convert.ToDouble also has other overloads that can be useful when not dealing with strings.

These two parsing methods are invaluable for when you are storing percentages in text files or databases. Additionally, for very large numbers that are not monetary values, double.Parse is useful. However, when dealing with currency values, investigate the decimal type and its parsing methods.

Percentage Decimal

Summary

The C# programming language

This overview demonstrated some facts about the C# double type. As a low-level type, the double comprises eight bytes of memory usage. And as a value type, it has clear efficiency advantages over any possible object-based replacements. For very accurate representations, you can instead choose the decimal type. The double type is a low-level numeric type that is the size of two ints put together, contiguous in memory.

Numeric Types
.NET