## Working with Numbers

### Conversions

Task | Functions | Examples |
---|---|---|

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); |

Formatting to hexadecimal | ToString(“X”); |
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 [32]; 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 [4]; rand.GetBytes (bytes); // Fill the byte array with random numbers. BitConverter.ToInt32 (bytes, 0).Dump ("A cryptographically strong random integer");