Floating-point

From TinyMUX
Jump to navigation Jump to search

[Floating point] is a complicated mix of math, conventions, and compromises -- the details of which are probably best left to the general article. However, it is also useful to understand how MUSH servers use, depend on, and are limited by floating-point.

Floating-point isn't exact, and floating-point operations are sometimes defined across only part of their range. For example, what are the results of dividing by zero, taking the square root of a negative number, or a logarithm of zero? Also, floating-point standards impose limits on how small and large a number may be as well as the precision.

The most frustrating part of floating-point is that calculations are performed in base-2 instead of base-10 so the inexact nature of floating-point calculations is amplified due to the inexact conversion of user inputs to the internal floating-point representation and the inexact conversion from the internal floating-point format to user-friendly text.

Two Approaches

Thus far, MUSH servers have approached this in two ways with advantages and disadvantages to each. And, there is some blurring between the two.

Useful Subset Approach

In the not so distant past, all results were rounded to the 6th decimal place and the trailing zeros were removed. TinyMUSH and RhostMUSH still do this. PennMUSH provides float_precision to control the rounding position, but once chosen, it is fixed for the entire game. TinyMUX 2.6 also provides float_precision. By default, it is disabled.

The advantage of this approach is that it cleans up inexact answers.

The disadvantage is that these MUSH servers are unable to perform reasonable math below the 5th decimal place and the round-off errors of working close to the 6th decimal place are large.

However, PennMUSH does sometimes generate and recognize the following named numbers: +Inf, -Inf, Nan.

Full Set Approach

TinyMUX imposes a one-to-one mapping between the internal floating-point representation and the text. There are special named numbers: Ind, +Inf, -Inf, and Nan. There is no fixed rounding point. The conversion to text is interesting because it always uses the fewest digits that give the same internal value when converted back. Also, TinyMUX goes to great lengths to manage the order of certain operations in an effort to minimize floating-point errors.

The advantage of this approach is that TinyMUX is able to perform any calculation that the underlying hardware can perform, and it makes the best of the available hardware.

The disadvantage of this approach is that it reveals all of the remaining inexactness inherent in those calculations.

Examples

Without Operations

All servers evaluate add(.1) ==> '.1' even though 0.1 is only approximated by floating-point. Remember that 0.5 is exact, but 0.1 is not.

Special Name Behavior

On PennMUSH, mul(2,sqrt(-1)) ==> '#-1 ARGUMENTS MUST BE NUMBERS', and sqrt(-1) ==> '#-1 IMAGINARY NUMBER'.
On TinyMUSH, mul(2,sqrt(-1)) ==> '0', and sqrt(-1) ==> '#-1 SQUARE ROOT OF NEGATIVE'.
On TinyMUX, mul(2,sqrt(-1)) ==> 'Ind', and sqrt(-1) ==> 'Ind'. The 'Ind' is carried from the sqrt() through the mul().

Subtraction and Relative Error

On PennMUSH, TinyMUSH, TinyMUX with float_precision enabled, and RhostMUSH, sub(1.01,1) ==> '0.01'.
On TinyMUX with float_precision disabled, sub(1.01,1) ==> '0.01000000000000001'.

Range

On PennMUSH, TinyMUSH, TinyMUX with float_precision enabled, and RhostMUSH, fdiv(1,10000000) ==> '0'.
On TinyMUX with float_precision disabled, fdiv(1,10000000) ==> '1E-7'.