# Turbo Pascal Real

While most languages use a 32-bit or 64-bit floating point decimal variable, usually called *single* or *double*, Turbo Pascal featured an uncommon 48-bit float called a *real* which served the same function as a float. Real variable types were frequently used in the early versions of Pascal because it did not have native support for 32-bit integers until later versions, so, if you wanted to store a number greater than 32,767 or a number with a decimal value, you had to use a real. 32 and 64-bit floats were introduced in Turbo Pascal version 5. Pascal's successor, Delphi, did not feature reals as a variable type.

A Pascal real has a value range of 2.9 x 10^{-39} to 1.7 x 10^{38}.

The structure of a Pascal real is seen in the diagram below.

Byte | 0 | 1 | 2 | 3 | 4 | 5 |
---|---|---|---|---|---|---|

Bit | 01234567 | 01234567 | 01234567 | 01234567 | 01234567 | 01234567 |

Value |
EEEEEEEE | MMMMMMMM | MMMMMMMM | MMMMMMMM | MMMMMMMM | SMMMMMMM |

Where E is Exponent, M is Mantissa, and S is the Sign bit.

## Conversion

Any games written in Turbo Pascal may feature game data files with reals encoded into them. However, unless your mod program is written in Turbo Pascal, you won't have any way to directly read or write these values. The simplest way to do this is to convert each real into a double when reading them from a file, and from a double into a real when writing them back to a file.

### Real to Double

This will take a real as input and give a double as output.

#### C#

```
// This program expects a byte array named real48[6] to be loaded with the 6 bytes of the real from the file.
Double exponentbase = 129d;
Double exponent = real48[0] - exponentbase; // The exponent is offset so deduct the base.
// Now Calculate the mantissa
Double mantissa = 0.0;
Double value = 1.0;
// For Each Byte.
for (int i = 5; i >= 1; i--)
{
int startbit = 7;
if (i == 5)
{ startbit = 6; } //skip the sign bit.
//For Each Bit
for (int j = startbit; j >= 0; j--)
{
value = value / 2;// Each bit is worth half the next bit but we're going backwards.
if (((real48[i] >> j) & 1) == 1) //if this bit is set.
{
mantissa += value; // add the value.
}
}
}
if (mantissa == 1.0 && real48[0] == 0) // Test for null value
return 0.0;
double factor = ((real48[5] & 0x80) != 0) ? -1 : 1; // Change sign if bit 7 is set
return factor * (1 + mantissa) * Math.Pow(2.0, exponent);
```

#### FreeBASIC

```
' Load the real from a file into a byte array.
Open "Real.bin" For Binary As #1
Dim Real48(0 To 5) As UByte
Dim ByteNo As Byte
For ByteNo = 0 To 5
Get #1, , Real48(ByteNo)
Next ByteNo
Close #1
' Get the exponent value, and eliminate the 129 offset.
Dim Exponent As Double
Exponent = Real48(0) - 129.0
' Calculate the mantissa.
Dim Mantissa As Double
Dim Value As Double
Value = 1
For ByteNo = 5 To 1 Step -1
Dim StartBit As Byte
StartBit = 7
If ByteNo = 5 Then StartBit = 6 ' Skip the sign bit.
Dim BitNo As Byte
For BitNo = StartBit To 0 Step -1
Value = Value / 2
If ((Real48(ByteNo) Shr BitNo) And 1) = 1 Then
Mantissa = Mantissa + Value
End If
Next BitNo
Next ByteNo
' Add the implicit 1.
Mantissa = Mantissa + 1
' Test for a null value.
Dim Result As Double
If Mantissa = 1.0 And Real48(0) = 0 Then
Result = 0.0
Else
' If the sign bit is set, make the value negative.
If Real48(5) AND &H80 = -1 Then
Mantissa = -Mantissa
End If
' Raise the mantissa to the specified exponent.
Result = Mantissa * (2 ^ Exponent)
End If
Print Result
Sleep
```

### Double to Real

This will take a double as input and give a real as output.