www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - writeln double precision

reply Arun Chandrasekaran <aruncxy gmail.com> writes:
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
Oct 23 2017
parent reply Arun Chandrasekaran <aruncxy gmail.com> writes:
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?
Oct 23 2017
parent reply =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
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
Oct 23 2017
parent reply Arun Chandrasekaran <aruncxy gmail.com> writes:
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
Oct 24 2017
parent reply "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
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".
Oct 24 2017
next sibling parent reply jmh530 <john.michael.hall gmail.com> writes:
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+?
Oct 24 2017
parent "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
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.
Oct 24 2017
prev sibling parent reply Arun Chandrasekaran <aruncxy gmail.com> writes:
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
Oct 24 2017
next sibling parent =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
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
Oct 24 2017
prev sibling parent Jonathan M Davis <newsgroup.d jmdavisprog.com> writes:
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
Oct 25 2017