what the conversion is applied in the expression (double to int) - c++

there is an expression (as a part of median calculation):
auto iter1 = std::next(first, floor(size/2) - 1 );
double result = *iter1 + *(iter1 + 1)) / 2;
where the type of the value under iterators is int.
expected result e.g.:
1.5 = (1 + 2 ) / 2
however , in case of values 1 and 2 the result is 1, looks like implicit conversion to int
please explain, what the rule (or my misunderstanding?) is applied here

In your second expression double result = *iter1 + *(iter1 + 1)) / 2;: as per operator precedence, the evaluation of *(iter1 + 1)) / 2 is done first; and since the operands of the / operator are both ints, the sub-expression will result in integer division. The result of the integer division is then added to *iter1.
there is an expression (as a part of median calculation):
double result = *iter1 + *(iter1 + 1)) / 2;
Since the common type of the expression in the right hand side is an int. No conversion is done. Having at least one double will fix you problem. (Also note the parenthesis I added to fit your example).
double result = (*iter1 + static_cast<double>(*(iter1 + 1))) / 2.0;

Related

Why does the increment/decrement operators break the recursion functionality [duplicate]

This question already has answers here:
Order of evaluation in C++ function parameters
(6 answers)
Closed 2 years ago.
func(int n)
// the function should return the sum of the first n term of the
// harmonic series (1/1 + 1/2 + 1/3 + ... + 1/n )
double sumover(int n)
{
if (n == 0)
return 0;
else
{
return (1. / n) + sumover(--n); // here is the bug
}
}
When the function is called with n = 1, I am expecting it to compute 1. / 1 + sumover(0) = 1 / 1 + 0
However, it's computing 1./0 + sumover(0) , why?
return (1. / n) + sumover(--n);
There is no guarantee that the term (1. / n) will be calculated before sumover(--n).
The standard doesn't specify that.
Hence the second term may be calculated firstly, then (1. / n) becomes (1. /(n - 1)) and then you get an unexpected output.
Replace it by
return (1. / n) + sumover(n - 1);

Explicit casting in C/C++

After reading several SO posts on the subject I am still confused, mainly concerning to integer and boolean variables/expressions.
A. Integer expressions
Suppose I want to use modulo expression in a floating point computation, what, if any, is the most correct of the following? Is there any difference between C and C++? or should I just trust the compiler to make the correct conversion?
double sign;
int num = rand() % 100;
//want to map odd num to -1.0 and even num to 1.0
//A
sign = -2 * (num % 2) + 1;
//B
sign = -2.0 * (num % 2) + 1;
//C
sign = -2.0 * (num % 2) + 1.0;
//D
sign = -2 * (num % 2) + 1.0;
//E
sign = -2 * (double)(num % 2) + 1;
//F
sign = -2.0 * (double)(num % 2) + 1;
//G
sign = -2.0 * (double)(num % 2) + 1.0;
//H
sign = -2 * (double)(num % 2) + 1.0;
B. Boolean expressions
Can I use a boolean expression, safely, as an element in floating / integer computations without explicit casting? Is there a difference between C and C++?
double d_res = 1.0;
int i_res = 1;
int num = rand() % 10;
d_res = d_res + (num > 5);//or d_res = d_res + (double)(num > 5)?
i_res += (num > 5);//or i_res += (int)(num > 5)?
A. The initialization
double sign = -2 * (num % 2) + 1;
is perfectly well-defined. That's what I'd use; I don't think there's any need to complicate things with extra casts or anything.
C and C++ are well-defined and convenient in their implicit conversions between integer and floating-point types. Explicit conversions are usually not needed. In my experience there are only three things to worry about:
Code like double ratio = 1 / 3 doesn't do what you want; you need to force one of the operands to / to be floating-point. (This has nothing to do with your question, but it's an extremely easy mistake to make.)
Overflow, if one type or the other can't represent the value. (Also not a problem for your example.)
Overzealous compilers. Many compilers will "helpfully" warn you that you might lose precision when converting from double to float, or from a floating-point type to an integer. So you may need explicit casts to silence those warnings.
B. Asking for the numeric value of a Boolean is perfectly well-defined (is guaranteed to give you a nice, clean, 1 or 0), so your second fragment should be fine also. (I know this is true for C, and per a comment below, it's true for C++ also.)

Can someone explain how the shorthand assignment operator actually works?

#include <iostream>
using namespace std;
int main()
{
int x=2,a=3,b=2;
x*=a/b;
cout<<x<<" ";
x=2;
x=x*a/b;
cout<<x;
return 0;
}
I am getting output as:
2
3
while in my opinion x*=a/b; and x=x*a/b; mean the same thing.
Can anybody explain this behaviour?
They are not quite the same.
x *= a / b is grouped as x *= (a / b) and a / b takes place in integer arithmetic (it's 1).
x = x * a / b is grouped as x = ((x * a) / b). the integer division has a less drastic and different effect.
With integer division: 3/2 is 1.
x*=a/b; is evaluated as x *= (a / b) so x *= 3 / 2 -> x *= 1.
x=x*a/b; is evaluated as x = (x * a) / b; so (2 * 3) / 3 -> 6 / 2 -> 3
I am getting output as: 2 3 while in my opinion x*=a/b; and x=x*a/b;
mean the same thing. Can anybody explain this behaviour?
x *= a / b;
// ^^^^^
This is integer division, the rest is discarded and therefore 3 / 2 is 1.
Therefore the expression x *= a / b is the same as x *= 1 which stays 2.
x = x * a / b;
On the other hand is evaluated as
x = (x * a) / b;
The result is then
x = (2 * 3) / 2;
becomes
x = 6 / 2;
which is 3
Per [expr.ass]/6 E1 *= E2 is exactly he same as E1 = E1 * E2. That does not mean that x*=a/b; is the same as x=x*a/b;. Since E2 is a/b, x*=a/b; is actually equivalent to x=x*(a/b); which does produce the same results.

C++ and Octave results differ for simple arithmetic

I have a C++ code and an Octave that both compute the same equation
In C++
#include <math.h>
int main()
{
float x = 1.5f;
float y = pow(x, 6) * 235809835.41f - pow(x, 5) * 2110439254.2f + pow(x, 4) *7869448124.8f - pow(x, 3) * 15648965509.0f + pow(x, 2) * 17503313074.0f - (x)* 10440563329.0f + 2594694745.0f; // result y = 3584
return 0;
}
In Octave
x = 1.5
y = (x ^ 6) * 235809835.41 - (x ^ 5) * 2110439254.2 + (x ^ 4) *7869448124.8 - (x ^ 3) * 15648965509 + (x ^ 2) * 17503313074 - (x)* 10440563329 + 2594694745‏ // result y = 26
The computed value of y differs in the two cases. C++ computes y to be 3584 and Octave computes y to be 26. What could be the cause for this divergence?
EDIT : Excel produces the same result as Octave, and the result is logical too within the context of the equation. So, something is wrong with the C++ code or compiler.
This appears to be due to the limited precision of the float type, which is likely causing one of the operations to be effectively discarded because one operand is of a smaller enough magnitude than the other to cause a significant change to the result. (See this extremely contrived example that shows what this might look like.)
If you rewrite the code to use the double type, which is more precise, then the result is 26.810783, which matches the result I get from evaluating the formula in Maxima.
Further reading: What Every Computer Scientist Should Know About Floating-Point Arithmetic

What is the correct way to use C++ style casts to perform an expression at a desired precision?

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) + ... ?
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 ints (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;
/ 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.
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;
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 ints to be automatically converted to floats.
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;
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.