Recortes de mi Webeo


Using Floating Point Math

Posted in Palm OS por novaxo en 11 julio, 2007

Alternativas para el uso del punto decimal.

When Palm Computing designed the first Palm units, they were working with a severely resource-constrained platform: 128 K of RAM and 512 KB of ROM. At the same time, they chose to provide analogues for most of the C standard library’s functions in ROM, so user programs wouldn’t have to link in their own C library support: by using Palm OS’s StrPrintF() function instead of your compiler’s sprintf(), for example, you probably save several KB of RAM.

Unfortunately, Palm Computing wasn’t able to get the entire Standard C Library into ROM, and what they did manage to squeeze in has several compromises, particularly when it comes to floating point math. This article will show you the proper methods for using floating point math under Palm OS.

Converting a Floating Point Value to a String

If you poke through the Palm OS float managers, you’ll find FplFToA() and FlpFToA(), but these can only output in scientific notation. Furthermore, the Palm OS’s StrPrintF() does not have a %f format specifier. Instead, you can use Fred Bayer’s printDouble(), which is in the public domain. This compiles to about 900 bytes in my tests.

Converting a Numeric String to a Floating Point Value

There are many recipes for this floating about the `Net, but the simplest is built into Palm OS 2.0 and later: FlpAToF(). In places, the docs imply that this function requires input in exponential format like the similarly-named FplAToF() function from the old OS 1.0 float manager. Tests show that this is not the case; it happily parses any floating point number, going clear back to OS 2.0. If you write code that will be compiled with PRC-Tools, you should call FlpBufferAToF() instead, as in the example below. This is to work around a problem due to a gray area in the Palm OS ABI specification. GCC generates code to call FlpAToF() differently than CodeWarrior, and since it’s too late to change the ABI specification or either compiler to match the other, the 4.0 SDK added FlpBufferAToF() to work around the issue. This function works with both compilers and works on all OSes that support FlpAToF().

                #include <FloatMgr.h>

                double my_atof(const char* pc)
                {
                    FlpCompDouble fcd; 
                    FlpBufferAToF(&fcd.fd, pc);
                    return fcd.d;
                }

If for some reason the FlpAToF() method isn’t suitable, I recommend strToDouble() by David Bray. You might use this if you had to target OS 1.0 for some reason, or wanted to change the parsing rules. Be warned that this will add about 600 bytes to your executable over using FlpAToF().

Arithmetic, Geometric and Trigonometric Functions

None of the functions from C’s math.h are in Palm OS. The solution to this is to use MathLib, which is a Palm-ified version of the GNU C Library’s math functions. This is a 50 KB shared library that your users install separately from your program executable. Lots of other programs use it so your users might not have to install it, and there’s no size hit for Handspring Visor users because it’s in the Visor’s ROM. PRC-Tools users have an alternative to MathLib. At least as of 2.0.90, PRC-Tools includes a lightweight math library. Since it links into your program, you don’t have to require your users to install the 50 KB MathLib library. On the other hand, your program’s PRC will grow by several KB, which, multipled by the number of programs your users have installed that use math.h functions, may well exceed 50 KB.

PRC-Tools’ math library has two problems. First, it doesn’t yet seem very polished: I got several warnings and errors when trying to build my program with it. Second, it appears to use single-precision math, rather than the double-precision math specified by the ISO C Standard. I saw obvious calculation errors in my programs when I used it instead of MathLib. For example, when I built my program with PRC-Tools’ math library, it decided that pow(sqrt(2), 8) equals 15.9999996… When built with MathLib, it gives the correct answer, 16.0.

Still, if your needs are simple, this may be a better choice for you than MathLib.

Optimizing MathLib

If you need to use MathLib, you might be tempted to strip out the functions in it that you don’t use. That’s a bad idea because then you’d have to distribute a nonstandard MathLib, which would mean some users would have to have two different copies loaded. However, there is one small thing you can do to optimize your use of MathLib. When you build a program with MathLib, you have to include a “glue module” called MathLib.c into your project. This contains about 50 glue functions: when you call the standard C function tan(), that’s just a glue function that uses the Palm’s shared library mechanism to call MathLibTan(). Due to the way most linkers work, all of those glue functions get included into your program’s executable, even the ones you never call! It’s safe, however, to just remove them from MathLib.c and rebuild your program. The full version of that file compiles to about 1800 bytes on my system, but when stripped down to have only what my f/Calc program needs, it’s only about 300 bytes.

MathLib Bugs

I’ve discovered one bug in MathLib: the isinf() function does not detect infinite values correctly. Infinite numbers happen in floating point programming for roughly the same reasons that overflows occur in integer math, so many programs need to check for them. The only way I’ve found to check for infinite values is to check to see if the number is over 42 million. (There’s a higher, more exact value, but this approximation is good enough for my program’s purposes.) This implies that related MathLib functions finite() and isnan() may also be buggy, but I haven’t checked them.

Using MathLib with Newer SDKs

The current version of MathLib doesn’t build properly with anything newer than SDK 3.1. To make it work with SDK 3.5 or newer, you need to change the include for Pilot.h at the top of MathLib.c to this:

                #include <PalmOS.h>
                #include <PalmCompatibility.h>

MathLib.h needs a lot of changes, mainly because of all the typedefs that changed in SDK 3.5. Here’s my patched version of MathLib.h.

The Fpl* and Flp* Functions

The Fpl* functions constitute the original Float Manager (OS 1.0), and the Flp* functions are the New Float Manager (OS 2.0 and up). It used to be that to use floating point numbers, you had to use the old Float Manager functions directly. Advances in Palm OS compilers made direct calls to either float manager almost completely unnecessary. Very rarely you may need to call something in the New Float Manager; you should consider the old Float Manager should be completely off limits, since there are better alternatives across the board.

Last update: 18 Feb 2003

Fuente del recorte

Anuncios

2 comentarios to 'Using Floating Point Math'

Subscribe to comments with RSS o TrackBack to 'Using Floating Point Math'.

  1. Maximus said,

    I would like to see a continuation of the topic

  2. novaxo said,

    Hi Maximus,
    The las update of this topic is from 2003 and its imposible a continuation beacuse Palm is dying.


Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s


A %d blogueros les gusta esto: