## Working with Numbers

### Conversions

Parsing base 10 numbers Parse
TryParse
```double d = double.Parse("3.5");
int i;
bool ok = int.TryParse("3", out i);
```
Parsing from base2, 8, or 16 Convert.ToIntegral
```int i = Convert.ToInt32("1E", 16);
```
```string hex = 45.ToString("X");
```
Lossless Numeric Conversion Implicit 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);
```

### Math

Lists the members of the static Math class.

Category Methods
Rounding Round, Truncate, Floor, Ceiling
Maximum/Minimum Max, Min
Absolute value and sign Abs, Sign
Square root Sqrt
Raising to a power Pow, Exp
Logarithm Log, Log10
Trigonometric Sin, Cos, Tan

Floor always rounds down, Ceiling always rounds up – even with negative numbers. If you have array or sequence of numbers, use Max and Min extension methods in System.Linq.Enumerable.

### BigInteger

Lives in System.Numerics in namespace called System.Numerics.dll which allows you to represent an arbitrarily large integer without any loss of precision.

```// BigInteger supports arbitrary precision.

BigInteger twentyFive = 25;      // implicit cast from integer

BigInteger googol = BigInteger.Pow (10, 100);

// Alternatively, you can Parse a string:
BigInteger googolFromString = BigInteger.Parse ("1".PadRight (100, '0'));

Console.WriteLine (googol.ToString());

double g1 = 1e100;                  // implicit cast
BigInteger g2 = (BigInteger) g1;    // explicit cast
g2.Dump ("Note loss of precision");

// This uses the System.Security.Cryptography namespace:
RandomNumberGenerator rand = RandomNumberGenerator.Create();
byte[] bytes = new byte ;
rand.GetBytes (bytes);
var bigRandomNumber = new BigInteger (bytes);   // Convert to BigInteger
bigRandomNumber.Dump ("Big random number");
```

The advantage of storing such a number in a BigInteger over a byte is that you get value-type semantics. Calling ToByteArray converts a BigInteger back to a byte array.

### Complex

Represents real and imaginary components of type double. Complex resides in the System.Numerics.dll assembly.

```var c1 = new Complex (2, 3.5);
var c2 = new Complex (3, 0);

Console.WriteLine (c1.Real);       // 2
Console.WriteLine (c1.Imaginary);  // 3.5
Console.WriteLine (c1.Phase);      // 1.05165021254837
Console.WriteLine (c1.Magnitude);  // 4.03112887414927

Complex c3 = Complex.FromPolarCoordinates (1.3, 5);

// The standard arithmetic operators are overloaded to work on Complex numbers:
Console.WriteLine (c1 + c2);    // (5, 3.5)
Console.WriteLine (c1 * c2);    // (6, 10.5)

Complex.Atan (c1).Dump ("Atan");
Complex.Log10 (c1).Dump ("Log10");
Complex.Conjugate (c1).Dump ("Conjugate");
```

### Random

The Random class generates a pseudorandom sequence of random bytes, integers or doubles. Before using Random, you need to instantiate first with or without seed.

Next(n) – generates a random integer between 0 and n-1.

NextDouble – generates a random double between 0 and 1.

NextByte – fills a byte array with random values.

Random is not considered for high-security applications instead cryptography should be used.

```// If given the same seed, the random number series will be the same:
Random r1 = new Random (1);
Random r2 = new Random (1);
Console.WriteLine (r1.Next (100) + ", " + r1.Next (100));      // 24, 11
Console.WriteLine (r2.Next (100) + ", " + r2.Next (100));      // 24, 11

// Using system clock for seed:
Random r3 = new Random();
Random r4 = new Random();
Console.WriteLine (r3.Next (100) + ", " + r3.Next (100));      // ?, ?
Console.WriteLine (r4.Next (100) + ", " + r4.Next (100));      // ", "
// Notice we still get same sequences, because of limitations in system clock resolution.

// Here's a workaround:
Random r5 = new Random (Guid.NewGuid().GetHashCode());
Random r6 = new Random (Guid.NewGuid().GetHashCode());
Console.WriteLine (r5.Next (100) + ", " + r5.Next (100));      // ?, ?
Console.WriteLine (r6.Next (100) + ", " + r6.Next (100));      // ?, ?

// Random is not crytographically strong (the following, however, is):
var rand = System.Security.Cryptography.RandomNumberGenerator.Create();
byte[] bytes = new byte ;
rand.GetBytes (bytes);       // Fill the byte array with random numbers.

BitConverter.ToInt32 (bytes, 0).Dump ("A cryptographically strong random integer");
```