# Fixed Point Maths

## version 5 by Michael Callaghan

Documentation

Fixed point maths is an extension to permit simple mathematical operations to be carried out on fixed point numbers.

Chapter : About Fixed Point Maths

Section : Introduction

Inform 7 allows the use of integer numbers and their addition, subtraction, multiplication and division. Division is limited to returning an integer result and, separately, a remainder. If we want to use more complex mathematical functions or non-integer numbers, there is no in-built facility to do so.

This extension allows us to use fixed point numbers in Inform 7, such as 12.2344. It includes a modest range of mathematical functions using fixed point numbers and, where appropriate, their equivalents for integer numbers. Details of the functions provided are set out in this documentation.

Section : How the extension works

Although Inform 7 allows only the use of integers, a number can be divided into two parts. See Chapter 14 of the manual. Therefore, we can use this flexibility to create fixed point numbers with an integer and a decimal part.

Section : Precision and range

Fixed point maths is set up for use with numbers that have four decimal places. The range of numbers supported is -214748.3648 to 214748.3647. Note that because we are using four decimal places and numbers only in the range -214748.3658 to 214748.3647, some functions can become subject to significant rounding errors when using very large or very small values.

Section : Defining fixed point numbers

When we are writing a fixed point number in Inform 7, we have to include all four decimal places, even if they are zeros. For example, if we want the number 12.5 as a fixed point number, we write 12.5000.

Fixed point numbers are a kind of value called real number. Therefore, we can create variables of this form in the following way:

TwoPi is a real number that varies. TwoPi is 6.2832.

Section : Saying fixed point numbers

Fixed point numbers can be negative. There is a problem (as at version 5T18 of Inform 7) that causes negative numbers to be printed incorrectly where the number consists of parts. Therefore, this extension uses a modified form of say statement with fixed point numbers. We use the form 'X as a number' in the say statement.

say "[TwoPi as a number]";
say "[-1234.6789 as a number]".

The issue with printing negative numbers has been resolved with version 5Z71, so we can now simply say:

say "[TwoPi]";
say "[-1.2345]".

The old form "as a number" is being retained for backwards compatability.

Section : Error checking

This extension does not include error checking routines. The most common error is division by 0. As all division operations reduce to integer division equivalents, division by 0 will be trapped by Inform 7 in any event. Overflow and underflow errors will not be checked so if you try to add, subtract, multiply or divide values and the results exceed the limits of the extensions precision, the results may not be as expected.

If you try to calculate the square root or log of a negative number, the result will always be 0.

Section : Credits

Thanks to Ron Newcomb and Mike Tarbert for their helpful comments that have helped to improve this extension. Any errors and omissions remain with the author.

Section : Version history

Version 5 - 1 February 2011: Corrected to work with version 6G60.

Version 4 - 16 June 2010: Deprecated features removed from Example B.

Version 3 - 1 August 2009: Allows for text to be converted to a real number.

Version 2 - 22 June 2009: Version numbering changed to prevent problems installing and using the extension under Inform 7.

Version 1.2 - 27 April 2009: Note added to indicate that real numbers can now be printed using simple say statements. Square root function renamed real sqaure root to avoid clashes with the new (integer based) square root in version 5Z71.

Version 1.1 - 14 September 2008: Small change to enable "The Classroom" to compile under 5U92.

Version 1.0 - 25 July 2008: First public release of Fixed Point Maths.

Chapter : Converting between number systems

Section : Finding the corresponding integer from a fixed point number

We can convert a fixed point number to an integer number using the phrase 'X as an integer'.

let val be 12.5678 as an integer.

This takes a fixed point number and turns it into the nearest integer. For example 2.1 becomes 2. 3.5611 becomes 4. -1.2345 becomes -1 and -1.7823 becomes -2.

0.5 is used as the boundary for rounding up or down so 12.4999 or below will round down to 12 and 12.5000 or above will round up to 13.

Section : Rounding up a fixed point number to an integer

We can convert a fixed point number to the next highest integer using the phrase 'X rounded up'.

let val be 12.0012 rounded up.

This always rounds away from 0. For example 2.1000 becomes 3 and -5.0123 becomes -6.

Section : Rounding down a fixed point number to an integer

We can convert a fixed point number to the next lowest integer using the phrase 'X rounded down'.

let val be 12.0012 rounded down.

This always rounds towards 0. For example 2.8888 becomes 2 and -5.7878 becomes -5.

Section : Absolute value of a number

We can find the absolute value of a number using the phrase 'the absolute value of X'.

let val be the absolute value of -12.3456;
let val be the absolute value of -45;

The function leaves positive values unchanged and converts negative numbers to their positive equivalent. -12.3456 becomes 12.3456, etc. This function works for both fixed point and integer numbers.

Section : Convert an integer to a fixed point number

We can convert an integer to a fixed point number using the phrase 'X as a fixed point number'.

let val be 5 as a fixed point number.

This converts 5 to 5.0000.

Section : Changing the sign of a number

We can change a positive number to a negative number and a negative number to a positive number using either of the phrases 'the reverse of X' or 'the negation of X'.

let val be the reverse of 25;
let val be the negation of 25;
let val be the reverse of -12.345;
let val be the negation of -12.345.

This converts 25 to -25 and -12.345 to 12.345. This function works for both fixed point and integer numbers.

Chapter : Comparisons between fixed point numbers

Section : Testing if two fixed point numbers are equal

If we want to test if two fixed point numbers are equal we use the phrase 'if X real equals Y'

if val1 real equals val2:
say "val1 is equal to val2".

We can also substitute an integer number on one side or other of the phrase but not on both sides.

Section : Testing if one fixed point number is greater than a second fixed point number

If we want to test if one fixed point number is greater than a second fixed point number we use the phrase 'if X is real greater than Y'

if val1 is real greater than val2:
say "val1 is greater than val2".

We can also substitute an integer number on one side or other of the phrase but not on both sides.

Section : Testing if one fixed point number is less than a second fixed point number

If we want to test if one fixed point number is less than a second fixed point number we use the phrase 'if X is real less than Y'

if val1 is real less than val2:
say "val1 is less than val2".

We can also substitute an integer number on one side or other of the phrase but not on both sides.

Section : Testing if a fixed point number is less than 0

If we want to test whether a fixed point number is less than 0, we use the phrase 'if X is negative'.

if val1 is negative:
say "val1 is less than 0".

We need a separate function for this as a fixed point number is made up of two number parts. -0.2333 contains the parts 0 and -2333. Testing only the first part of the number would give an incorrect result as it is not less than 0.

Chapter : Addition, subtraction, multiplication and division

We add two floating point numbers using the phrase 'X real plus Y'.

let val1 be 12.3333 real plus 45.4555;
let val1 be 2 real plus -3.3333;
let val1 be val1 real plus 10.

As we can see from these examples, integer numbers can be used within fixed point addition. The reason that we use real plus to designate fixed point addition is to avoid namespace clashes with the Inform 7 integer addition.

Section : Subtraction

We subtract two floating point numbers using the phrase 'X real minus Y'.

let val1 be 12.3333 real minus 45.4555;
let val1 be 2 real minus 3.3333;
let val1 be val1 real minus 10.

As we can see from these examples, integer numbers can be used within fixed point subtraction. The reason that we use real minus to designate fixed point subtraction is to avoid namespace clashes with the Inform 7 integer subtraction.

Section : Multiplication

We multiply two floating point numbers using the phrase 'X real times Y'.

let val1 be 12.3333 real times 45.4555;
let val1 be 2 real times -3.3333;
let val1 be val1 real times 10.

As we can see from these examples, integer numbers can be used within fixed point multiplication. The reason that we use real times to designate fixed point multiplication is to avoid namespace clashes with the Inform 7 integer multiplication.

Section : Division

We divide two floating point numbers using the phrase 'X real divided by Y'.

let val1 be 12.3333 real divided by 45.4555;
let val1 be 2 real divided by -3.3333;
let val1 be val1 real divided by 10.

As we can see from these examples, integer numbers can be used within fixed point division. The reason that we use real divided by to designate fixed point division is to avoid namespace clashes with the Inform 7 integer division.

Section : Inverse

We can calculate the inverse (1/x) of a number using the phrase 'the inverse of X':

let val be the inverse of 3.0000;
let val be the inverse of 5.

We can use the inverse function with both fixed point numbers and integer numbers.

Section : Factorial

We can calculate the factorial of an integer number using the phrase 'the factorial of X'.

let val be the factorial of 5.

Section : Simple powers

We can raise an integer number or a fixed point number to the power of a whole number using the phrase 'X to the power Y'.

let val be 3 to the power 5;
let val be 4.5555 to the power 4.

As a short cut for squares and cubes of numbers, we can use:

let val be 4 squared;
let val be 12.2222 cubed.

Section : Square roots

We can calculate the square root of a number using the phrase 'the real square root of N'.

let val be the real square root of 5;
let val be the real square root of 23.4566.

The method used to calculate the square root of a number is the Newton-Raphson iteration method. If you try to calculate the square root of a negative number, the result is 0.0000.

We can convert an angle in degrees to the equivalent in radians using the phrase 'X in radians'.

let val be 90 in radians.

This function works for both fixed point numbers and integer numbers.

We can convert an angle in radians to degrees using the phrase 'X in degrees'.

let val be 1 in degrees;
let val be 2.3456 in degrees.

This function works for both integer and real numbers.

Section : Sines

We can calculate the sine of an angle in degrees using the phrase 'the sine of X'

let val be the sine of 30.5;
let val be the sine of -120.

We can use fixed point numbers or integer numbers.

The method used to calculate the sine of a number is the Taylor expansion series for the sine of a number. The angle is normalised into the range 0 to 360 degrees. If the angle is 0, 90, 180, 270 or 360, the results 0, 1, 0, -1, 0 are returned. If the angle is not one of these numbers, the angle is further normalised to 0 to 90 degrees, converted to radians and the result calculated from the Taylor Series for this angle.

We can calculate the arcsin of a number in the range -1 to 1 by using the phrase 'the arcsine of X'. Values outside the range -1 to 1 will return the result 0.0000.

let val be the arcsine of 0.2500.

The angle is returned in degrees to the nearest one tenth of a degree.

Section : Cosines

We can calculate the cosine of an angle in degrees using the phrase 'the cosine of X'

let val be the cosine of 30.5;
let val be the cosine of -120.

We can use fixed point numbers or integer numbers.

The cosine of an angle is calculated by adding 90 degrees to the angle and calculating the sine of the result.

Section : Tangents

We can calculate the tangent of an angle in degrees using the phrase 'the tangent of X'.

let val be the tangent of 30.5;
let val be the tangent of -120.

We can use fixed point numbers or integer numbers.

The tangent of an angle is calculated by dividing the sine of the angle by the cosine of the angle.

We can calculate the arctangent of a number by using the phrase 'the arctangent of X'.

let val be the arctangent of 0.5000;
let val be the arctangent of 1.

We can use fixed point number or integer numbers. The result is returned as an angle to the nearest tenth of a degree.

Section : Natural logs

We can find the natural log (to base e) of a number by using the phrase 'the natural log of X':

let val be the natural log of 10;
let val be the natural log of 2.3456.

We can use fixed point numbers or integer numbers. Calculating the natural log of a number equal to or less than 0 will return the result 0.0000.

Section : E to the power X

We can find the result of e (2.7183) to the power of a number by using the phrase 'e to the power X'.

let val be e to the power 2.5;
let val be e to the power 10.

We can use fixed point numbers or integer numbers.

Chapter : Converting text to a number

We can convert text to a real point number using the phrase, let X be the number derived from "text". For example:

let X be the number derived from "-12.2345".

If the text does not match the requirements for a real number, an internal flag, invalid conversion, is set to true. We can use this flag to ensure that the text is a real number.

let X be the number derived from "a123.1222":
if invalid conversion is true:
say "This is not valid real number. It must contain only digits and the characters '+ - and .' There must be [precision] digits after the decimal point.";
otherwise:
say "[X]".