Now we come to the controversial one. As I pointed out back in 2011, the
% operator is the remainder operator. When extending the division and remainder operators from naturals to integers, I require that the following conditions be true for dividend
x, non-zero divisor
q and remainder
x == y * q + r
y are non-negative then
0 <= r < y
(-x) / y == x / (-y) == -(x / y)
Let’s take a look at the consequences of these three facts. Continue reading →
I’m going to use the same technique I used for Natural comparisons to do Integer comparisons: make a helper function that returns -1 if
x < y, 0 if
x == y and 1 if
x > y, and then have every entry point simply call that helper function. This way we know that all the operators are consistent. The big difference here of course is that I do not need to have a special case that says that null sorts before any value. Continue reading →
In the latest episode of the Coverity Development Testing Blog‘s continuing series “Ask the Bug Guys”, I dig into two questions about the null coalescing operator. This handy little operator is probably the least well understood of all the C# operators, but it is quite useful. Unfortunately, it is easy to accidentally use it incorrectly due to precedence issues.
As always, if you have questions about a bug you’ve found in a C, C++, C# or Java program that you think would make a good episode of ATBG, please send your question along with a small reproducer of the problem to
TheBugGuys@Coverity.com. We cannot promise to answer every question or solve every problem, but we’ll take a selection of the best questions that we can answer and address them on the dev testing blog every couple of weeks.
Almost all the
Integer operations are simply wrappers around the
Natural operations, plus some gear to deal with the signs. Continue reading →
The integers are an extension to the naturals that closes them over subtraction. Rather than do anything fancy, I’m simply going to say that an integer is a natural with an associated sign, and that zero is always “positive”. We don’t want to end up in a situation where there are two forms of zero, since that is confusing. (We could of course have three signs, positive, negative and zero, but, meh. We don’t gain any great benefits from having a third sign.)
This time however I’m going to make a struct. C# requires that
default(SomeStruct), where all the fields are their default values, be a valid value of the type. The default should logically be zero, as it is with all the built-in number types. So rather than checking for null, as we did with the reference type
Natural, I’m going to check the
sign field for null, which will only be possible if we’ve got a default struct. We’ll simply replace that with zero. (I am in general opposed to modifying the formal parameters of a method; I prefer to treat them as read-only variables. I’ll make an exception in this case because it keeps the code short and clear.) Continue reading →
We have only two operators left, integer division and remainder. We’ve left the most complicated two operations for last, so let’s tread carefully here.
(Only two? I’m not going to do bit shifting operators; I don’t think of them as operations on natural numbers. If you want them, obviously they are trivial: shifting right is just taking the tail, shifting left is appending a zero bit as the new head. Similarly I am not going to implement the bitwise logical operators. Nor am I going to do the unary plus operator, which wins my award for World’s Most Useless Operator. It is a no-op on both naturals and integers; if you really want it, it’s not hard to write. The unary minus operator makes no sense on naturals; the only legal operand value would be zero.) Continue reading →
Good heavens, I blew past my tenth blogoversary without even noticing it. My first blog post was on the 12th of September, 2003 and looking back I see that I made a whopping 36 posts in the two weeks that followed. That’s craziness; my publishing rate is now about a tenth of that. But of course then I had a huge backlog of material to publish that I had been collecting for years, so there you go.
Thanks all for helping me during my fabulous adventures; I appreciate it very much. Here’s to another ten years!
On today’s episode of the Coverity Development Testing Blog series Ask The Bug Guys we have two posts. I take on the question does explicit interface implementation violate encapsulation? and my colleague Jon follows up on my previous posting about increment operators to discuss the precedence of the increment operator and bonus, the meaning of local static in C/C++.
As always: if you have a question about some aspect of C, C++, C# or Java programming language design, or want to share an interesting bug that bit you in one of those languages, please send it (along with a concise reproducer of the problem) to
TheBugGuys@Coverity.com. We cannot promise to answer every question or solve every problem, but we’ll take a selection of the best questions that we can answer and address them here every couple of weeks.
Getting equality correct is surprisingly tricky in C#. The landscape is a bit of a confusing jumble:
!= operators are a syntactic sugar for static method calls, so it is dispatched based on the static (compile-time) type of both operands.
object.Equals(object) is a virtual method, so of course it dispatches on the runtime type of its receiver but not its argument. An override on a type T is required to handle any object as an argument, not just instances of T.
IEquatable<T>.Equals(T) by contrast takes a T.
- For reference types, you’ve got to consider comparisons to null even if it is an invalid value.
That’s four ways to implement equality already and we haven’t even gotten into
IComparable<T>.CompareTo(T), which also needs to be able to compute equality. Continue reading →
Ok, addition and multiplication are in the can. Those are the easy ones because the set of natural numbers is “closed” over those operations. That is, if you have any two naturals then both their sum and their product is also a natural. Not so subtraction! To see why, first we have to state what subtraction really is. Continue reading →