digitalmars.D.learn - Premature conversion
- =?ISO-8859-1?Q?Hans-Eric_Gr=f6nlund?= (7/7) Nov 07 2007 The code below:
- Regan Heath (14/22) Nov 07 2007 You are performing 'integer' division then converting the result to a
- Regan Heath (3/32) Nov 07 2007 I should have read your weblog first :)
- Bill Baxter (9/17) Nov 07 2007 I'm pretty sure the reason it works that way is because that's exactly
- Lutger (17/30) Nov 07 2007 I responded in your blog, but I might as well respond here too to this
- Steven Schveighoffer (26/30) Nov 07 2007 What if you *wanted* to do integer division, and then assign to a real?
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
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
Regan Heath wrote:Hans-Eric Grönlund wrote:I should have read your weblog first :) ReganThe 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.
Nov 07 2007
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
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önlundI 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
"Hans-Eric Grönlund" wroteThe 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