Another take on decimal data types

kdevel kdevel at vogtner.de
Sat Jan 13 22:51:18 UTC 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




More information about the Digitalmars-d-announce mailing list