June 96 - 64-Bit Integer Math on 680x0 Machines
64-Bit Integer Math on 680x0 Machines
DALE SEMCHISHEN
When an application has to perform integer arithmetic with
numbers larger than 32 bits on both the PowerPC and 680x0
platforms, you could use the floating-point types of the SANE and
PowerPC Numerics libraries. But if all you really need is a larger
integer, a better choice is to use the existing 64-bit math routines
available on the PowerPC platform and write an equivalent library
for the 680x0 Macintosh. This article presents just such a library.
Developers of PowerPC applications that need 64-bit math can simply call the various
"wide" Toolbox routines. These routines perform addition, subtraction, multiplication,
division, square root, and a few other operations. On the 680x0-based Macintosh,
some of these same routines are available in QuickDraw GX. But if you can't assume
your customers have QuickDraw GX installed, you need a library that supports 64-bit
math.
The Wide library presented in this article works on both platforms and has exactly the
same interface and types as the wide routines in the Toolbox on PowerPC machines. The
library also provides some new routines such as 32-bit to 64-bit add and subtract
and a 64-bit-to-string conversion function. The library is included on this issue's
CD, along with its source code.
All the routines use the 64-bit data type defined in the header file Types.h, which is
the standard type used for signed 64-bit integers on both the PowerPC and 680x0
Macintosh:
struct wide {
Sint32 hi; /* upper 32 bits (signed) */
Uint32 lo; /* lower 32 bits (unsigned) */
};
typedef struct wide wide, *WidePtr;
THE WIDE ROUTINES
Before plunging into the Wide library, let's see what 64-bit math routines I'll be
talking about. First, I'll introduce those that are available on PowerPC machines, then
those you'll find on a 680x0 Macintosh with QuickDraw GX, and finally the routines in
the Wide library.
POWERPC TOOLBOX
In the header file FixMath.h, the routines listed in Table 1 are defined for 64-bit math
on the PowerPC platform.
680X0 QUICKDRAW GX
On 680x0 machines that have QuickDraw GX installed, all the wide routines for the
PowerPC platform listed in Table 1 are available, with the exception of WideBitShift.
The QuickDraw GX header file GXTypes.h defines the wide routine types and function
prototypes in exactly the same way that the header file FixMath.h does for PowerPC
machines.
In addition, QuickDraw GX on 680x0 machines has a routine that the PowerPC
platform doesn't have: WideScale. This function returns the bit number of the
highest-order nonzero bit in a 64-bit number. The Wide library implements this
function on the PowerPC platform.
THE WIDE 64-BIT LIBRARY
The Wide 64-bit integer math library on this issue's CD provides all the wide
routines that are available on PowerPC machines and on 680x0 machines with
QuickDraw GX, plus a few extras. The extra routines, which are available on both the
PowerPC and 680x0 platforms, are listed in Table 2.
WideAssign32, WideAdd32, WideSubtract32. These routines are
self-explanatory.
WideToDecStr.This routine converts a signed 64-bit integer to the SANE string type
decimal, which is also defined by the PowerPC Numerics library. This string
structure is a good intermediate format for final conversion to a string format of your
choosing.
Since WideToDecStr calls the SANE library to generate the string, SANE must be linked
with your 680x0 application. The SANE library is included with all the major
development systems.
To convert the string returned by WideToDecStr to a Pascal string, call the SANE
routine dec2str.
If you want to generate a localized number, take a look at the article
"International Number Formatting" in develop Issue 16. You could call the
LocalizeNumberString function from that article after converting the output
of WideToDecStr to a Pascal string, or you could modify LocalizeNumberString
to accept the output of WideToDecStr.*
p>WideInit.The library is self-initializing; the first time you call any wide routine,
WideInit is also called. If the execution speed of your first runtime call to a wide
routine is important, you have the option of calling WideInit during your application's
startup to avoid that overhead.
The purpose of WideInit is to determine what processor is being used, or emulated; it
calls Gestalt to make this determination. If your Macintosh has a 68020-68040 CPU
(68020, 68030, or 68040), the library will use the 64-bit multiply and divide
instructions available on that processor; otherwise, the library will have to call
software subroutines for those operations. On 68000 machines, such as the Macintosh
Plus and SE, the processor's multiply instruction is limited to 32 bits and the library
has no choice but to use the slower algorithmic approach for multiplication and
division.
SOURCE CODE ON A PLATTER
The library can be compiled on the 680x0 and PowerPC platforms using either the
Metrowerks CodeWarrior or Symantec C development system. The library tests which
development system is compiling it and, if it's not CodeWarrior or Symantec, the
preprocessor displays an error message saying the library needs to be ported to your