19.10.2012 Views

Designing and Building Portable Systems in C++ - Applied Informatics

Designing and Building Portable Systems in C++ - Applied Informatics

Designing and Building Portable Systems in C++ - Applied Informatics

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

2.5 Float<strong>in</strong>g Po<strong>in</strong>t Types<br />

Similar to <strong>in</strong>teger types, the <strong>C++</strong> st<strong>and</strong>ard does not specify any particular b<strong>in</strong>ary<br />

representation for float<strong>in</strong>g po<strong>in</strong>t numbers. The st<strong>and</strong>ard def<strong>in</strong>es three float<strong>in</strong>g po<strong>in</strong>t types:<br />

float, double <strong>and</strong> long double. Type double must provide at least as much precision as<br />

float, <strong>and</strong> long double must provide at least as much precision as double. Furthermore,<br />

the set of values of the type float must be a subset of the values of type double <strong>and</strong> the set<br />

of values of the type double must be a subset of the values of type long double. Although<br />

not required by the st<strong>and</strong>ard, the implementation of float<strong>in</strong>g po<strong>in</strong>t arithmetic used by most<br />

<strong>C++</strong> compilers conforms to a st<strong>and</strong>ard, IEEE 754-1985, at least for types float <strong>and</strong> double.<br />

This is directly related to the fact that the float<strong>in</strong>g po<strong>in</strong>t units of modern CPUs also implement<br />

this st<strong>and</strong>ard. The IEEE 754 st<strong>and</strong>ard specifies the b<strong>in</strong>ary format for float<strong>in</strong>g po<strong>in</strong>t numbers,<br />

as well as the semantics for float<strong>in</strong>g po<strong>in</strong>t operations.<br />

Byte order also applies to float<strong>in</strong>g po<strong>in</strong>t types, so on a big-endian mach<strong>in</strong>e, the constant π =<br />

3.1415926... (or, strictly speak<strong>in</strong>g, an approximation of it) as a float value, will be stored as<br />

0x40 0x49 0x0F 0xDB, while on a little-endian mach<strong>in</strong>e it will be stored as 0xDB 0x0F 0x49<br />

0x40. Of all three float<strong>in</strong>g po<strong>in</strong>t types, long double is the least portable. Some systems do not<br />

support long double directly; on these systems, it is the same size as a double. Byte order<br />

issues aside, float <strong>and</strong> double values usually can be exchanged <strong>in</strong> b<strong>in</strong>ary format between<br />

platforms; long double values cannot.<br />

The IEEE 754 st<strong>and</strong>ard has some special features, <strong>and</strong> they are a major reason for problems<br />

when port<strong>in</strong>g float<strong>in</strong>g po<strong>in</strong>t code between platforms. NaN (Not a Number) is a special value<br />

represent<strong>in</strong>g the result of tak<strong>in</strong>g the square root of a negative number. Inf<strong>in</strong>ity is the result of a<br />

divide by zero. Signed zero means there are two representations for zero: +0 <strong>and</strong> –0. There are<br />

also gradual underflow <strong>and</strong> denormal numbers, but these two features are not universally<br />

available. F<strong>in</strong>ally, there are various round<strong>in</strong>g modes, float<strong>in</strong>g po<strong>in</strong>t exceptions <strong>and</strong> flags,<br />

which may be useful to some applications. <strong>C++</strong> does not provide support for work<strong>in</strong>g with<br />

these features (for example, check<strong>in</strong>g for NaN or Inf<strong>in</strong>ity), but there are usually non-st<strong>and</strong>ard<br />

functions provided by runtime libraries. Also, the C99 st<strong>and</strong>ard provides some support here.<br />

Neither the IEEE 754 nor the <strong>C++</strong> st<strong>and</strong>ard specify how transcendental functions like s<strong>in</strong>(),<br />

cos(), exp(), etc. have to be implemented. Therefore, for the same arguments, the results<br />

that these functions return on various platforms might not be the same. This is another reason<br />

for gett<strong>in</strong>g non-identical results for the same expression on different platforms. The st<strong>and</strong>ard<br />

also does not specify how the conversion from decimal float<strong>in</strong>g po<strong>in</strong>t values to their b<strong>in</strong>ary<br />

representation must be implemented.<br />

3 Operat<strong>in</strong>g System APIs<br />

Modern general-purpose operat<strong>in</strong>g systems give application <strong>and</strong> system programmers a<br />

variety of programm<strong>in</strong>g <strong>in</strong>terfaces to work with. At the lowest level, every operat<strong>in</strong>g system<br />

provides so-called system calls, system services or executive services – functions directly<br />

implemented <strong>in</strong> the operat<strong>in</strong>g system kernel, <strong>and</strong> <strong>in</strong>voked via some k<strong>in</strong>d of software <strong>in</strong>terrupt<br />

or trap mechanism. On a higher level are library functions, such as those from the C library on<br />

Unix. W<strong>in</strong>dows NT goes one step further <strong>and</strong> has so-called personalities or subsystems –<br />

different sets of programm<strong>in</strong>g <strong>in</strong>terfaces that are all implemented <strong>in</strong> terms of the low-level<br />

system services. The W<strong>in</strong>32 API is not, as one might easily guess, the native programm<strong>in</strong>g<br />

<strong>in</strong>terface of W<strong>in</strong>dows NT, but rather a higher-level API built atop the largely undocumented<br />

executive services.<br />

9

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!