problem with std.variant rounding

via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Fri Apr 28 09:53:19 PDT 2017


On Friday, 28 April 2017 at 16:42:28 UTC, Petar Kirov 
[ZombineDev] wrote:
> On Friday, 28 April 2017 at 16:24:55 UTC, Suliman wrote:
>> On Friday, 28 April 2017 at 15:45:25 UTC, Suliman wrote:
>>> I am using https://github.com/mysql-d/mysql-native
>>> It's return from DB variant data-type.
>>>
>>> My DB include value: 56.051151 (double type in DB)
>>>
>>> I need to extract it. I tried several variants:
>>>
>>> writeln(point[3].coerce!float);
>>> writeln(point[3].coerce!string);
>>> writeln(point[3].coerce!double);
>>>
>>> but all of them return me it as: 56.0512
>>>
>>> How to return exactly 56.051151 ?
>>
>> import std.stdio;
>> import std.variant;
>>
>> void main()
>> {
>> 	Variant b = 56.051151;
>> 	float x = b.coerce!float;
>> 	writeln(x);
>> }
>>
>>>56.0512
>
> The precision is still there, you're just not requesting it:
>
> import std.conv : text;
> import std.stdio;
> import std.variant;
>
> void main()
> {
>     Variant b = 56.051151;
>     float x = b.coerce!float;
>
>     foreach (i; 0 .. 10)
>         writefln(text("%.", i, "f"), x);
> }
>
> 56
> 56.1
> 56.05
> 56.051
> 56.0512
> 56.05115
> 56.051151
> 56.0511513
> 56.05115128
> 56.051151276
>
>> How to return exactly 56.051151 ?
>
> Specify the number of digits after the decimal point manually, 
> e.g. writefln("%.6f", x) will print 56.051151.

BTW, you should always try to use the same floating-point type, 
so if you use 64-bit doubles in the database, you should also use 
double in your D code, otherwise you may accumulate rounding 
errors after each conversion. When converting to smaller 
floating-point types (real -> double and double -> float) you are 
essentially throwing out precision. For example:

import std.conv : text;
import std.stdio;
import std.variant;

void main()
{
     Variant b = 56.051151;

     foreach (i; 0 .. 16)
     {
         writefln(text("%.", i, "f"), b.coerce!float);
         writefln(text("%.", i, "f"), b.coerce!double);
     }
}

Notice how the floats and doubles differ at i >= 6.

56
56
56.1
56.1
56.05
56.05
56.051
56.051
56.0512
56.0512
56.05115
56.05115
56.051151
56.051151
56.0511513
56.0511510
56.05115128
56.05115100
56.051151276
56.051151000
56.0511512756
56.0511510000
56.05115127563
56.05115100000
56.051151275635
56.051151000000
56.0511512756348
56.0511510000000
56.05115127563477
56.05115100000000
56.051151275634766
56.051150999999997


More information about the Digitalmars-d-learn mailing list