C++ int float casting
Asked Answered
D

10

49

Why is m always = 0? The x and y members of someClass are integers.

float getSlope(someClass a, someClass b)
{           
    float m = (a.y - b.y) / (a.x - b.x);
    cout << " m = " << m << "\n";
    return m;
}
Durra answered 28/3, 2011 at 9:9 Comment(2)
Please review the answers you marked the wrong answer. (float) is no C++ it is C style.Sphalerite
this is a classic issue among programming learners; one good thing about javascript is it avoids issues with nonsense "integer division" which should throw errors, rather than output incorrect numbers. Javascript all numbers are floating pointBond
L
62

Integer division occurs, then the result, which is an integer, is assigned as a float. If the result is less than 1 then it ends up as 0.

You'll want to cast the expressions to floats first before dividing, e.g.

float m = static_cast<float>(a.y - b.y) / static_cast<float>(a.x - b.x);
Lamebrain answered 28/3, 2011 at 9:10 Comment(9)
..And watch out for division by zero!Pacifistic
@Pacifistic - It's not that dangerous to divide by 0, when we're talking about floating point numbers. You could safely divide any float number by 0.0 or -0.0, will give you inf. But yes, if it's unexpected, it will cause problems.Capitulate
@Kiril Kirov: Yeah it won't cause an exception/crash like integer division-by-zero does, but it leaves you with either +INF, -INF or NaN which will probably cause the OP further problems when he tries to use m.Pacifistic
@Lamebrain isn't it enough to cast any one of the elements of the expression to float? e.g. (static_cast<float>(a.y)-b.y)/(a.x-b.x)Verism
You should use a C++-style cast instead of a C-style cast in C++.Concordance
@Verism cast is useful to quiet a warning about the loss of precision withint to float, which typically needs to form a rounded float for large int values.Damnatory
@Lamebrain thanks for writing such a concise answer!Bond
@S.S. Anne: I finally fixed my answer since it's stayed accepted all these years. Little over 10 years and a month... better late than never, right? (I think I wasn't very active at the time you commented so I may have missed it.)Lamebrain
If you're not familiar with them, you might benefit more from learning templates and variadic types/functions. It would be no problem to make a function that uses either static_cast or perfect forwarding on its arguments before calling back to... whatever it is you were doing.Hollander
C
75

You need to use cast. I see the other answers, and they will really work, but as the tag is C++ I'd suggest you to use static_cast:

float m = static_cast< float >( a.y - b.y ) / static_cast< float >( a.x - b.x );
Capitulate answered 28/3, 2011 at 9:14 Comment(6)
I don't necessarily disagree, but counterpoints: (1) this is far less readable, and (2) less portableDeary
@Deary - "less portable" in what way?Capitulate
Namely, it couldn't be ported directly to C... again, just a counterpoint :)Deary
@Deary - C is completely different language. I don't qualify this as "portability issue", but I get your pointCapitulate
+1 this should be the correct answer as the OP asked for C++. stroustrup.com/bs_faq2.html#static-castBritannic
Why is everybody casting both operands? I thought if either n or d were floats, n/d would promote the other and do floating division, divf if you will. Personally I would lean toward making them doubles for the operation even if the destination is float (a cost of float's resolution near zero is that it has low resolution where large integers are still contiguous. Try casting the top few ints to float and back.)Hollander
L
62

Integer division occurs, then the result, which is an integer, is assigned as a float. If the result is less than 1 then it ends up as 0.

You'll want to cast the expressions to floats first before dividing, e.g.

float m = static_cast<float>(a.y - b.y) / static_cast<float>(a.x - b.x);
Lamebrain answered 28/3, 2011 at 9:10 Comment(9)
..And watch out for division by zero!Pacifistic
@Pacifistic - It's not that dangerous to divide by 0, when we're talking about floating point numbers. You could safely divide any float number by 0.0 or -0.0, will give you inf. But yes, if it's unexpected, it will cause problems.Capitulate
@Kiril Kirov: Yeah it won't cause an exception/crash like integer division-by-zero does, but it leaves you with either +INF, -INF or NaN which will probably cause the OP further problems when he tries to use m.Pacifistic
@Lamebrain isn't it enough to cast any one of the elements of the expression to float? e.g. (static_cast<float>(a.y)-b.y)/(a.x-b.x)Verism
You should use a C++-style cast instead of a C-style cast in C++.Concordance
@Verism cast is useful to quiet a warning about the loss of precision withint to float, which typically needs to form a rounded float for large int values.Damnatory
@Lamebrain thanks for writing such a concise answer!Bond
@S.S. Anne: I finally fixed my answer since it's stayed accepted all these years. Little over 10 years and a month... better late than never, right? (I think I wasn't very active at the time you commented so I may have missed it.)Lamebrain
If you're not familiar with them, you might benefit more from learning templates and variadic types/functions. It would be no problem to make a function that uses either static_cast or perfect forwarding on its arguments before calling back to... whatever it is you were doing.Hollander
A
9

you can cast both numerator and denominator by multiplying with (1.0) .

Anzac answered 5/6, 2021 at 13:36 Comment(1)
Ironically this answer avoids the unnecessary clunky syntax everyone else used and uses higher precision appropriately. Underrated.Hollander
M
2

You should be aware that in evaluating an expression containing integers, the temporary results from each stage of evaluation are also rounded to be integers. In your assignment to float m, the value is only converted to the real-number capable float type after the integer arithmetic. This means that, for example, 3 / 4 would already be a "0" value before becoming 0.0. You need to force the conversion to float to happen earlier. You can do this by using the syntax float(value) on any of a.y, b.y, a.x, b.x, a.y - b.y, or a.x - b.x: it doesn't matter when it's done as long as one of the terms is a float before the division happens, e.g.

float m = float(a.y - b.y) / (a.x - b.x); 
float m = (float(a.y) - b.y) / (a.x - b.x); 
...etc...
Muff answered 28/3, 2011 at 9:15 Comment(1)
(float(a.y) - b.y) / (a.x - b.x) is strange as it does a float subtraction for .y, yet an int subtraction for .x.Damnatory
T
0

Because (a.y - b.y) is probably less then (a.x - b.x) and in your code the casting is done after the divide operation so the result is an integer so 0.

You should cast to float before the / operation

Twice answered 28/3, 2011 at 9:12 Comment(0)
R
0

You are performing calculations on integers and assigning its result to float. So compiler is implicitly converting your integer result into float

Reach answered 28/3, 2011 at 9:34 Comment(0)
H
0

When doing integer division, the result will always be a integer unless one or more of the operands are a float. Just type cast one/both of the operands to a float and the compiler will do the conversion. Type casting is used when you want the arithmetic to perform as it should so the result will be the correct data type.

float m = static_cast<float>(a.y - b.y) / (a.x - b.x);
Heteropolar answered 13/9, 2020 at 3:5 Comment(1)
try to reEdit your answer by highlighting the codeSubinfeudate
C
-1

he does an integer divide, which means 3 / 4 = 0. cast one of the brackets to float

 (float)(a.y - b.y) / (a.x - b.x);
Chelyuskin answered 28/3, 2011 at 9:10 Comment(0)
N
-1

You can use ios manipulators fixed(). It will allow you to print floating point values.

Negotiate answered 28/12, 2021 at 15:24 Comment(0)
C
-2

if (a.y - b.y) is less than (a.x - b.x), m is always zero.

so cast it like this.

float m = ((float)(a.y - b.y)) / ((float)(a.x - b.x));
Corri answered 28/3, 2011 at 9:12 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.