# Re: Another take on decimal data types

```On Saturday, 13 January 2018 at 19:28:40 UTC, rumbu wrote:
```
`On Saturday, 13 January 2018 at 18:37:10 UTC, kdevel wrote:`
```
```
```I get large numerical dicrepancies and an exception:
```
```
That's because you are mixing floating point and decimal.

```
Just to take one example: double 1.1 cannot be represented exactly as floating point and it's in fact 1.10000002384185791015625.
```
```
Sure. double has 53 mantissa bits but float only 24. But that is not my point.
```I am *not* talking about the 1e-18 but about these lines:

```
1.10 0.891207360061435339970703 0.878166666666666700439167 -1e-02 1.20 0.932039085967226349689098 0.932735999999999982229600 1e-04 1.30 0.963558185417192964729825 0.964774416666666678037840
```1e-03

and

```
5.70 -0.550685542597637763537807 -25.165500000000002545915000 -
```
At 5.7 the value is obviously out of range.

```
sin is calculated using a Taylor series: sin(x) = x - x^3/3! + x^5/5! - x^7/7! ... and so on. Raising to power all that junk after 1.1 will lead finally to error. If you really want to find out sin(1.1) using decimal, try sin(decimal128("1.1")) or sin(decimal128(1)/10);
```
```
Chapter 9.2 of IEEE-754-2008 says the domain of sin(x) is (-inf, inf). So if the argument x is outside the radius of convergence of the Taylor series x must be reduced modulo 2pi such that it fits.
```
```
For exact values like sin(1.0), I let you decide which one is more exact:
```
Wolfram Alpha: 0.8414709848078965066525023216302989
real:          0.8414709848078965066645910000000000
double:        0.8414709848078965048700000000000000
float:         0.8414709568023681640600000000000000
decimal128:    0.8414709848078965066329679978908351
decimal64:     0.8414709848078965000000000000000000
decimal32:     0.8414710000000000000000000000000000

```
Anyway, I wouldn't call a difference at the 18th digit a "large discrepancy" when we are talking about irrational numbers.
```
See above.

```
Regarding the exception, I cannot reproduce it, but I'll look into it.
```
Nice.

```
```Thank you for your exhaustive testing :)
```
```
```
There's more to come (sorry for the greek symbols, could not resist to check this utf-8 feature):
```
unity.d
```
import std.stdio;
import std.typecons;
import std.range;
import std.math;
import decimal;

immutable size_t N = 100;

void unity (T) ()
{
writeln ("\n=== ", T.stringof, " ===\n");
immutable one = T (1);
immutable two = T (2);
immutable π = atan (one) * 4;
writefln!"π = <%30.24f>" (π);

foreach (i; iota(N + 1)) {
auto φ = two * π * i / N;
auto sinφ = sin (φ);
auto cosφ = cos (φ);
auto unity = sinφ * sinφ + cosφ * cosφ;
auto δ = one - unity;
writeln ("φ = <", φ, ">, δ = <", δ, ">");
}
}

void main ()
{
//   unity!float;
//   unity!double;
//   unity!real;
//   unity!decimal32;
unity!decimal64;
unity!decimal128;
}
```

```
Selected lines from the output produced here (Linux, DMD64 D Compiler v2.077.1):
```
=== Decimal!64 ===

π = <    3.141592653589793000000000>
φ = <0>, δ = <0>
φ = <0.0628319>, δ = <0>
φ = <0.125664>, δ = <1e-16>          possibly okay
:
φ = <0.942478>, δ = <2.41721e-06>    too large
:
φ = <2.45044>, δ = <-6.57811e-07>    ditto
φ = <2.51327>, δ = <-3.83012e-10>    ditto
φ = <2.57611>, δ = <0.479476>        ditto
:
:
:

=== Decimal!128 ===

π = <    3.141592653589793238612055>
φ = <0>, δ = <0>
φ = <1e-02>, δ = <-1.73780e-22>
:
```
Something went wrong with printing φ. And also this program crashes:
```
core.exception.RangeError@decimal/package.d(6652): Range violation
----------------
??:? _d_arrayboundsp [0x80bc65f]
```
??:? void decimal.sinkFloat!(char, decimal.integrals.unsigned!(128).unsigned).sinkFloat(ref const(std.format.FormatSpec!(char).FormatSpec), void delegate(const(char)[]), const(decimal.integrals.unsigned!(128).unsigned), const(int), const(bool), const(decimal.RoundingMode), const(bool)) [0x80b2976] ??:? void decimal.sinkGeneral!(char, decimal.integrals.unsigned!(128).unsigned).sinkGeneral(ref const(std.format.FormatSpec!(char).FormatSpec), void delegate(const(char)[]), const(decimal.integrals.unsigned!(128).unsigned), const(int), const(bool), const(decimal.RoundingMode)) [0x80b33a4] ??:? void decimal.sinkDecimal!(char, decimal.Decimal!(128).Decimal).sinkDecimal(ref const(std.format.FormatSpec!(char).FormatSpec), void delegate(const(char)[]), ref const(decimal.Decimal!(128).Decimal), const(decimal.RoundingMode)) [0x80b241a] ??:? const void decimal.Decimal!(128).Decimal.toString!(char).toString(scope void delegate(const(char)[]), std.format.FormatSpec!(char).FormatSpec) [0x80b22bb] ??:? void std.format.formatObject!(std.stdio.File.LockingTextWriter, decimal.Decimal!(128).Decimal, char).formatObject(ref std.stdio.File.LockingTextWriter, ref decimal.Decimal!(128).Decimal, ref const(std.format.FormatSpec!(char).FormatSpec)) [0x80b73cf] ??:? void std.format.formatValue!(std.stdio.File.LockingTextWriter, decimal.Decimal!(128).Decimal, char).formatValue(ref std.stdio.File.LockingTextWriter, ref decimal.Decimal!(128).Decimal, ref const(std.format.FormatSpec!(char).FormatSpec)) [0x80b7393] ??:? uint std.format.formattedWrite!(std.stdio.File.LockingTextWriter, char, decimal.Decimal!(128).Decimal).formattedWrite(ref std.stdio.File.LockingTextWriter, const(char[]), decimal.Decimal!(128).Decimal) [0x80b6efd] ??:? void std.stdio.File.write!(immutable(char)[], decimal.Decimal!(128).Decimal, immutable(char)[], decimal.Decimal!(128).Decimal, immutable(char)[], char).write(immutable(char)[], decimal.Decimal!(128).Decimal, immutable(char)[], decimal.Decimal!(128).Decimal, immutable(char)[], char) [0x8093176] ??:? void std.stdio.writeln!(immutable(char)[], decimal.Decimal!(128).Decimal, immutable(char)[], decimal.Decimal!(128).Decimal, immutable(char)[]).writeln(immutable(char)[], decimal.Decimal!(128).Decimal, immutable(char)[], decimal.Decimal!(128).Decimal, immutable(char)[]) [0x80930c8] ??:? void unity.unity!(decimal.Decimal!(128).Decimal).unity() [0x8092f62]
```??:? _Dmain [0x80905ec]

```