January 11, 2018 Re: Another take on decimal data types | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | On Thu, Jan 11, 2018 at 04:38:57PM -0500, Steven Schveighoffer via Digitalmars-d-announce wrote: > On 1/11/18 4:12 PM, kdevel wrote: > > On Thursday, 11 January 2018 at 20:40:01 UTC, Dmitry Olshansky wrote: > > > What did you expect? > > > > To be honest: A compile time error. Modern C compilers can check such format strings. Example: GCC 6: > > But dmd isn't a C compiler, nor does it have to worry about the problems C has (namely, untyped varargs). To dmd, printf is just another function, there's nothing special about it. [...] Yeah, checking C-style printf formats isn't dmd's problem. The Phobos equivalent of printf, however, *does* support compile-time format checking in the latest version: writefln!"%s %d %d"("abc", 1); // "Orphan format specifier: %d" writefln!"%s %d"("abc", 1, 2); // "Orphan format arguments: args[2..3]" writefln!"%s %d"(1, "abc"); // "Incorrect format specifier for range: %d" writefln!"%f"(1); // "incompatible format character for integral argument: %f" Best of all, this is all done via CTFE in the library code, no hard-coding in the compiler necessary. You can implement your own compile-time checker for your own DSLs in the same way, without needing to hack the compiler. T -- MSDOS = MicroSoft's Denial Of Service |
January 11, 2018 Re: Another take on decimal data types | ||||
---|---|---|---|---|
| ||||
Posted in reply to Seb | On 2018-01-11 15:34:04 +0000, Seb said: >> Side-Note: I'm always missing the betterC information or is the philosophy to just try it out? > > We have now this page: > > https://dlang.org/spec/betterc.html Hi, thanks. Should have been more precise: An informaiton for every lib if it is compatible with betterC. IMO betterC is the strategic trojan horse to get D into the broader masses. > Well, betterC it's still a WIP feature and its feature subset is improved from release to release. > In doubt you can always use run.dlang.io to quickly try out things. That's great, thanks for the hint. -- Robert M. Münch http://www.saphirion.com smarter | better | faster |
January 11, 2018 Re: Another take on decimal data types | ||||
---|---|---|---|---|
| ||||
Posted in reply to rumbu Attachments:
| On 2018-01-11 18:15:23 +0000, rumbu said: > On Thursday, 11 January 2018 at 11:19:41 UTC, Robert M. Münch wrote: >> >> Great stuff! Will this work in betterC mode? > > It will not work without some refactory. Most of phobos/druntime dependencies are minimal an can be rewritten - in fact there are only 9 dependencies: bsr, bsf, addu, subu, adds, subs from druntime and isNaN, isinfinity, signbit from std.math. > > The rest of the dependencies are simply traits that must work by default under betterC. Ok, that doesn't sound impossible. > Once dependencies are solved, another problem will be the exception mechanism. 90% of arithmetic operations are meant to throw exceptions, but this can be overridden by the alternate exception handling - raising and setting flags. Yes, makes sense. > BUT - a very big but - the most important issue is the formatting thing. > ... > a printf equivalent for decimal types is rewritten from scratch or - > decimal values must be converted to binary float before printing them - > but this will negate the main purpose of the decimal type - precision. Well, I think even using a decimal128 for some calculations to have higher precision intermediate results and only converting them to float for UI interaction would make a lot of sense. At least in our use-case, that would be quite interesting. Looking forward to see some benchmarks. -- Robert M. Münch http://www.saphirion.com smarter | better | faster |
January 11, 2018 Re: Another take on decimal data types | ||||
---|---|---|---|---|
| ||||
Posted in reply to kdevel | On Thursday, 11 January 2018 at 21:24:30 UTC, kdevel wrote:
> On Thursday, 11 January 2018 at 20:44:13 UTC, kdevel wrote:
>> On Thursday, 11 January 2018 at 20:35:03 UTC, kdevel wrote:
>>> <--- loop output missing
>
> loop.d
> ```
> import std.stdio;
> import decimal;
>
> void loopme(T) ()
> {
> "---".writeln;
> T e = T(1000);
> while (e > T(1e-6)) {
> e.writeln;
> e /= 10;
> }
> }
>
> void main ()
> {
> loopme!float;
> loopme!decimal32;
> }
> ```
>
> This prints
>
> ---
> 1000
> 100
> 10
> 1
> 0.1
> 0.01
> 0.001
> 0.0001
> 1e-05
> ---
> 1000
> 100
> 10
> 1
> 0.1
> 0.0100000 <--
> 0.00100000 <--
> 0.000100000 <--
> 1.00000e-05 <--
>
> Why are there trailing zeroes?
As I said, the %g specifier (used by default in writeln) makes me cry. Anyway, I made some modifications, now it prints correctly (in fact using floats just proves the need of decimals on my system):
--
1000
100
10
1
0.1
0.01
0.00099999
0.000099999
1e-05
---
1000
100
10
1
0.1
0.01
0.001
0.0001
1e-05
Regarding printf, I cannot help, this is a C function, has nothing to do with D formatting.
|
January 11, 2018 Re: Another take on decimal data types | ||||
---|---|---|---|---|
| ||||
Posted in reply to rumbu | On Thursday, 11 January 2018 at 22:36:40 UTC, rumbu wrote:
> 1000
> 100
> 10
> 1
> 0.1
> 0.01
> 0.001
> 0.0001
> 1e-05
>
> Regarding printf, I cannot help, this is a C function, has nothing to do with D formatting.
Sure. What about the failed comparison:
gt.d
```
import std.stdio;
import decimal;
void loopme(T) ()
{
"---".writeln;
T e = 10;
while (e > 1e-6) {
e /= 10;
writeln (e, ' ', e > 1e-6);
}
}
void main ()
{
loopme!decimal32;
loopme!decimal64;
loopme!decimal128;
}
```
This gives here:
---
1 true
0.1 false
---
1 true
0.1 false
---
1 true
0.1 true
0.0100000 true
0.00100000 true
0.000100000 true
1.00000e-05 true
1.00000e-06 true
1.00000e-07 false
|
January 12, 2018 Re: Another take on decimal data types | ||||
---|---|---|---|---|
| ||||
Posted in reply to kdevel | On Thursday, 11 January 2018 at 23:57:29 UTC, kdevel wrote: What about the failed comparison: > > gt.d > ``` > import std.stdio; > import decimal; > > void loopme(T) () > { > "---".writeln; > T e = 10; > while (e > 1e-6) { > e /= 10; > writeln (e, ' ', e > 1e-6); > } > } > > void main () > { > loopme!decimal32; > loopme!decimal64; > loopme!decimal128; > } > ``` > > This gives here: > > --- > 1 true > 0.1 false > --- > 1 true > 0.1 false > --- > 1 true > 0.1 true > 0.0100000 true > 0.00100000 true > 0.000100000 true > 1.00000e-05 true > 1.00000e-06 true > 1.00000e-07 false This is not failed comparison. 1e-6 cannnot be represented exactly as binary floating point, it is in fact 0.00000099999999999999995481 as double which happens to be less than 1e-6. decimal32 and decimal64 are rounding up the value, decimal128 has enough precision (34 digits) to render exactly the value above. writefln(" 7 digits: %#.7f", 1e-6); writefln("15 digits: %#.15f", 1e-6); writefln("34 digits: %#.34f", 1e-6); ----- 7 digits: 0.0000010 15 digits: 0.000001000000000 34 digits: 0.0000009999999999999999548100000000 |
January 12, 2018 Re: Another take on decimal data types | ||||
---|---|---|---|---|
| ||||
Posted in reply to rumbu | > On Thursday, 11 January 2018 at 23:57:29 UTC, kdevel wrote:
> What about the failed comparison:
>>
....
You are right in fact, there is also a failed comparison. Now corrected.
|
January 12, 2018 Re: Another take on decimal data types | ||||
---|---|---|---|---|
| ||||
Posted in reply to rumbu | On Friday, 12 January 2018 at 05:18:15 UTC, rumbu wrote:
>> On Thursday, 11 January 2018 at 23:57:29 UTC, kdevel wrote:
>> What about the failed comparison:
>>>
> ....
>
> You are right in fact, there is also a failed comparison. Now corrected.
Works. Thanks for the changes!
|
January 12, 2018 Re: Another take on decimal data types | ||||
---|---|---|---|---|
| ||||
Posted in reply to rumbu | On Monday, 8 January 2018 at 22:16:25 UTC, rumbu wrote: > - all std.math functions implemented (even logarithms and trigonometry); nosine.d ``` import std.stdio; // import std.math; import decimal; void nosine (T) () { T d = T(1.1); writeln (sin(d)); } void main () { nosine!decimal32; nosine!decimal64; nosine!decimal128; } ``` $ dmd nosine.d decimal.git/libdecimal.a decimal/package.d(10505): Error: undefined identifier decimalCapAngle decimal/package.d(5364): Error: template instance decimal.decimalSin!(Decimal!32) error instantiating nosine.d(8): instantiated from here: sin!(Decimal!32) nosine.d(13): instantiated from here: nosine!(Decimal!32) decimal/package.d(10505): Error: undefined identifier decimalCapAngle decimal/package.d(5364): Error: template instance decimal.decimalSin!(Decimal!64) error instantiating nosine.d(8): instantiated from here: sin!(Decimal!64) nosine.d(14): instantiated from here: nosine!(Decimal!64) decimal/package.d(10505): Error: undefined identifier decimalCapAngle decimal/package.d(5364): Error: template instance decimal.decimalSin!(Decimal!128) error instantiating nosine.d(8): instantiated from here: sin!(Decimal!128) nosine.d(15): instantiated from here: nosine!(Decimal!128) |
January 12, 2018 Re: Another take on decimal data types | ||||
---|---|---|---|---|
| ||||
Posted in reply to H. S. Teoh | On Thursday, 11 January 2018 at 22:07:42 UTC, H. S. Teoh wrote: > On Thu, Jan 11, 2018 at 04:38:57PM -0500, Steven Schveighoffer via Digitalmars-d-announce wrote: >> On 1/11/18 4:12 PM, kdevel wrote: >> > On Thursday, 11 January 2018 at 20:40:01 UTC, Dmitry Olshansky wrote: >> > > What did you expect? >> > >> > To be honest: A compile time error. Modern C compilers can check such format strings. Example: GCC 6: >> >> But dmd isn't a C compiler, nor does it have to worry about the problems C has (namely, untyped varargs). To dmd, printf is just another function, there's nothing special about it. > [...] > > Yeah, checking C-style printf formats isn't dmd's problem. > > The Phobos equivalent of printf, however, *does* support compile-time format checking in the latest version: > > writefln!"%s %d %d"("abc", 1); // "Orphan format specifier: %d" > writefln!"%s %d"("abc", 1, 2); // "Orphan format arguments: args[2..3]" > writefln!"%s %d"(1, "abc"); // "Incorrect format specifier for range: %d" > writefln!"%f"(1); // "incompatible format character for integral argument: %f" > > Best of all, this is all done via CTFE in the library code, no hard-coding in the compiler necessary. You can implement your own compile-time checker for your own DSLs in the same way, without needing to hack the compiler. Interesting, guess this was added last April with dmd 2.074? https://dlang.org/changelog/2.074.0.html#std-format-formattedWrite You or someone should write up a blog post about this, with both this example and expanding on how D enables this kind of functionality in general. |
Copyright © 1999-2021 by the D Language Foundation