Floating-point: Bit Value of INF, NAN, DEN

Posted September 26th, 2008 in General C++, Numeral by Mason

I have every write a post and mentioned a little bit about the binary format of IEEE 754 in Comparison of Float and Double Precision. In this post I made a table to indicate the details of bit values for the IEEE 754 32bit single-precision float, the bit values of some special floating point value, including Zero, One, Minus One, Smallest denormalized number, “Middle” denormalized number, Largest denormalized number, Smallest normalized number, Largest normalized number, Positive infinity, Negative infinity, Not a number (NaN).

Capture 2008-09-26 13.12.57

In the column “Watch in Windows”, I put what I can see from the watch window in Visual Studio 2008 (Visual C++ Environment).

Performance: encapsulate floating point and built-in tolerance

Posted September 11th, 2008 in General C++, Numeral by Mason

When it comes to the floating point comparison with tolerance, two approaches come into my mind.

The first approach is to write inline functions and call them when compare floating point numbers. It is easy to understand and is widely used by numerous applications. Yes, it is really simple and I like it. The only concern is that I have to call these functions explicitly when compare two float or double variables, and I have to be aware of the code where it is necessary to compare with tolerance.

The second approach is to encapsulation floating point using a class. A float variable is the only member variable and I have to override lots of operators, assignment operator, relational and equality operators to control flow, arithmetic, unary, prefix and postfix operators. But how to implement the class is not a big deal, I’m worrying about the performance decrease which is introduced by using classes instead of pure machine data type.

Then I write the first to my open source library LibG, and made unit test for performance. The result looks good to me.

Testing Environment
Hardware1: CPU: AMD Sempron 2600+ (1.6G Hz). Memory: 1G, DDR400
Hardware2: CPU: Intel Core2 6300 (1.86G Hz). Memory: 4G
Software: Windows XP Professional with SP2

Testing Method
Repeat 15million times of a set of operations. There are one additional assignment, one comparison and one pre-decrement to complete the loop. Run 10 times and get average time.

Source Code
Open source portal of LibG: http://code.google.com/p/libg/
The class giFloat and giDouble: http://code.google.com/p/libg/source/browse/trunk/inc/gifloat.h
The testing code: http://code.google.com/p/libg/source/browse/trunk/test/libg_unit_test/test_gifloat.cpp

Testing Result
1. Arithmetic Operations: Operations Set: +, -, *, /, +=, -=, *=, /=

Testing Result (ms) float giFloat double giDouble
Hardware1 856.3 837.3 336.1 337.6
Performance   +2.22%   -0.45%
Hardware2 517.2 517.3 528.1 504.7
Performance   -0.02%   +4.43%
The performance of using class is very close to machine data type.

2. Relational and Equality Operations: Operations Set: ==, !=, >, >=, <, <=

Result float
(no tolerance)
float
(inline functions)
giFloat double
(no tolerance)
double
(inline functions)
giDouble
Hardware1 378.1 667.2 734.4 270.3 435.9 482.8
Performance     -10.07%     -9.71%
Hardware2 165.6 282.8 312.7 151.4 237.7 237.3
Performance     -9.56%     +0.12%
Comparing with using inline functions, the performance of using class decreased about 10%, it’s acceptable to me. The data type double is the most frequently used type on geometry computation, the performance result on Intel Core2 CPU is exciting.

Include Guard: #pragma once vs. #ifndef #define #endif

Posted September 6th, 2008 in General C++ by Mason

In the C and C++ programming languages, an include guard, sometimes called a macro guard, is a particular construct used to avoid the problem of double inclusion when dealing with the #include directive. The addition of include guards to a header file is one way to achieve this. pragma once is a non-standard but widely supported preprocessor directive designed to cause the current source file to be included only once in a single compilation. Both approaches specify that the file will be included only once by the compiler when compiling a source code file.

The table below compared the details of pragma once and #ifndef #define #endif approach:

pragma once #ifndef #define #endif
Sample code
// header file
#pragma once
class foo { };
// header file
#ifndef FOO_HEADER
#define FOO_HEADER
class foo { };
#endif // FOO_HEADER
C++ Standard No

But both GCC and Microsoft Visual C++ support it.

Yes
Compiling Performance Better

This can reduce build times as the compiler will not open and read the file after the first #include of the module.

It will still have to open the file multiple times, and discard the guard part when compiler find the macro guard. In a large project this could cause increased compile times.

But you can also optimize the compiling performance of #ifdef #define #endif approach by this way.