Thread overview | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
|
October 23, 2017 writeln double precision | ||||
---|---|---|---|---|
| ||||
I've written a simple tool [1] to find the DET and CMC specifically for biometrics performance measurement. When I generate the report, I expected to see high precision floating point numbers, but I see that writefln trims the precision to the last 6 digits after decimal point. Am I doing the right thing here? Should I use a different format specifier? [1] https://bitbucket.org/carun/biometrics-reports/src Cheers, Arun |
October 23, 2017 Re: writeln double precision | ||||
---|---|---|---|---|
| ||||
Posted in reply to Arun Chandrasekaran | On Monday, 23 October 2017 at 14:07:06 UTC, Arun Chandrasekaran wrote:
> I've written a simple tool [1] to find the DET and CMC specifically for biometrics performance measurement.
>
> When I generate the report, I expected to see high precision floating point numbers, but I see that writefln trims the precision to the last 6 digits after decimal point.
>
> Am I doing the right thing here? Should I use a different format specifier?
>
> [1] https://bitbucket.org/carun/biometrics-reports/src
>
> Cheers,
> Arun
```
void main() {
double a = 22/7.0;
import std.stdio: writeln, writefln;
writefln("%.51f", a);
}
```
and it prints all the decimals. So I'm happy that I have not lost the precision. But why does the compiler bring the C baggage for the integer division? Why do I need to `cast (double)` ? Can't the compiler figure it out?
|
October 23, 2017 Re: writeln double precision | ||||
---|---|---|---|---|
| ||||
Posted in reply to Arun Chandrasekaran | On 10/23/2017 07:22 AM, Arun Chandrasekaran wrote: > void main() { > double a = 22/7.0; > import std.stdio: writeln, writefln; > writefln("%.51f", a); > } > But why does the compiler bring the C baggage for the integer > division? Why do I need to `cast (double)` ? I think you mean having to write 7.0 to bring a double into the expression. > Can't the compiler figure > it out? Yes, it can but we don't want that. Otherwise, the code would be too slippery to keep under control. For example, introducing the following temporary variable would change the semantics: // Before: foo(22/7); // After double temp = 22/7; foo(temp); // Is this the same call with the same value? Writing the above made me aware that function overloading would be too cumbersome as the compiler would find too many potential matches for the expressions. For example, should it convert 22/7 to float or double or long, etc. The rule is that every expression has a type and 22/7 is int. The rules are carried from C and can be tricky. Both "Integer Promotions" and "Usual Arithmetic Conversion" are interesting here: https://dlang.org/spec/type.html#integer-promotions Ali |
October 24, 2017 Re: writeln double precision | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ali Çehreli | On Monday, 23 October 2017 at 18:08:43 UTC, Ali Çehreli wrote:
> On 10/23/2017 07:22 AM, Arun Chandrasekaran wrote:
> > [...]
> The rule is that every expression has a type and 22/7 is int.
Thanks Ali. Is this for backward compatibility with C? Because, if there is a division, a natural/mathematical (not programmatic) expectation is to see a a double in the result.
Arun
|
October 24, 2017 Re: writeln double precision | ||||
---|---|---|---|---|
| ||||
Posted in reply to Arun Chandrasekaran | On Tue, Oct 24, 2017 at 10:02:11AM +0000, Arun Chandrasekaran via Digitalmars-d-learn wrote: > On Monday, 23 October 2017 at 18:08:43 UTC, Ali Çehreli wrote: > > On 10/23/2017 07:22 AM, Arun Chandrasekaran wrote: > > > [...] > > The rule is that every expression has a type and 22/7 is int. > > Thanks Ali. Is this for backward compatibility with C? Because, if there is a division, a natural/mathematical (not programmatic) expectation is to see a a double in the result. [...] I have never seen a programming language in which dividing two integers yields a float or double. Either numbers default to a floating point type, in which case you begin with floats in the first place, or division is integer division, yielding an integer result. T -- Real Programmers use "cat > a.out". |
October 24, 2017 Re: writeln double precision | ||||
---|---|---|---|---|
| ||||
Posted in reply to H. S. Teoh | On Tuesday, 24 October 2017 at 16:18:03 UTC, H. S. Teoh wrote:
>
> I have never seen a programming language in which dividing two integers yields a float or double. Either numbers default to a floating point type, in which case you begin with floats in the first place, or division is integer division, yielding an integer result.
>
>
> T
Haven't used Python 3+?
|
October 24, 2017 Re: writeln double precision | ||||
---|---|---|---|---|
| ||||
Posted in reply to H. S. Teoh | On Tuesday, 24 October 2017 at 16:18:03 UTC, H. S. Teoh wrote:
> On Tue, Oct 24, 2017 at 10:02:11AM +0000, Arun Chandrasekaran via Digitalmars-d-learn wrote:
>> On Monday, 23 October 2017 at 18:08:43 UTC, Ali Çehreli wrote:
>> > On 10/23/2017 07:22 AM, Arun Chandrasekaran wrote:
>> > > [...]
>> > The rule is that every expression has a type and 22/7 is int.
>>
>> Thanks Ali. Is this for backward compatibility with C? Because, if there is a division, a natural/mathematical (not programmatic) expectation is to see a a double in the result.
> [...]
>
> I have never seen a programming language in which dividing two integers yields a float or double. Either numbers default to a floating point type, in which case you begin with floats in the first place, or division is integer division, yielding an integer result.
>
>
> T
I'm not denying that all the programming languages does it this way (even if it is a cause of related bugs).
I'm just questioning the reasoning behind why D does it this way and if it is for compatibility or if there is any other reasoning behind the decision.
Arun
|
October 24, 2017 Re: writeln double precision | ||||
---|---|---|---|---|
| ||||
Posted in reply to Arun Chandrasekaran | On 10/24/2017 09:59 AM, Arun Chandrasekaran wrote: >>> On Monday, 23 October 2017 at 18:08:43 UTC, Ali Çehreli wrote: >>> > The rule is that every expression has a type and 22/7 is int. > I'm just questioning the reasoning behind why D does it this way and if > it is for compatibility or if there is any other reasoning behind the > decision. I'm not a language designer so I can't be sure but I think it has the same reasons that it has in C. The alternative would not be fit for a system language because we wouldn't know what types would be used for certain operations. And types are related to performance because they may be operated on different sets of CPU registers. In the case of floating point, a CPU need not have floating registers at all. So, we don't want types slip from under our grasp because the compiler decided to help the programmer. (One may think that all common CPUs have FP processing units today but it may not be the case in the future. For example, the not-yet-shipping Mill CPU can be configured to have zero or more processing units of any kind.) And we haven't talked about what type 14/7 should be. If we want that to be int, then I think we're in bigger trouble. (I think a timing values should be shorter than 22/7 and suddenly I get an int in my hand.) And only after writing that last sentence I realize that perhaps you meant this only for literals. If so, having same rules for literals vs. variables is beneficial and very important. There are known problems with C, C++, and D compilers' choosing finer precision during compile time for floating point literals during macro expansions. For example, calculations end up having different results on different compilations. Languages like Python 3+ can afford all of this because types or performance don't play a strong role in that environment. ;) Ali |
October 24, 2017 Re: writeln double precision | ||||
---|---|---|---|---|
| ||||
Posted in reply to jmh530 | On Tue, Oct 24, 2017 at 04:59:04PM +0000, jmh530 via Digitalmars-d-learn wrote: > On Tuesday, 24 October 2017 at 16:18:03 UTC, H. S. Teoh wrote: > > > > I have never seen a programming language in which dividing two integers yields a float or double. Either numbers default to a floating point type, in which case you begin with floats in the first place, or division is integer division, yielding an integer result. > > > > > > T > > Haven't used Python 3+? Haha, I guess I'm behind the times! T -- Gone Chopin. Bach in a minuet. |
October 25, 2017 Re: writeln double precision | ||||
---|---|---|---|---|
| ||||
Posted in reply to Arun Chandrasekaran | On Tuesday, October 24, 2017 16:59:31 Arun Chandrasekaran via Digitalmars-d- learn wrote:
> On Tuesday, 24 October 2017 at 16:18:03 UTC, H. S. Teoh wrote:
> > On Tue, Oct 24, 2017 at 10:02:11AM +0000, Arun Chandrasekaran
> >
> > via Digitalmars-d-learn wrote:
> >> On Monday, 23 October 2017 at 18:08:43 UTC, Ali Çehreli wrote:
> >> > On 10/23/2017 07:22 AM, Arun Chandrasekaran wrote:
> >> > > [...]
> >> >
> >> > The rule is that every expression has a type and 22/7 is int.
> >>
> >> Thanks Ali. Is this for backward compatibility with C? Because, if there is a division, a natural/mathematical (not programmatic) expectation is to see a a double in the result.
> >
> > [...]
> >
> > I have never seen a programming language in which dividing two integers yields a float or double. Either numbers default to a floating point type, in which case you begin with floats in the first place, or division is integer division, yielding an integer result.
> >
> >
> > T
>
> I'm not denying that all the programming languages does it this
> way (even if it is a cause of related bugs).
> I'm just questioning the reasoning behind why D does it this way
> and if it is for compatibility or if there is any other reasoning
> behind the decision.
Part of it is compatibility. In general, valid C code should either be valid D code with the same semantics, or it shouldn't compile. We haven't done a perfect job with that, but we're close. And dividing two integers resulting in a floating point value doesn't fit with that at all. But regardless of that, there's the question of whether it's even desirable, and in a language that's geared towards performance, it really isn't. Also, many us don't want floating point values creeping into our code anywhere without us being explicit about it. Floating point math is not precise in the way that integer math is, and IMHO it's best to be avoided if it's not needed. Personally, I avoid using floating point types as much as possible and only use them when I definitely need them. If they acted like actual math, that would be one thing, but they don't, because they live in a computer, and D's built-in numerical types are closely modeled after what's in the hardware.
Obviously, floating point types can be quite useful, and we want them to work properly, but having stuff automatically convert to floating point types on you without being asked would be a serious problem. And in general, D is far more strict about implicit conversions than C/C++ is, not less. So, it would be really out of character for it to do floating point division with two integers.
- Jonathan M Davis
|
Copyright © 1999-2021 by the D Language Foundation