January 13, 2018
On Saturday, 13 January 2018 at 17:46:15 UTC, rumbu wrote:
> The following code works:
>
>     real r;
>     for (r = 1; r < 6; r += .1L) {
>         decimal128 d = r;
>         auto dsin = sin (d);
>         auto rsin = sin (r);
>         auto delta = dsin - rsin; //delta is decimal128
>         writefln ("%9.2f %30.24f %30.24f %12.4g", r, rsin, dsin, delta);
>     }

rsinus.d
```
import std.stdio;
import std.math;
import decimal;

void main ()
{
   real r;
   for (r = 1; r < 6; r += .1L) {
      decimal128 d = r;
      auto dsin = sin (d);
      auto rsin = sin (r);
      auto delta = dsin - rsin;
      writefln ("%9.2f %30.24f %30.24f %12.4g", r, rsin, dsin, delta);
   }
}
```

I get large numerical dicrepancies and an exception:

     1.00     0.841470984807896506664591     0.841470984807896506632968    3.633e-18
     1.10     0.891207360061435339970703     0.878166666666666700439167       -1e-02
     1.20     0.932039085967226349689098     0.932735999999999982229600        1e-04
     1.30     0.963558185417192964729825     0.964774416666666678037840        1e-03
     1.40     0.985449729988460180693261     0.985449729988460165022208    2.352e-17
     1.50     0.997494986604054430972058     0.997494986604054430940101   -1.206e-17
     1.60     0.999573603041505164359688     0.917333333333333309393333       -1e-02
     1.70     0.991664810452468615338453     0.991664810452468621659666    5.316e-17
     1.80     0.973847630878195186514452     0.973847630878195177217801    3.222e-17
     1.90     0.946300087687414488452770     0.946300087687414518558711    5.006e-17
     2.00     0.909297426825681695322298     0.909297426825681695408286   -1.229e-17
     2.10     0.863209366648873770600393     0.863209366648873727768592   -9.243e-17
     2.20     0.808496403819590184279108     0.808496403819590083669388   -1.180e-16
     2.30     0.745705212176720177432929     0.745705212176720299976718    1.573e-16
     2.40     0.675463180551150926659871     0.675463180551150998081025    4.488e-17
     2.50     0.598472144103956494242628     0.598472144103956494052117   -5.365e-17
     2.60     0.515501371821464235509908     0.515501371821464164136844   -1.059e-16
     2.70     0.427379880233829934906920     0.427379880233829779962563   -1.640e-16
     2.80     0.334988150155904919986691     0.334988150155905092912699    1.534e-16
     2.90     0.239249329213982328722001     0.239249329213982423337949    8.154e-17
     3.00     0.141120008059867222739193     0.141120008059867222100109    9.000e-18
     3.10     0.041580662433290579926783     0.041580662433290496264607   -8.502e-17
     3.20    -0.058374143427579908318645    -0.058374143427580079845578   -1.746e-16
     3.30    -0.157745694143248381115198    -0.157745694143248199327762    1.774e-16
     3.40    -0.255541102026831318288136    -0.255541102026831224503296    1.098e-16
     3.50    -0.350783227689619847116916    -0.350783227689619848119312   -1.252e-17
     3.60    -0.442520443294852383234834    -0.442520443294852457798085   -5.310e-17
     3.70    -0.529836140908493212172466    -0.529836140908493358228498   -1.787e-16
     3.80    -0.611857890942719074699619    -0.611857890942718929385788    9.811e-17
     3.90    -0.687766159183973817053612    -0.687766159183973746224122    2.078e-17
     4.00    -0.756802495307928250372134    -0.756802495307928251373997   -5.067e-17
     4.10    -0.818277111064410503490831    -0.818277111064410297331800    1.797e-16
     4.20    -0.871575772413588059281658    -0.871575772413588143861425   -6.686e-17
     4.30    -0.916165936749454983402223    -0.916165936749454908701153    1.013e-16
     4.40    -0.951602073889515953533484    -0.951602073889516059449964   -1.634e-16
     4.50    -0.977530117665097055001684    -0.977530117665097055387688   -4.889e-17
     4.60    -0.993691003633464455912887    -0.993691003633464414974720   -8.475e-18
     4.70    -0.999923257564100884174467    -0.999923257564100886240565   -5.624e-17
     4.80    -0.996164608835840671935500    -0.996164608835840688651004   -8.651e-18
     4.90    -0.982452612624332512691275    -0.982452612624332448489733    2.651e-17
     5.00    -0.958924274663138469525139    -0.958924274663138468894495   -1.739e-17
     5.10    -0.925814682327732297803524    -0.925814682327732436044974   -9.704e-17
     5.20    -0.883454655720153265790421    -0.883454655720153186437488    5.926e-17
     5.30    -0.832267442223901164892897    -0.832267442223901270573400   -1.281e-16
     5.40    -0.772764487555987363974919    -0.772764487555987145324893    2.202e-16
     5.50    -0.705540325570391908089566    -0.705540325570391906230803    1.647e-17
     5.60    -0.631266637872321313522395    -0.631266637872321596869491   -3.079e-16
     5.70    -0.550685542597637763537807   -25.165500000000002545915000          -

core.exception.RangeError@decimal/package.d(6652): Range violation
----------------
??:? _d_arrayboundsp [0x46ccea]
decimal/package.d:6652 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)) [0x460a41]
decimal/package.d:6851 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)) [0x461ae9]
decimal/package.d:6890 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)) [0x460208]
decimal/package.d:1316 const void decimal.Decimal!(128).Decimal.toString!(char).toString(scope void delegate(const(char)[]), std.format.FormatSpec!(char).FormatSpec) [0x45fff1]
/.../dmd2/linux/bin64/../../src/phobos/std/format.d:3341 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)) [0x4620c2]
/.../dmd2/linux/bin64/../../src/phobos/std/format.d:3669 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)) [0x462069]
/.../dmd2/linux/bin64/../../src/phobos/std/format.d:568 uint std.format.formattedWrite!(std.stdio.File.LockingTextWriter, char, real, real, decimal.Decimal!(128).Decimal, decimal.Decimal!(128).Decimal).formattedWrite(ref std.stdio.File.LockingTextWriter, const(char[]), real, real, decimal.Decimal!(128).Decimal, decimal.Decimal!(128).Decimal) [0x45711b]
/.../dmd2/linux/bin64/../../src/phobos/std/stdio.d:1496 void std.stdio.File.writefln!(char, real, real, decimal.Decimal!(128).Decimal, decimal.Decimal!(128).Decimal).writefln(const(char[]), real, real, decimal.Decimal!(128).Decimal, decimal.Decimal!(128).Decimal) [0x456be6]
/.../dmd2/linux/bin64/../../src/phobos/std/stdio.d:3797 void std.stdio.writefln!(char, real, real, decimal.Decimal!(128).Decimal, decimal.Decimal!(128).Decimal).writefln(const(char[]), real, real, decimal.Decimal!(128).Decimal, decimal.Decimal!(128).Decimal) [0x456b37]
rsinus.d:12 _Dmain [0x44c27d]

> if you really need to convert decimalX values to floating point counterparts, you'll need to cast them:
>
> x = cast(real)somedecimalvalue;
>
> (but update your files before this, I discovered a bug in opCast)

Yea, this seems to work now.
January 13, 2018
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.

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);


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.

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


Thank you for your exhaustive testing :)

January 13, 2018
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]


January 13, 2018
On Saturday, 13 January 2018 at 20:40:20 UTC, kdevel wrote:
> 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.
>

There was an error in 128/256 bit division. The exception might be caused also by the same division since in the output values are rounded also by division. I think now it's solved.

Now it prints:

     1.00    +0.841470984807896506690000 +0.8414709848078965066525023216302990   +2.653e-18
     1.10    +0.891207360061435339970000 +0.8912073600614353383642161528821827   +6.642e-19
     1.20    +0.932039085967226349660000 +0.9320390859672263482207034175881317   +7.207e-19
     1.30    +0.963558185417192964750000 +0.9635581854171929634976039012289115   +1.998e-18
     1.40    +0.985449729988460180680000 +0.9854497299884601806594745788060975   +2.659e-18
     1.50    +0.997494986604054430920000 +0.9974949866040544309417233711414873   +2.942e-18
     1.60    +0.999573603041505164340000 +0.9995736030415051644881114370526778   +2.988e-18
     1.70    +0.991664810452468615300000 +0.9916648104524686161192003644210237   +3.119e-18
     1.80    +0.973847630878195186490000 +0.9738476308781951865323731788433576   +2.532e-18
     1.90    +0.946300087687414488450000 +0.9463000876874144907527365796794817   +4.753e-18
     2.00    +0.909297426825681695360000 +0.9092974268256816953960198659117448   +2.896e-18
     2.10    +0.863209366648873770580000 +0.8632093666488737742146820454680267   +5.515e-18
     2.20    +0.808496403819590184280000 +0.8084964038195901884235447312035390   +6.724e-18
     2.30    +0.745705212176720177430000 +0.7457052121767201827156143818820931   +7.216e-18
     2.40    +0.675463180551150926640000 +0.6754631805511509324649212496712473   +7.965e-18
     2.50    +0.598472144103956494230000 +0.5984721441039565012621472421085657   +8.762e-18
     2.60    +0.515501371821464235500000 +0.5155013718214642429697257155298933   +8.470e-18
     2.70    +0.427379880233829934900000 +0.4273798802338299426927023640114310   +8.893e-18
     2.80    +0.334988150155904919980000 +0.3349881501559049280238548187303455   +9.224e-18
     2.90    +0.239249329213982328710000 +0.2392493292139823378938385702354806   +1.009e-17
     3.00    +0.141120008059867222730000 +0.1411200080598672320006697688125648   +9.751e-18
     3.10    +0.041580662433290579925000 +0.0415806624332905891860497743294677   +9.416e-18
     3.20    -0.058374143427579908319000 -0.0583741434275798991542696566715643   +8.966e-18
     3.30    -0.157745694143248381120000 -0.1577456941432483701618970386961038   +1.049e-17
     3.40    -0.255541102026831318290000 -0.2555411020268313076483241184102069   +9.852e-18
     3.50    -0.350783227689619847110000 -0.3507832276896198368828885525540795   +8.817e-18
     3.60    -0.442520443294852383210000 -0.4425204432948523726088679351487828   +8.991e-18
     3.70    -0.529836140908493212180000 -0.5298361409084932021854772134659022   +8.015e-18
     3.80    -0.611857890942719074680000 -0.6118578909427190654510058312314653   +7.749e-18
     3.90    -0.687766159183973817050000 -0.6877661591839738086537681707768678   +6.346e-18
     4.00    -0.756802495307928250370000 -0.7568024953079282428752720232848741   +5.825e-18
     4.10    -0.818277111064410503450000 -0.8182771110644104967923257194259585   +4.708e-18
     4.20    -0.871575772413588059290000 -0.8715757724135880526646647777983275   +4.035e-18
     4.30    -0.916165936749454983420000 -0.9161659367494549780197217790850059   +2.480e-18
     4.40    -0.951602073889515953550000 -0.9516020738895159488107335437472529   +1.689e-18
     4.50    -0.977530117665097054990000 -0.9775301176650970518056064241753746   -3.056e-19
     4.60    -0.993691003633464455930000 -0.9936910036334644542315117020129026   -1.232e-18
     4.70    -0.999923257564100884190000 -0.9999232575641008839565405992429380   -2.457e-18
     4.80    -0.996164608835840671960000 -0.9961646088358406733565781684136726   -3.857e-18
     4.90    -0.982452612624332512720000 -0.9824526126243325156335998995246860   -5.634e-18
     5.00    -0.958924274663138469490000 -0.9589242746631384739990737444940666   -8.499e-18
     5.10    -0.925814682327732297800000 -0.9258146823277323037497456163785133   -9.250e-18
     5.20    -0.883454655720153265820000 -0.8834546557201532731063845238285883   -1.041e-17
     5.30    -0.832267442223901164880000 -0.8322674422239011735432977190794839   -1.104e-17
     5.40    -0.772764487555987363960000 -0.7727644875559873750523273015869194   -1.385e-17
     5.50    -0.705540325570391908070000 -0.7055403255703919225313239842210499   -1.603e-17
     5.60    -0.631266637872321313520000 -0.6312666378723213293016843594524164   -1.760e-17
     5.70    -0.550685542597637763540000 -0.5506855425976377779216063046556619   -1.622e-17
     5.80    -0.464602179413757213930000 -0.4646021794137572317851754163529263   -1.909e-17
     5.90    -0.373876664830236362540000 -0.3738766648302363811468503760962045   -1.985e-17
     6.00    -0.279415498198925875720000 -0.2794154981989258948954720395703132   -2.020e-17

>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.

That's exactly how it's done internally: https://github.com/rumbu13/decimal/blob/master/src/decimal/package.d#L13380

Your unity test also seems now to compute correctly. My maximum |δ| for decimal128 is now 1e-34

>There's more to come (sorry for the greek symbols, could not resist to check this utf-8 feature)

I like them too: https://github.com/rumbu13/decimal/blob/master/src/decimal/package.d#L13558

Do you have something against including parts of your test published here as unittests? Thanks.


January 13, 2018
On Saturday, 13 January 2018 at 22:05:02 UTC, rumbu wrote:
> Now it prints:
>
>      1.00    +0.841470984807896506690000 +0.8414709848078965066525023216302990   +2.653e-18

My values differ slightly
     1.00     0.841470984807896506664591     0.841470984807896506652502    3.653e-18

But I would check this later.

> Your unity test also seems now to compute correctly. My maximum |δ| for decimal128 is now 1e-34

Same here.

> Do you have something against including parts of your test published here as unittests? Thanks.

No, of course not, please take whatever you need! I have another testcase which prints awkward results:

sinus_31.d
```
import std.stdio;
import std.math;
import decimal;

void main ()
{
   real r;
   for (r = 1; r < 6; r += .1L) {
      decimal128 d = r;
      auto dsin = sin (d);
      auto rsin = sin (r);
      real delta = cast(real) dsin;
      delta -= rsin;
      writefln ("%9.2f %30.24f %30.24f %12.4g", r, rsin, dsin, delta);
   }
}
```

Please note the large deltas in case of negative operands. I suspect the conversion to real is wrong for these numbers:

     1.00     0.841470984807896506664591     0.841470984807896506652502   -5.421e-20
     1.10     0.891207360061435339970703     0.891207360061435378734271    3.871e-17
     1.20     0.932039085967226349689098     0.932039085967226332095783   -1.756e-17
     1.30     0.963558185417192964729825     0.963558185417192975802550    1.106e-17
     1.40     0.985449729988460180693261     0.985449729988460165022497   -1.567e-17
     1.50     0.997494986604054430972058     0.997494986604054430941723   -5.421e-20
     1.60     0.999573603041505164359688     0.999573603041505161845555   -2.548e-18
     1.70     0.991664810452468615338453     0.991664810452468621659514    6.343e-18
     1.80     0.973847630878195186514452     0.973847630878195177217087   -9.324e-18
     1.90     0.946300087687414488452770     0.946300087687414518555639    3.014e-17
     2.00     0.909297426825681695322298     0.909297426825681695396020    5.421e-20
     2.10     0.863209366648873770600393     0.863209366648873727768840   -4.283e-17
     2.20     0.808496403819590184279108     0.808496403819590083670346   -1.006e-16
     2.30     0.745705212176720177432929     0.745705212176720299980194    1.226e-16
     2.40     0.675463180551150926659871     0.675463180551150998092962    7.145e-17
     2.50     0.598472144103956494242628     0.598472144103956494051855   -2.168e-19
     2.60     0.515501371821464235509908     0.515501371821464164135960   -7.139e-17
     2.70     0.427379880233829934906920     0.427379880233829779959717   -1.549e-16
     2.80     0.334988150155904919986691     0.334988150155905092912764    1.729e-16
     2.90     0.239249329213982328722001     0.239249329213982423338157    9.458e-17
     3.00     0.141120008059867222739193     0.141120008059867222100745    -6.37e-19
     3.10     0.041580662433290579926783     0.041580662433290496266481   -8.366e-17
     3.20    -0.058374143427579908318645    -0.058374143427580079845624       0.1167
     3.30    -0.157745694143248381115198    -0.157745694143248199327897       0.3155
     3.40    -0.255541102026831318288136    -0.255541102026831224503680       0.5111
     3.50    -0.350783227689619847116916    -0.350783227689619848120369       0.7016
     3.60    -0.442520443294852383234834    -0.442520443294852457800917        0.885
     3.70    -0.529836140908493212172466    -0.529836140908493358235883         1.06
     3.80    -0.611857890942719074699619    -0.611857890942718929404559        1.224
     3.90    -0.687766159183973817053612    -0.687766159183973746223590        1.376
     4.00    -0.756802495307928250372134    -0.756802495307928251372639        1.514
     4.10    -0.818277111064410503490831    -0.818277111064410297328416        1.637
     4.20    -0.871575772413588059281658    -0.871575772413588143853178        1.743
     4.30    -0.916165936749454983402223    -0.916165936749454908681465        1.832
     4.40    -0.951602073889515953533484    -0.951602073889516059450567        1.903
     4.50    -0.977530117665097055001684    -0.977530117665097055389135        1.955
     4.60    -0.993691003633464455912887    -0.993691003633464414978127        1.987
     4.70    -0.999923257564100884174467    -0.999923257564100886248443            2
     4.80    -0.996164608835840671935500    -0.996164608835840688668900        1.992
     4.90    -0.982452612624332512691275    -0.982452612624332448489147        1.965
     5.00    -0.958924274663138469525139    -0.958924274663138468893154        1.918
     5.10    -0.925814682327732297803524    -0.925814682327732436041956        1.852
     5.20    -0.883454655720153265790421    -0.883454655720153186430800        1.767
     5.30    -0.832267442223901164892897    -0.832267442223901270558807        1.665
     5.40    -0.772764487555987363974919    -0.772764487555987145293506        1.546
     5.50    -0.705540325570391908089566    -0.705540325570391906231919        1.411
     5.60    -0.631266637872321313522395    -0.631266637872321596871912        1.263
     5.70    -0.550685542597637763537807    -0.550685542597637621830316        1.101
     5.80    -0.464602179413757213934100    -0.464602179413757384094532       0.9292
     5.90    -0.373876664830236362535186    -0.373876664830236042617223       0.7478
     6.00    -0.279415498198925875709877    -0.279415498198925872811555       0.5588

There's also code which one would expect to compile:

lt.d
```
import std.stdio;
import decimal;

void main ()
{
   decimal32 d;
   if (d < 0)
      writeln ("< 0");
   else
      writeln ("not < 0");
}
```

$ dmd -g lt.d decimal.git/libdecimal.a
decimal/package.d(9404): Error: template decimal.cmp cannot deduce function from argument types !()(uint, int, bool, uint, int, bool), candidates are:
decimal/package.d(2574):        decimal.cmp(D1, D2)(auto ref const D1 x, auto ref const D2 y) if (isDecimal!(D1, D2))
decimal/package.d(1073): Error: template instance decimal.decimalCmp!(Decimal!32, int) error instantiating
lt.d(7):        instantiated from here: opCmp!int

and also this one:

coerce.d
```
import std.stdio;
import std.typecons;
import decimal;

void main ()
{
   decimal32 d = "1";
   auto p = 4 * d;
   auto q = d * 4;
   writeln (typeof(p).stringof);
   writeln (typeof(q).stringof);
}
```

$ dmd -g coerce.d decimal.git/libdecimal.a
decimal/package.d(8339): Error: template instance isFloatingpoint!F template 'isFloatingpoint' is not defined, did you mean isFloatingPoint?
coerce.d(8): Error: template instance decimal.Decimal!32.Decimal.opBinaryRight!("*", int) error instantiating


January 14, 2018
On Saturday, 13 January 2018 at 22:51:18 UTC, kdevel wrote:
> On Saturday, 13 January 2018 at 22:05:02 UTC, rumbu wrote:
>> Now it prints:
>>
>>      1.00    +0.841470984807896506690000 +0.8414709848078965066525023216302990   +2.653e-18
>
> My values differ slightly
>      1.00     0.841470984807896506664591     0.841470984807896506652502    3.653e-18
>
> But I would check this later.

Can you please tell me on your system what are the values for real.sizeof and real.mant_dig?


> Please note the large deltas in case of negative operands. I suspect the conversion to real is wrong for these numbers:

> -0.996164608835840688668900        1.992
>      4.90    -0.982452612624332512691275    -0.982452612624332448489147        1.965
>      5.00    -0.958924274663138469525139    -0.958924274663138468893154        1.918
>      5.10    -0.925814682327732297803524

Forgot to propagate the sign in case of decimal to binary conversion. Corrected.

>
> There's also code which one would expect to compile:
>

It compiles now.

January 14, 2018
On Sunday, 14 January 2018 at 07:20:26 UTC, rumbu wrote:
> On Saturday, 13 January 2018 at 22:51:18 UTC, kdevel wrote:
>> [...]
>
> Can you please tell me on your system what are the values for real.sizeof and real.mant_dig?

They are 12 and 64 (-m32) and 16 and 64 (-m64).

>> [...]
>
>>      [...]
>
> Forgot to propagate the sign in case of decimal to binary conversion. Corrected.

ACK.

>>[...]
>
> It compiles now.

ACK.
January 14, 2018
On Sunday, 14 January 2018 at 11:44:39 UTC, kdevel wrote:
> On Sunday, 14 January 2018 at 07:20:26 UTC, rumbu wrote:
>> On Saturday, 13 January 2018 at 22:51:18 UTC, kdevel wrote:
>>> [...]
>>
>> Can you please tell me on your system what are the values for real.sizeof and real.mant_dig?
>
> They are 12 and 64 (-m32) and 16 and 64 (-m64).
>

This is curious. Because the only documented real type with a 64-bit mantissa is the 80-bit Intel Extended Precision format with a unique sizeof of 10 (and not 12 or 16).

Actually, real80 is the only type I'm supporting in the library, any other real type is converted to double. This will explain some loss of precision.

Do you have more information about the real type on you system, because on mine (Windows), real.sizeof is always 10, irrespective of -m32 or -m64.

Mantissa will be easy to extract being 64-bit, but I don't know the exact layout of your real type to extract the exponent.




January 14, 2018
On Sunday, 14 January 2018 at 12:35:43 UTC, rumbu wrote:
> On Sunday, 14 January 2018 at 11:44:39 UTC, kdevel wrote:
>> On Sunday, 14 January 2018 at 07:20:26 UTC, rumbu wrote:
>>> On Saturday, 13 January 2018 at 22:51:18 UTC, kdevel wrote:
>>>> [...]
>>>
>>> Can you please tell me on your system what are the values for real.sizeof and real.mant_dig?
>>
>> They are 12 and 64 (-m32) and 16 and 64 (-m64).
>>
>
> This is curious. Because the only documented real type with a 64-bit mantissa is the 80-bit Intel Extended Precision format with a unique sizeof of 10 (and not 12 or 16).

sizeof returns the in-memory size (at least in C and C++) which is subject to alignment constraints.  32-bit mode typically requires 4-byte aligned access (96 bit = 12 byte) while 64-bit requires 8-byte alignment (128 bit = 16 bytes) for optimal performance. Cf. e.g. p. 28 of "SYSTEM V APPLICATION BINARY INTERFACE Intel386" (long double)

http://www.sco.com/developers/devspecs/abi386-4.pdf

and p. 12 of "System V Application Binary Interface AMD64 Architecture Processor Supplement"

https://www.uclibc.org/docs/psABI-x86_64.pdf

> Actually, real80 is the only type I'm supporting in the library, any other real type is converted to double. This will explain some loss of precision.

Agreed.

> Do you have more information about the real type on you system, because on mine (Windows), real.sizeof is always 10, irrespective of -m32 or -m64.
>
> Mantissa will be easy to extract being 64-bit, but I don't know the exact layout of your real type to extract the exponent.

Assumed that your machine has a X86_64 cpu real = long double is the 80-bit extended precision format. I suppose you are running windows and it may be that the Window ABI stores these reals 16-bit (2-byte) aligned. In this case there will be no padding. But I have not found info on this topic.
1 2 3 4 5
Next ›   Last »