www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Premature conversion

reply =?ISO-8859-1?Q?Hans-Eric_Gr=f6nlund?= <hasse42g gmail.com> writes:
The code below:

real a = 5/2;

results in the, to me, unexpected value of 2 for the variable a. What's the
rationale behind this behavior? 

There are more details on my weblog:
http://www.hans-eric.com/2007/11/06/d-gotchas/

Best regards

Hans-Eric Grönlund
Nov 07 2007
next sibling parent reply Regan Heath <regan netmail.co.nz> writes:
Hans-Eric Grönlund wrote:
 The code below:
 
 real a = 5/2;
 
 results in the, to me, unexpected value of 2 for the variable a. What's the
rationale behind this behavior? 
 
 There are more details on my weblog:
 http://www.hans-eric.com/2007/11/06/d-gotchas/

You are performing 'integer' division then converting the result to a real. With integer division 5/2 is 2 remainder 1. This code behaves as you would expect (I suspect): real a = 5.0/2.0; Here 5.0 and 2.0 are floating point literals, not integer literals so floating point division is performed resulting in 2.5. These also work as you'd expect: real a = 5/2.0; real a = 5.0/2; because D will promote integer literals to floating point in these cases. I'm sure there are some rules on the D website for how and when and why it promotes integers to floats and so on but I can't find them at present. Regan
Nov 07 2007
parent Regan Heath <regan netmail.co.nz> writes:
Regan Heath wrote:
 Hans-Eric Grönlund wrote:
 The code below:

 real a = 5/2;

 results in the, to me, unexpected value of 2 for the variable a. 
 What's the rationale behind this behavior?
 There are more details on my weblog:
 http://www.hans-eric.com/2007/11/06/d-gotchas/

You are performing 'integer' division then converting the result to a real. With integer division 5/2 is 2 remainder 1. This code behaves as you would expect (I suspect): real a = 5.0/2.0; Here 5.0 and 2.0 are floating point literals, not integer literals so floating point division is performed resulting in 2.5. These also work as you'd expect: real a = 5/2.0; real a = 5.0/2; because D will promote integer literals to floating point in these cases. I'm sure there are some rules on the D website for how and when and why it promotes integers to floats and so on but I can't find them at present.

I should have read your weblog first :) Regan
Nov 07 2007
prev sibling next sibling parent Bill Baxter <dnewsgroup billbaxter.com> writes:
Hans-Eric Grönlund wrote:
 The code below:
 
 real a = 5/2;
 
 results in the, to me, unexpected value of 2 for the variable a. What's the
rationale behind this behavior? 
 
 There are more details on my weblog:
 http://www.hans-eric.com/2007/11/06/d-gotchas/

I'm pretty sure the reason it works that way is because that's exactly how it works in C (and C++). So making 5/2 result in 2.5 would be a "gotcha" for any C programmer expecting D to act more or less like C. Python has been transitioning from having rules like C to having a special integer division operator, //. So in Python with the new rules (or with 'from future import division') 5/2 is 2.5 and 5//2 is 2. Personally I don't have a problem with either way. --bb
Nov 07 2007
prev sibling next sibling parent Lutger <lutger.blijdestijn gmail.com> writes:
Hans-Eric Grönlund wrote:
 The code below:
 
 real a = 5/2;
 
 results in the, to me, unexpected value of 2 for the variable a. What's the
rationale behind this behavior? 
 
 There are more details on my weblog:
 http://www.hans-eric.com/2007/11/06/d-gotchas/
 
 Best regards
 
 Hans-Eric Grönlund
 

I responded in your blog, but I might as well respond here too to this question. Speaking for myself, I understand the rationale as follows: 1. in assignment, the expression on the right hand side is evaluated and then assigned to the left hand side. 2. if the types don't match, the rhs is implicitly converted if that is allowed. In this case, the '/' operator is defined for integral operands, thus the result is an integer division which is then converted to a floating point type. This makes it intuitive for me, I would be surprised if the expression on the right hand side is evaluated differently depending on the type of the left hand side. That would be a gotcha, especially if the expression is more complicated. If floating point and integral division would have different operators this reasoning wouldn't apply. But that's another story.
Nov 07 2007
prev sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
"Hans-Eric Grönlund" wrote
 The code below:

 real a = 5/2;

 results in the, to me, unexpected value of 2 for the variable a. What's 
 the rationale behind this behavior?

What if you *wanted* to do integer division, and then assign to a real? I look at this problem EXACTLY like operator precendence. For example, what does x become in the following equation? int x = 1 + 2 * 3; If you evaluate (1+2) first, then the result is 9. If you evaluate (2*3) first, the result is 7. So why isn't it 9? Because the rules state that you do multiplication first. Back to your example, the compiler has rules, which you must observe to get what you want. The compiler doesn't know what you are thinking, so in ambiguous cases you must tell it what you want if what you want is not the default. In D, the rule is to evaluate the rhs first, then promote if necessary during assignment. In this case, (as you note on your blog): real a = 5.0/2; This tells the compiler you want to do the conversion to floating point BEFORE the operation. In the case of wanting 1+2 evaluated first: int x = (1 + 2) * 3; So complaining that your statement results in 2, and not 2.5 is like complaining that the compiler didn't know you wanted to do addition before multiplication. You may now ask, why isn't the default the other way around? Well, I can't really answer that question :) But I hope the behavior doesn't change because I'm sure it would break a lot of code that expects to do integer division. -Steve
Nov 07 2007