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)
Related
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.
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.
I have a value in temperature and I want to get a resistance value from this temperature.
I use Steinhart-Hart method but this equation always returns 7,39 regardless of temperatures and coefficients.
My second implementation based on steinhart method (see below) doesn't work with negative coefficients.
Do you know what's the problem with my code ?
double WSensor::temperatureToResistance(double _temp)
{
double Temp = _temp + 273.15;
double X = ((this->therm->getA() - (1 / Temp)) / this->therm->getC());
double Y = this->therm->getB() / this->therm->getC();
double argExpo = pow(-(X / 2) + pow((X*X) / 4 + (Y*Y*Y) / 27, 1.0 / 2.), 1.0 / 3.0) - pow((-(X / 2) - pow((X*X) / 4 + (Y*Y*Y) / 27, 1.0 / 2.0)) * (-1), 1.0 / 3.0);
return exp(argExpo);
}
After 3 days of work, I know why this equation does not work on arduino : overflowing.
Some parts of the equation create float too large for this board model (Arduino Uno).
One of the solutions is to rephrase the equation to prevent bigger results. But this solution takes too much time and need good mathematical skills, that's why I decided to move the equation in an external API.
Basically I have two variables:
double halfWidth = Width / 2;
double halfHeight = Height / 2;
As they are being divided by 2, they will either be a whole number or a decimal. How can I check whether they are a whole number or a .5?
You can use modf, this should be sufficient:
double intpart;
if( modf( halfWidth, &intpart) == 0 )
{
// your code here
}
First, you need to make sure that you're using double-precision floating-point math:
double halfWidth = Width / 2.0;
double halfHeight = Height / 2.0;
Because one of the operands is a double (namely, 2.0), this will force the compiler to convert Width and Height to doubles before doing the math (assuming they're not already doubles). Once converted, the division will be done in double-precision floating-point. So it will have a decimal, where appropriate.
The next step is to simply check it with modf.
double temp;
if(modf(halfWidth, &temp) != 0)
{
//Has fractional part.
}
else
{
//No fractional part.
}
You may discard a fractional part and compare the result with the original value using floor():
if (floor(halfWidth) == halfWidth) {
// halfWidth is a whole number
} else {
// halfWidth has a non-zero fractional part
}
As rightly pointed out by #Dávid Laczkó, it's a better solution than modf() because there's no need for an additional variable.
And according to my benchmarks (Linux, gcc 8.3.0, optimizations -O0...-O3), the floor() call consumes less CPU time than modf() on the modern notebook and server processors. The difference even growing with compiler optimizations enabled. Probably it's because the modf() has two arguments when the floor() has only one argument.
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.