Version 1 (modified by sam, 11 years ago) (diff)

start the real class documentation

# Real numbers

Real numbers are a custom class that stores floating-point numbers with approximately 150 digits of precision.

Care has been taken to make the use of the `real` object as close as possible to `float` or `double`.

## Usage

Support for real numbers is straightforward:

```#include <lol/math/real.h>
```

If you are not using the full Lol Engine but a stripped down version such as LolRemez, make sure you compile `real.cpp` together with your application.

## Creation

You can create a real number using numeric literals:

```real x = 1.25, y = 2.0f;
real z = 0x100000;
real w(5);
```

It is also possible to use a string representation:

```real w = "1.202056903159594285399738161511449990764986292";
```

Warning: it is critical that you understand the difference between `"0.1"` and `0.1` here:

```real right = "0.1";
real wrong = 0.1;
```

When you write `0.1` the compiler understands this as a double precision floating point literal whose actual value is `0.1000000000000000055511151231257827021181583404541015625`, so you only get 17 digits of precision. When you write `"0.1"` the real number constructor will understand what you mean and will create an object with the highest possible precision.

Note that parsing a string to build a real number is expensive. Whenever possible, try to initialise reused variables only once, or use the constants provided by the `real` class.

## Constants

Some commonly used constants are provided by the `real` class. They are similar to the `M_PI`, `M_E` etc. variables provided by the `<math.h>` header except they have the `R_` prefix for “real”.

 `R_0` the integer value 0 `R_1` the integer value 1 `R_2` the integer value 2 `R_3` the integer value 3 `R_10` the integer value 10 `R_E` Euler’s number e `R_LOG2E` the reciprocal of ln(2) `R_LOG10E` the reciprocal of ln(10) `R_LN2` ln(2), the natural logarithm of 2 `R_LN10` ln(10), the natural logarithm of 10 `R_PI` Archimede’s constant pi `R_PI_2` pi divided by 2 `R_PI_3` pi divided by 3 `R_PI_4` pi divided by 4 `R_1_PI` the reciprocal of pi `R_2_PI` 2 divided by pi `R_2_SQRTPI` 2 divided by the square root of pi `R_SQRT2` Pythagoras’ constant, the square root of 2 `R_SQRT3` Theodorus’ constant, the square root of 3 `R_SQRT1_2` the square root of 1/2

## Conversions

Real numbers can be cast implicitly to numeric types with basically the same rules as `float` or `double`:

```real r ("1.5");
float f = r;

double d = real::R_LN10;
```

You can also print a real number to `stdout` with an arbitrary number of decimals:

```real r("0.1");
r.print(10);
```

Bug warning: it is not yet possible to output a real number to a standard C++ stream.

## Operators

Most expected operators are available for real numbers:

• `+`, `-`, `*`, `/`
• unary `+`, unary `-`
• `+=`, `-=`, `*=`, `/=`
• `==`, `!=`, `<`, `<=`, `>`, `>=`
• implicit boolean conversion and `!` operator

As an extension, the `<<`, `<<=`, `>>` and `>>=` operators are available for very fast division or multiplication by a power of two.

Example: compute the first 150 digits of the golden ratio as the quotient of two very large Fibonacci numbers:

```real a0(1), a1(1);
for (int i = 0; i < 400; i++)
{
real tmp = a0 + a1;
a0 = a1; a1 = tmp;
}
(a0 / a1).print(150);
```
```6.18033988749894848204586834365638117720309179805762862135448622705260462818902449707207204189391137484754088075386891752126633862223536931793180060766e-1
```

## Functions

Most expected `<math.h>` functions are available for real numbers, even those only introduced in the C99 standard.

### Trigonometric functions

 `sin` sine function `cos` cosine function `tan` tangent function `asin` arcsine function `acos` arccosine function `atan` arctangent function `atan2` two-argument arctangent

### Hyperbolic functions

 `sinh` hyperbolic sine `cosh` hyperbolic cosine `tanh` hyperbolic tangent

### Exponentials and logarithms

 `exp` exponential `exp2` base-2 exponential `log` natural logarithm `log2` base-2 logarithm `log10` base-10 logarithm `frexp` split number into a normalised fraction and an exponent `ldexp` multiply x by two to the power of y `modf` split number into an integral part and a fractional part

### Power functions

 `re` reciprocal: 1 divided by x `sqrt` square root `cbrt` cubic root `pow` x raised to the power y `gamma` the gamma function

Bug warning: as of now, the gamma function is only accurate to about 100 decimals instead of the expected 150.

### Rounding, absolute value, remainder etc.

 `ceil` the ceiling function `copysign` copy x’s sign to y `floor` the floor function `fabs` absolute value `round` the rounding function `fmod` modulo: remainder of dividing x by y

Example: find the solution to cos(x) = x³ using Newton-Raphson:

```real x(0.5);
for (int i = 0; i < 10; i++)
x = x - (cos(x) - x * x * x) / (-sin(x) - real::R_3 * x * x);
x.print(150);
```
```8.65474033101614446620685901186228747792911931818935500889279915855447006056021560514064272319562802280528781987092146472497110319687730308211712150975e-1
```

## Tips

The Lol Engine real numbers target accuracy rather than speed: we expect functions such as `sin`, `exp` or `pow` to always be accurate to the last digit of precision. However, they may be very slow.

The table shows the relative timings you may expect from various operations:

 operation speed (milliseconds) `+` (real) 0.14 `*` (real) 0.54 `/` (real) 6.50 `sin` (real) 90.00 `exp` (real) 160.00

As a comparison, here are some values for floats:

 operation speed (milliseconds) `/` (float) 0.001 `sin` (float) 0.40 `exp` (float) 0.08