Real Numbers in NewtonScript

One of the Newton 2.x OS Q&As
Copyright © 1997 Newton, Inc. All Rights Reserved. Newton, Newton Technology, Newton Works, the Newton, Inc. logo, the Newton Technology logo, the Light Bulb logo and MessagePad are trademarks of Newton, Inc. and may be registered in the U.S.A. and other countries. Windows is a registered trademark of Microsoft Corp. All other trademarks and company names are the intellectual property of their respective owners.


For the most recent version of the Q&As on the World Wide Web, check the URL: http://www.newton-inc.com/dev/techinfo/qa/qa.htm
If you've copied this file locally, click here to go to the main Newton Q&A page.
This document was exported on 7/23/97.


Real Numbers in NewtonScript (3/28/97)

Q: How are real numbers represented as floating point in NewtonScript? How accurate are they? What about infinities, NANs, and other exceptions?

A: Real numbers in NewtonScript are represented as IEEE 64-bit floating point numbers, which are accurate to about 15 decimal digits. You can read more about the IEEE floating point numbers in "Inside Macintosh: PowerPC Numerics" available online at the URL:
        http://gemma.apple.com/dev/techsupport/insidemac/PPCNumerics/PPCNumerics-2.html

The Newton floating point environment is not as rich in features as the PowerPC environment, and the PowerPC numerics document is only mentioned as a useful resource for understanding floating point issues. It in no way documents API or features of the Newton floating point environment.

Briefly, numbers are represented by 1 bit of sign ("on" is negative), 11 bits of exponent, and 52 bits of fractional part. The exponent bits are stored in excess 0x3FF, that is, 0x3FF is the representation for 0, values greater than 0x3FF are positive exponents, and values less than 0x3FF are negative exponents. The 52 bits of fractional part actually provide 53 bits of accuracy, because the initial 1 bit is dropped.

For example, suppose that we want to convert 9 97/128 into IEEE 64 bit format:
1) convert to base 2
1001.1100001
2) shift number to the form of 1.yyyyyy * 2^Z
1.0011100001 * 2^3
3) add 0x3FF (excess 0x3FF) to exponent field, convert to binary.
3+0x3FF = 0x402 = 100 0000 0010
4) now put the numbers together, using only the fractional part of the number represented above, in the form of yyyyyy
0 10000000010 0011100001000000000000000000000000000000000000000000
in hex representation, this is 0x4023840000000000
5) Just to verify, try it: StrHexDump(9+97/128, 16) -> "4023840000000000"

The IEEE standard also allows for non-normal numbers. Here are the exceptions:
infinity e = 7FF, f = 0 (+ or - depending on sign bit)
NaN e = 7FF, f <> 0 (also overflow, error, etc.)
zero e = 0, f = 0 (+ or -, depending on sign bit)
subnormal e = 0, f <> 0 (these are less precise numbers, smaller than the smallest normal number)

Note that there is more than one not a number value. In fact, there are quite a large number. The IEEE spec assigns meaning to various NaN values, as well as defining signalling and quiet NaNs. NewtonScript does not distinguish between NaN values. One NaN is as good as another.

In NewtonScript, real numbers are 8-byte binary objects of class 'real. In addition to the NewtonScript floating point literal syntax, you can use the compile time function MakeBinaryFromHex to construct real numbers, and you must use this style for custom NaN values. The most recent platform files for Newton 2.0 and Newton 2.1 provide constants for negative zero (kNegativeZero), positive and negative infinity (kInfinity, kNegativeInfinity), and a canonical NaN (kNaN).
MakeBinaryFromHex("4023840000000000", 'real) -> 9.7578125 // = 9+97/128