Archive

Archive for the ‘programming’ Category

Is IEE 754 too advanced?

August 24th, 2007 No comments

In my previous post I’m afraid I exposed my inexperience in the world of floating point programming. As many pointed out it’s the inherited behavior of the IEEE 754 standard, and, in Walter Brights own words, to change it would break legacy usage. In other words I should direct my concerns about the handling of uninitialized values toward the standard and not hold the D Programming Language responsible.

I still feel awkward, and to some extent astonished, that I can use an expression like (x != x) to check for an initialized floating point value, but not (x != real.nan). This behavior goes against my intuition.

NaN is defined to return false for all the normal comparison operators. The standard would have been better – in my opinion – if it made an exception for the equality (==) and not equality (!=) operators. It would save many of us from being caught by surprise.

Anyway, I guess you can’t fight an IEEE standard, so I hereby drop my case. 🙂

Update:

I read up on NaN:s in the IEEE 754 specification and found that Not A Number is not necessarily represented by one single value, but rather it could be a whole family of them. That complicates things, but the final nail in the coffin was put by Lars Noshinski on the official D newsgroup. He puts it in this convincing way:

“But you’d probably be surprised to see

0.0/0.0 == sqrt(-1.L)

evaluate to true.”

There is no arguing against that. So I guess the answer to the question in the title is: No, the IEEE 754 is just as advanced as it needs to be.

Update 2:

If you (like me) want to learn more about floating point numbers, there is a great sum up in the What Every Computer Scientists Should Know About Floating-point Arithmetic.

Categories: programming Tags:

Is D:s floating point handling too advanced?

August 23rd, 2007 3 comments

The floating point support in the D Programming Language is more advanced than that of standard C and C++. I’m not sure I like every aspect of it though. The thing I’m having problem with is how D handles the special value NAN (Not A Value).

For instance, a simple comparison will always return false if one or both of it’s operands are uninitialized (having the value of NAN). This produces the following unintuitive behavior:

if (real.nan != real.nan)
{
  writefln("It's strange, but you'll always see this text!");
}

I can see the reason why they chose the always-fail-if-NAN semantics for the other comparison operators, but not for equal-to and not-equal-to. In this case I think they went too far in their strive for consistency.

The consequence of the D floating point semantics is this: If you want to assert that a float value is initialized, for example in an invariant block, this won’t work:

class SomeClass {
  real someFieldVar;

  invariant {
    assert(someFieldVar != real.nan) {...}
  }

}

Neither will this:

assert(someFieldVar);

As a side note, if the value of someFieldVar is zero, the above expression would evaluate to false! This is why I never use non-boolean expressions where true or false are expected. I think that should be prohibited by the language.

Anyway, you have two options when checking for an uninitialized value. Neither is – in my humble opinion – particularly beautiful.

First, you could use one of the new NAN-aware binary operators that D introduces, like !<>=, !<, !>=, or !<>. These new operators just give me a headache, they don’t come naturally and I can’t seem to learn them. Here’s the best way I found to check for the uninitialized value using the new floating point operators:

assert(0 !<>= value);

That operator returns true if one or both operands are uninitialized. I don’t feel comfortable with that solution. It’s not obvious what the code does. In that sense, the only remaining alternative is better: using the std.math.isnan function.

import std.math;
:
assert(isnan(someFieldVar));

This is okay, but it feels a little clumsy and backwards using a function. It would have been much better if Walter Bright had used the more intuitive semantics for the normal equality operator. So that I didn’t have to depend upon the std.math namespace, and could write:

assert(someFieldVar != real.nan);

or even better, added a property to the floating point value:

assert(someFieldVar.isnan);
Categories: D Programming Language, programming Tags:

Agile low level programming in D

August 21st, 2007 2 comments

Agile software development techniques have long been utopia for low level system developers. The C programming language has been the most reasonable choice for implementing hardware near applications and drivers; But C was not designed with agility in mind. Hence methods like test driven development has been a pain to implement using C.

Now an alternative exists: The D Programming Language is designed to combine the low level programming abilities and performance of languages like C and C++, with the productivity features of modern languages.

You could describe D as C with features like object oriented programming, exception handling, garbage collection and design by contract. Cool agile features indeed, but D has another one that I instantly fell in love with: built in support for unit testing.

In D you can declare unittest blocks.

unittest {
  assert(sometest, "sometest failed");
}

The unittest construct makes it very easy to practice test-driven development. For instance, lets say we want to create a new type for three dimensional vectors. In order to be test-driven we need to start with the test:

unittest {
  Vector3 v;
}

We compile the program using the -unittest switch.

dmd -unittest test.d

Of course we get a compiler error, Vector3 is still undefined. Lets define it.

struct Vector3 {
}

This time the program compiles. Back to the unittest. Now let’s try a simple assignment.

unittest {
  Vector3 v = Vector3(1.0, 2.0, 3.0);
}

This, again, produces a compile time error. Vector3 doesn’t have the x, y and z fields, so we implement them.

struct Vector3 {
  real x, y, z;
}

The code passes compilation. Next step: implement vector addition. We start with the test.

unittest {
  Vector3 v1 = Vector3(1, 2, 3);
  Vector3 v2 = Vector3(3, 2, 1);
  Vector3 vr = v1 + v2;
}

As we expect, the code doesn’t compile. We need to overload the + operator.

struct Vector3 {
  real x, y, z;

  // Overload + operator
  Vector3 opAdd(Vector3 a)
  {
    return Vector3(0, 0, 0);
  }
}

Now the program compiles, but we don’t know if the add operator produces the right result (which it doesn’t with the current code). To check the result we can use assert.

unittest {
  Vector3 v1 = Vector3(1, 2, 3);
  Vector3 v2 = Vector3(3, 2, 1);
  Vector3 vr = v1 + v2;

  assert(vr.x == 4);
  assert(vr.y == 4);
  assert(vr.z == 4);
}

We compile, and it compiles without error. To run the unittest code we simply run the program. Unittest code is executed after program initialization, but before the main function. If a unittest fails the program terminates prematurely. Our program terminates (as expected) with an AssertError. Lets correct the add operator.

struct Vector3 {
  real x, y, z;

  Vector3 opAdd(Vector3 a)
  {
    return Vector3(x + a.x, y + a.y, z + a.z);
  }
}

It compiles and runs without errors. Great!

As you can see, test-driven development is a very smooth and simple process in D. There is no need for a separate framework, just compile and run your application. Also, the test code dwells close to the production code, which makes it easier to maintain and keep up-to-date. In fact, you can put unittest blocks anywhere in your code, even within the piece of code you are testing.

struct Vector3 {
  real x, y, z;

  // unittest blocks are allowed
  // within structs.
  unittest { ... }
}

Any type of code is allowed within a unittest block. This means that you can declare functions to do repetitive tasks.

unittest {
  function assertEqual(Vector3 a, Vector3 b)
  {
    assert(a.x == b.x);
    assert(a.y == b.y);
    assert(a.z == b.z);
  }

  Vector3 v1 = Vector3(1, 2, 3);
  Vector3 v2 = Vector3(3, 2, 1);

  assertEqual(v1 + v2, Vector3(4, 4, 4));
  assertEqual(v1 - v2, Vector3(2, 0, -2));
}

The test code is only included in the executable if it is compiled with the unittest flag, so there’s no need for a separate test project or conditional compilation. This is a very clean solution, highly suitable for a traditional language that compiles directly to machine code. Although I’m a big fan of testing framworks such as JUnit, I find it much easier to work with the built in unit testing features of D. Of course you don’t have advanced features like mock object support, but I guess that will be offered soon with some kind of unittest-based framework add-on.

If you have doubts about the foundation of the D Programming Language, you should be relieved to hear that it’s been designed by Walter Bright, who have spent almost a lifetime constructing C and C++ compilers.

You’ll find the complete code within my code sample pages.