What is the operations order of these two functions [duplicate] - c++

This question already has answers here:
Why does dividing two int not yield the right value when assigned to double?
(10 answers)
Closed 2 years ago.
I was writing a function to calculate the volume of a sphere when I encounter a problem and I don't know why if I change 4/3 * PI to PI * 4/3 I got different result.
What is the order of evaluation, if I use parenthesis like (4/3) * PI and PI * (4/3) I got the wrong answer in both cases.
#define PI 3.141592
float Volume(int radius){
return (4/3 * PI * pow(radius, 3));
}
float Volume(int radius){
return (PI * 4/3 * pow(radius, 3)); //the good one
}

According to the C++ Standard (5.6 Multiplicative operators)
1 The multiplicative operators *, /, and % group left-to-right.
Thus this expression
4/3 * PI
is evaluated like
( 4/3 ) * PI
So in this sub-expression 4 / 3 there is used the integer arithmetic and result is equal to 1.
This expression
PI * 4/3
also is evaluated from left to right like
( PI * 4 )/3
but in this case there is used the float arithmetic. The operand 4 is converted to the type of the variable PI that has the type double due to the usual arithmetic conversions. Then in turn the operand 3 is also converted to the type double because its left operand (expression) ( PI * 4 )has the type double.
In this expression
PI * (4/3)
again inside the parentheses there is used the integer arithmetic and the result of the sub-expression is 1.

To get the correct result, force the answer to be floating point like such:
return 4.0/3 * PI * pow(radius, 3);
Also, the * and / operators have the same precedence, so the expression will evaluate from left to right. So putting parentheses around 4/3 was right, except it does integer division.

Related

Im trying to calculate the formula of a sphere using cpp

Im making a calculator that can code the volume of a sphere, but i cant make the formula without getting the wrong answer. volume of sphere is 4/3 pi r cubed. And cant figure out how to make a fraction without making a complex function. Any idea on how to write out the formula correctly?
}else if (volumeChoice == "sphere"){
double sphereRadius { 0 };
const double pi { 3.14159265358979323846 };
cout << "Enter the radius\n";
cin >> sphereRadius;
double sphereFormula { (4/3) pi * pow(3.0, sphereRadius)};
cout << sphereFormula;
There are a couple main issues I noticed.
One: 4/3 uses integer division in C++, so the result returns 1, not 1.3333...
Change it to 4.0/3.0
Two: There is no multiplication sign between the 4/3 and pi, so it shouldn't compile.
Three: The pow function first parameter is the base, and the second is the exponent. The call should be pow(sphereRadius, 3.0) not pow(3.0, sphereRadius)
The line after changes should look like the following:
double sphereFormula { (4.0/3.0) * pi * pow(sphereRadius, 3.0)};
4 / 3 is integer division (result is 1), and your result will not be accurate because of that. Change it to 4.0 / 3.0 and you should see better results.
I'd be surprised if this code compiles because you're missing a multiplication sign between your four thirds and pi.
Finally, your arguments to pow() are switched. The first argument is the base, the second is the exponent. It never hurts to refer to the documentation.
double sphereFormula{(4.0 / 3.0) * pi * pow(sphereRadius, 3.0)};
A touch more explanation:
C++ reads natural number literals (4 and 3 in your case) as integers. Placing a .0 causes the compiler to read the literal as a double. C++ is not like python or other languages that will produce a decimal result from integer division.

Multi line math results different than single line

I was having an issue with some floating point math and I've found that if I do my math on one line, I get -0 passed to tan(), and if I do it across two lines, I get 0 passed to tan(). Have a look:
float theta = PI / 2.f;
float p = (PI / 2.f) - theta;
float result = tan(p);
The above, p = -0, result = -4.37...
float theta = PI / 2.f;
float p = PI / 2.f;
p -= theta;
float result = tan(p);
The above, p = 0, result = 0.
Can anyone explain the difference? I assume the -0 is causing that result from tan(), although I can't find anything on google that explains why. Why does the exact same calculation spread across different lines result in a different answer?
Thanks
It is probably because of the type of PI.
If you use double it will change to float and then the outcome
will be as you just represent.
But if PI is float both of this test scenarios are equal.
What #Naor says is probably correct. but I'd like to add something.
You probably not getting -4.37xx but -4.37xxxe-xx which is a pretty small negative number.
Since you can always get errors in floating point math. I'd say there is no need to change your code. Both snips are correct.
So this is what, in my opinion, is happening:
In both examples PI is a define, probably defined like this:
#define 3.14 //and some more digits
In C++, number like this is treated as double.
After preprocessing, this expression:
PI / 2.0f
will be treated as double-typed prvalue. This means that this line hides one more operation:
float theta = PI / 2.f;
which is a double-to-float conversion, which definitely looses some precision in this case.
In first example this also happens here:
float p = (PI / 2.f) - theta;
but only after evaluating whole expression. Note that during this evaluation (PI / 2.f) will be still double, but theta will be a float-to-double converted value, which explains the slight difference in result from 0.0.
In your last example you first convert (PI / 2.f) to float:
float p = PI / 2.f;
to subtract float-typed theta from it in next line. Which must result to 0.0, which probably compiler optimized out anyway ; ).

c++ find the scalar product of two doubles?

I am trying to follow an algebraic equation, and convert it to c++.
I am now stuck on:
s.dx + x
and:
(s.dy + y) /a
s, dx, dy, x, y, and a are all doubles.
Google tells me that the . in the mathematical notation means the scalar product (http://www.rapidtables.com/math/symbols/Algebra_Symbols.htm), but how can I get that from doubles? What is this algorithm in c++?
Many thanks.
Google is wrong, you are looking for the * operator:
s * dx + x
(x * dy + y) / a
You should write s*dx+x and (s*dy+y)/a.
Perhaps you (or somebody) misunderstood the . thing, perhaps because a number constant in code (immediate number like 1 or 1.0) will have a different type depending whenever you use a .. So 10000 * 10000 is an integer multiplication, while 10000.0 * 10000.0 is an floating-point (double) multiplication. But here the . isn't an operator, but is part of the floating-point syntax.
As an operator in C++, a . is used to get a member of a object (variable or method).

Why am I getting zero for all values in this expression?

Following is a fragment of a program for deducing whether or out 2 lines intersect.
P and P2 are CPoint objects marking the start and end point of one of the 2 lines.
double m1,m2; //slopes
double b1,b2; //y-intercepts
double y,x; //intersection point
m1=(max(P.y,P2.y) - min(P.y,P2.y)) /( max(P.x,P2.x) - min(P.x,P2.x) );
For some reason I'm always getting m1 to be 0. Why's that?
If your CPoint class is a point with integer coordinates, you have to do some conversion here to get the result you want. See the following demonstration of the problem. Consider two points P = (1, 4) and P2 = (5, 3):
m1=( max(P.y,P2.y) - min(P.y,P2.y) ) / ( max(P.x,P2.x) - min(P.x,P2.x) );
^^^^^^^^^^^^^ ^^^^^^^^^^^^^ ^^^^^^^^^^^^^ ^^^^^^^^^^^^^
4 3 5 1
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1 4
However, in integer division, 1 / 4 is 0, but you want the result to be 0.25. The fact that the result variable has a type of double doesn't change the value (and type) of the expression.
To solve this problem, you have to cast the parts of your expression just before it becomes relevant that they are to be considered as non-integral numbers. In your case this are the operands of the division, so that it will be a floating point division. (Casting the result of the division will also not help.)
m1 = static_cast<double>( max(P.y,P2.y) - min(P.y,P2.y) )
/ static_cast<double>( max(P.x,P2.x) - min(P.x,P2.x) );
Note that casting the second operand is optional, as double / int always uses floating point division.
Also note that your expression calculates the absolute value of the slope. You might want to calculate the signed slope.
Something you can improve in your code (this won't solve the problem above): Instead of subtracting the min of the max of the difference, just take the absolute value of the difference:
m1 = static_cast<double>( abs(P.y - P2.y) )
/ static_cast<double>( abs(P.x - P2.x) );
Since in C++, abs is a template function (in C it's a macro, urgh...), you can also force a result type using explicit template types:
m1 = abs<double>(P.y - P2.y)
/ abs<double>(P.x - P2.x);
Also, as the calculation of a slope between two given points seems to be a commonly used function, you can implement this as a free-standing function on two CPoints:
double absoluteSlope(const CPoint & p, const CPoint & q) {
return abs<double>(p.y - q.y) / abs<double>(p.x - q.x);
}
Even better, to make use of C++ templates, implement it on a generic class which has the members x and y:
template<class T>
double absoluteSlope(const T & p, const T & q) {
return abs<double>(p.y - q.y) / abs<double>(p.x - q.x);
}
This solution now works for your CPoint instance with integer coordinates as well as a (maybe upcoming) CPointF class with float / double coordinates.
As already warned above, this calculates the absolute slope. To change this to a mathematically correct (signed) slope, just replace abs with static_cast:
template<class T>
double slope(const T & p, const T & q) {
return static_cast<double>(p.y - q.y) / static_cast<double>(p.x - q.x);
}
The division A/B should A/(double)B. Use this in your code.
Fabs instead of abs too.

Calculating volume for sphere in C++

This is probably an easy one, but is the right way to calculate volume for a sphere in C++? My getArea() seems to be right, but when I call getVolume() it doesn't output the right amount. With a sphere of radius = 1, it gives me the answer of pi, which is incorrect:
double Sphere::getArea() const
{
return 4 * Shape::pi * pow(getZ(), 2);
}
double Sphere::getVolume() const
{
return (4 / 3) * Shape::pi * pow(getZ(), 3);
}
You're using integer division in (4 / 3). Instead, use floating point division: (4.0 / 3.0).
4/3 is 1, because integer division only produces integers. You can confirm this by test code: std::cout << (4/3) << std::endl;.
In (4 / 3), these are both integers so you get integer division. That means the result will be truncated (1.333... becomes 1). Make one of them a double so the other gets promoted to a double during division, yielding a correct result.
I prefer to use (4.0 / 3.0).
(4 / 3) is an integer expression and is therefore being truncated to 1. Try (4.0 / 3.0)