Reputation: 51
Given the following:
int a = 10, b = 5, c = 3, d = 1;
int x = 3, y = 2, z = 2;
return (float) a/x + b/y + c/z + d;
This presumably casts our precision to float and then performs our sequence of divisions at floating point precision.
What is the correct way to update this using C++ style casts?
Should this really be rewritten as:
return static_cast<float>(a) / static_cast<float>(b) + ... ?
Upvotes: 3
Views: 481
Reputation: 88215
int a = 10, b = 5, c = 3, d = 1;
int x = 3, y = 2, z = 2;
return (float) a/x + b/y + c/z + d;
This presumably casts our precision to float and then performs our sequence of divisions at floating point precision.
No, it casts a
to float
and so a/x
is performed as a floating point divide, but b/y
and c/z
are integer divides. Afterwards, the sums are computed after converting the integer division results to float.
This is because casts are simply another operator, and they have higher precedence than +
and /
. Dividing float
by an int
or adding a float
to an int
causes the int
s to be automatically converted to float
s.
If you want floating point division then you need to insert casts so that they are applied prior to the divisions, and then the other values get automatically promoted.
return (float) a/x + (float) b/y + (float) c/z + d;
Casting using C++ syntax is exactly the same, except the syntax won't let you get confused about what's actually being cast:
return static_cast<float>(a)/x + static_cast<float>(b)/y + static_cast<float>(c)/z + d;
You can also use constructor syntax, which also has the benefit of clearly showing what's cast:
return float(a)/x + float(b)/y + float(c)/z + d;
Or you can simply use temporary variables:
float af = a, bf = b, cf = c;
return af/x + bf/y + cf/z + d;
Upvotes: 0
Reputation: 106102
return (float) a/x + b/y + c/z + d;
is not correct if you want to return the float
value of sum of all divisions. In above expression only a/x
is float
division and rest of them are int
division (because of heiger precedence of /
operator than +
) which will result in value truncation. Better to stick with
return (double)a/x + (double)b/y + (double)c/z + d;
Upvotes: 1
Reputation: 6707
The cast is only necessary with division operation. And you can lighten syntax this way:
return 1.0*a/x + 1.0*b/y + 1.0*c/z + d;
This will compute the result as double
type, that gets automatically casted to float
if the function returns this type.
Upvotes: -1
Reputation: 726929
Start by correcting your code:
(float) a/x + b/y + c/z + d
produces 7.33333
, while the correct result is 8.33333
. Why? because b/y
and c/z
divisions are done in int
s (demo).
The reason the result is incorrect is that division takes precedence over addition: your program needs to divide b
by y
and c
by z
before adding them to the result of division of a
by x
, which is float
.
You need to cast one of the division operands to get this to work correctly. C cast works fine, but if you would rather use C++-style cast, here is how you can do it:
return static_cast<float>(a) / b + static_cast<float>(b) / y +
static_cast<float>(c) / z + d;
Upvotes: 7
Reputation: 157454
/
has higher precedence than +
, so b/y
will be performed in int
, not in float
.
The correct way to perform each division in float
is to cast at least one operand to float
:
static_cast<float>(a)/x + static_cast<float>(b)/y + static_cast<float>(c)/z + d
This is clearer than the equivalent C expression:
(float) a/x + (float) b/y + (float) c/z + d
Here one requires knowledge of precedence to realise that the cast to float
binds tighter than the division.
Upvotes: 5