Nullable comparisons are weird

One of the C# oddities I noted in my recent article was that I find it odd that creating a numeric type with less-than, greater-than, and similar operators requires implementing a lot of redundant methods, methods whose values could be deduced by simply implementing a comparator. For an example of such, see my previous series of articles on implementing math from scratch.

A number of people commented that my scheme does not work in a world with nullable arithmetic (or, similarly, NaN semantics, which are similar enough that I’m not going to call out the subtle differences here.) That reminded me that I’d been intending for some time to point out that when it comes to comparison operators, nullable arithmetic is deeply weird. Check out this little program: Continue reading

Long division, part two

This is a sequel to my 2009 post about division of long integers.

I am occasionally asked why this code produces a bizarre error message:

Console.WriteLine(Math.Round(i / 6000000000, 5));

Where i is an integer.

The error is:

The call is ambiguous between the following methods: 
'System.Math.Round(double, int)' and 'System.Math.Round(decimal, int)'

Um, what the heck? Continue reading

What is the unchecked keyword good for? Part two

Last time I explained why the designers of C# wanted to have both checked and unchecked arithmetic in C#: unchecked arithmetic is fast and dangerous, checked arithmetic is slightly slower but turns subtle, easy-to-miss mistakes into program-crashing exceptions. It seems clear why there is a “checked” keyword in C#, but since unchecked arithmetic is the default, why is there an “unchecked” keyword?

Continue reading

What is the unchecked keyword good for? Part one

One of the primary design goals of C# in the early days was to be familiar to C and C++ programmers, while eliminating many of the “gotchas” of C and C++. It is interesting to see what different choices were possible when trying to reduce the dangers of certain idioms while still retaining both familiarity and performance. I thought I’d talk a bit about one of those today, namely, how integer arithmetic works in C#.
Continue reading

How much bias is introduced by the remainder technique?

(This is a follow-up article to my post on generating random data that conforms to a given distribution; you might want to read it first.)

Here’s an interesting question I was pondering last week. The .NET base class library has a method Random.Next(int) which gives you a pseudo-random integer greater than or equal to zero, and less than the argument. By contrast, the rand() method in the standard C library returns a random integer between 0 and RAND_MAX, which is usually 32768. A common technique for generating random numbers in a particular range is to use the remainder operator:

int value = rand() % range;

However, this almost always introduces some bias that causes the distribution to stop being uniform. Do you see why?
Continue reading

A practical use of multiplicative inverses

Last time we showed how you can take any two coprime positive integers x and m and compute a third positive integer y with the property that (x * y) % m == 1, and therefore that (x * z * y) % m == z % m for any positive integer z. That is, there always exists a “multiplicative inverse”, that “undoes” the results of multiplying by x modulo m. That’s pretty neat, but of what use is it?
Continue reading

Math from scratch, part twelve: Euclid and Bézout

Now that we have an integer library, let’s see if we can do some 2300-year-old mathematics. The Euclidean Algorithm as you probably recall dates from at least 300 BC and determines the greatest common divisor (GCD) of two natural numbers. The Extended Euclidean Algorithm solves Bézout’s Identity: given non-negative integers a and b, it finds integers x and y such that:

a * x + b * y == d

where d is the greatest common divisor of a and b. Obviously if we can write an algorithm that finds x and y then we can get d, and x and y have many useful properties themselves that we’ll explore in future episodes.

Continue reading