I've recently begun my journey into C++ and have very little knowledge of it other than the basics. I'm trying to translate a Matlab code of mine to C++ as a way to help me understand the differences between the two. The Matlab code takes a given input X(height), and calculates the density (rho), and speed of sound (acousticSpeed) for the input.
Here is the Matlab code.
function [rho, acousticSpeed] = atmos(X)
%only valid to X = 11Km
%Constants
gamma=1.4;
R=287.05;
g=9.81;
To=288.15;
Po=101325;
zo=50;
L=-0.0065;
%Temperature Calculation
T=To+(L*(X-zo));
%Pressure Calculation
P=Po*(T/To)^(-g/(L*R));
%Density Calculation
rho=P/(R*T);
%Acoustic Speed
acousticSpeed=sqrt(gamma*R*T)
end
From what I've learned about C++, functions cannot return more than one value(or at least, its a very intensive process to make it so). This Matlab function returns two values, rho and acousticSpeed. For now, I have split this into 2 functions on C++ to calculate each individual output with the relevant equations.
For Rho I have
rho(double x){
double zo;
double To;
double Po;
double L;
double g;
double R;
double p;
zo = 50;
To = 288.15;
Po = 101325;
L = -0.0065;
g = -9.81;
R = 287.05;
double T = To + L*(x-zo);
double P = pow((Po*(T/To)), -(g*(L*R)));
p = P/(R*T);
return p;
}
For Speed of Sound I have
soundspeed(double x){
double zo;
double To;
double L;
double R;
double as;
double gamma;
zo = 0;
To = 288.15;
L = -0.0065;
R = 287.05;
gamma = 1.4;
double T = To + L*(x-zo);
as = pow(gamma*R*T,0.5);
return as;
}
and my Main function is
int main()
{
cout << "Please enter a desired altitude in meters." << endl;
double x;
double A;
double B;
cin>> x;
A = soundspeed(x);
B = rho(x);
cout << "For Altitude: " << x << " meters" << endl;
cout << "Speed of Sound: " << A << " meters per second." << " Air Density:
" << B;
return 0;
}
For an input of 500 meters, the Speed of Sound is 338 meters per second, and density is approximately 1.225.
The speed of sound function returns the correct value, but the density function returns 0.
I have included iostream and math.h(for the pow() function).
What have I done wrong? Is there a cleaner way to translate this Matlab Function to C++? Are there any other tips for me as a beginner that you experienced folks can give? Thanks.
Apologies for the length, I was unsure how else to include all the information.
The issue was with parenthesis and placement of values, particularly in the pressure calculation.
The original was
double P = pow((Po*(T/To)), -(g*(L*R)));
However the correct equation is
double P = Po*pow((T/To), -(g/(L*R)));
A simple solution that I should have tried before posting, as I did not want to waste anyone's time.
Thank you all for your help!
Related
Hey this is really one of the first things I've ever coded. I was wondering how might I fix this error. I am currently trying to do some research but can't find anything that is helpful in fixing it.
#include <iostream> // needed for Cin and Cout
#include <cmath>
#include <csmath>
using namespace std;
/************************************
* defines
*************************************/
#define PI 3.14159
/*************************************
* function prototype
*************************************/
int main()
{
//surface and volume
float radius;
float height;
float surfacearea;
float volume;
int pi = 3.14159
//Get the radius
cout << "enter the radius: ";
cin >> (float)radius;
//Get height
cout << "enter height: ";
cin >> height;
//Get the surfacearea
surfacearea = 2(pi*radius^2)+2(pi*radius)* height;
cout << "The surfacearea is: " << surfacearea;
//get volume
volume = (pi*radius)^2*height;
cout << "The volume is: " << volume << endl;
system ("pause");
return 0;
}
Change int to double for pi, because pi is a floating point number, which, as stated in the comments, is C++'s default for floating point numbers. Unless there is a particular reason to use float, use double for floating-point numbers.
double pi = 3.14159;
And the warning will go away.
Also, you don't have to cast your input to float, simply:
cin >> radius;
Additionally, at the very least, change radius^2 to radius*radius.
But better yet, avoid ^ altogether and use std::pow, an example of which can be found here.
Additionally, you don't need to #define PI 3.14159 because you never use it, and you try to define pi in main().
You better declare and initialize local variables right before you need them. For constants like pi you better use const and proper type. For a proper type C++11 offers you a great tool - auto. And ^ does not mean power in C++ you have to use std::pow() instead. So your code should look like this:
const auto pi = 3.14159;
//Get the radius
auto radius = 0.0;
cout << "enter the radius: ";
cin >> radius;
//Get height
auto height = 0.0;
cout << "enter height: ";
cin >> height;
//Get the surfacearea
auto surfacearea = 2 * pi * pow( radius, 2.0 ) + 2 * pi * radius * height;
cout << "The surfacearea is: " << surfacearea << endl;
//get volume
auto volume = pow( pi*radius, 2.0 ) * height;
cout << "The volume is: " << volume << endl;
To begin with, a warning is not an error; if it were a compilation error, then the code would not even compile. However, since it was a warning, that means your code did compile successfully and run, except that it produced a warning about something in your code. Now to the bugs in your code:
Firstly, your declaration for the local variable pi is incorrect. pi is declared in your code as a variable of data type int, short for integer. An integer is only a whole number, positive and negative one, but one that is neve more specific than 10^0. Now the problem is that you are trying to store a decimal value in an int variable. While the compiler is able to make a conversion of the decimal value into an int value, you lose the precision of the value; that's because it rounds the value. If you compile this sample code:
int floating = 1.23456789;
cout << floating << endl;
It will output 1 instead of 1.23456789, with the reason being that an int variable cannot store a float or double value; it however can convert this float or double value into an int value by rounding it.
Therfore, you should change your declaration for pi to:
double pi = 3.14159; // By the way, you forgot to add a semicolon here
Another problem: you are using unnecessary typecating in your cin statement for the radius:
cin >> (float)radius;
You would need to use casting if you want to change the data type of a variable for a particular operation (you don't change the variable data type; you merely process its value as the data type cast. In your case, it is unrequired, because the radius variable is already declared as a data type of float, in the line:
float radius;
Therefore, I would recommend you to simply change this cin statement to:
cin >> radius;
One more thing: the following lines in your code have a problem:
surfacearea = 2(pi*radius^2)+2(pi*radius)* height;
volume = (pi*radius)^2*height;
The "^" symbol does not raise a number to a power; it is called a bitwise XOR operator in c++ and it server the purpose of copying the bit if it is set in one operand but not both. You can find more information about it here: Bitwise Exclusive OR Operator: ^
In c++, if you want to raise a number x to a power like 2, then you have to do x * x. Alternatively, you can use the pow() function like: pow(x, 2.0). For your code, if we use the x*x method, it would be like:
surfacearea = 2(pi*radius*radius)+2(pi*radius)* height;
volume = (pi*radius)*(pi*radius)*height;
Alternatively, if we use the pow() function, then the code would look like:
surfacearea = 2(pi*pow(radius, 2))+2(pi*radius)* height;
volume = pow((pi*radius), 2)*height;
Fixing these peoblems should get your code to work.
//findSlope(twoPoints).exe
//finding the slope of line AB, using coordiantes of point A and B.
#include <iostream>
int main()
{
int a, b, c, d;
float answer;
std::cout << "The X coordiante of A: ";
std::cin >> a;
std::cout << "\nThe Y coordiante of A: ";
std::cin >> b;
std::cout << "\nThe X coordiante of B: ";
std::cin >> c;
std::cout << "\nThe Y coordiante of B: ";
std::cin >> d;
std::cout << "\nThe slope of line AB = " << std::endl;
answer = (b-d)/(a-c);
std::cout.setf(std::ios::fixed);
std::cout.precision(3);
std::cout << answer << std::endl;
//alternative= std::cout << fixed << setprecision(#) << answer << std::endl;
std::cout.unsetf(std::ios::fixed);
return 0;
}
I am learning C++ and I tried to code a program that calculate the slope using the coordinates of two points.
I understand that if I use float for variables I declared for the coordinates, the result of the calculation would output as float with decimals. However, I wonder if I may still use int for user input so that I can ensure the inputs are integers.
Extra question: Would it be possible to convert a float presented in the form of "#.##" to "# #/#"? More like how we do mathematics IRL.
You can use implicit conversion to double:
answer = (b-d)/(a-c*1.0);
Or explicit cast:
answer = (b-d)/(a-(float)c);
Bonuses:
for the fraction part: Converting decimal to fraction c++
Why does integer division result in an integer?
You can use int for user input, but to precisely calculate anything that contains a division operator /, you'll need to cast to floating point types.
It's usually considered a good practice in C++ to use static_cast for that (although you still may use c-style (float) syntax).
For example:
answer = static_cast<float>(b - d) / (a - c);
Here, you convert (b - d) to float and then divide it by integer, which results in a float.
Note that the following wouldn't work correctly:
answer = static_cast<float>((b - d) / (a - c));
The reason is that you first divide an int by another int and then convert the resulting int to a float.
P. S. float is really inaccurate, so I would advise to use double instead of float in all cases except where you want to write faster code that does not depend on mathematical accuracy (even though I'm not sure it would be faster on modern processors) or maintain compatibility with an existing library that uses float for some of its functions.
I'm working on below program and I want the program to do the same thing, but with not one main() function, but instead one main() function PLUS one user defined function called computeConeVolume that contains the calculation. In other words I want to remove the one line calculation and replace it with a function call, then write and add the function below main with the calculation, surrounded any other syntax that I need to complete it.
The function should contain local variables and a constant declared and must have the calculation, it may not do anything else such as input or output.
Should be able to declare "global" variables anywhere but no variables above or outside of main() and the function are allowed.
A value-returning function should be used because it's a little simpler to understand, but you can employ a void function.
Need to have a function prototype at the top of the code, then main, then your function.
Need some help with this since I'm new to C++ and trying to learn.
//Cone Volume Calculator Program
#include <iostream>
using namespace std;
int main( )
{
//Declare variables and constants
double coneRadius = 0.0;
double coneHeight = 0.0;
const double PI = 3.1415;
double coneVolume = 0.0;
//Prompt the user for inputs
cout << "Enter the radius of the cone: ";
cin >> coneRadius;
cout << "Enter the height of the cone: ";
cin >> coneHeight;
//Do the calculation
coneVolume = 0.3333 * PI * coneRadius * coneRadius * coneHeight;
//Display the result
cout << "The volume of your cone is: " << coneVolume << endl;
system("pause");
return 0;
} //end of main
I'm trying to recycle some of Amadeus' answer and use some of your code.
First of all, you should define the function you wish to calculate the cone volume with. Something like:
double coneVolume(double, double);
You should pay attention to always leave the main function at the end of your .c document.
What you also need is a declaration of your function. This is where you actually write down what the function does:
double coneVolume(double coneRadius = 0.0, double coneHeight = 0.0) {
double coneVolume = coneVolume = 0.3333 * PI * coneRadius * coneRadius * coneHeight;
return coneVolume;
}
The value setting in the method head is just a thing for default values, this isn't really needed here, just to show you.
Where is the const double PI = 3.1415; going? Somewhere above your functions, then it's visible everywhere in your document. You could also think about using math.h by include, then you can use M_PI, which is about the same thing as your PI constant. (To be more precise it is a definition which replaces any time you write M_PI by the actual Pi value)
If you really want the function to just calculate without input, you can just define them locally, just like in your main.
Note: Global scope is always out of the main method.
How about this program
#include <cmath>
#include <iostream>
using namespace std;
double coneVolume(double, double);
int main( )
{
//Declare variables and constants
double coneRadius = 0.0;
double coneHeight = 0.0;
//Prompt the user for inputs
cout << "Enter the radius of the cone: ";
cin >> coneRadius;
cout << "Enter the height of the cone: ";
cin >> coneHeight;
//Do the calculation
//Display the result
cout << "The volume of your cone is: " << coneVolume(coneRadius, coneHeight) << endl;
system("pause");
return 0;
} //end of main
double coneVolume(double coneRadius, double coneHeight)
{
double PI = acos(-1.0);
double volume = coneRadius * coneRadius * coneHeight * PI / 3.0;
return volume;
}
Please note that I added the cmath library in order to use the acos function.
double PI = acos(-1.0);
I read this trick in a piece of code that a guy used to do trigonometry using C++.
I did not use any kind of parenthesis when I calculated the volume because both * and / are in the same order of precedence and are evaluated from left to right. I divided by 3.0 because I am using doubles. For the prototype of the function that is right above the main function
double coneVolume(double, double);
I just wrote the type of arguments of the function as only the type of the arguments of the function is needed for propotypes.
I am writing a program in C++ for the distance formula. The answer to x1=0 y1=0 x2=1 y2=1 should be around 1.14, however the answer printed out is 2.00. Every single variable is stored as double I don't know what is going wrong here. Here is my code, and thank you for any help!!
// main.cpp
// Chap6_42
//
// Created on 10/21/14.
//
#include <iostream>
#include <cmath>
#include <iomanip>
using namespace std;
double distance(double,double,double,double); //distance prototype
int main()
{
double d = 0;
double x1 = 0; //coordinate x1
double x2 = 0; //coord x2
double y1 = 0; //coord y1
double y2 = 0; //coord y2
cout << "Enter four cords (x1,y1,x2,y2) to find the distance between them " << endl;
cout << "x1 = ";
cin >> x1;
cout << "y1 = ";
cin >> y1;
cout << "x2 = ";
cin >> x2;
cout << "y2 = ";
cin >> y2;
d = distance (x2,x1, y2,y1); //calls to distance function, performs computations
cout << "The distance is " << fixed << setprecision(2) << showpoint << d << endl;
return 0;
}
double distance(double x2,double x1,double y2,double y1) //distance function header
{
return sqrt(pow(x2-x1,2.0)) + sqrt(pow(y2-y1,2.0)); //distance function computations
}
//function definition
Your calculation is wrong. You're calling sqrt twice when you should only call it once on the entire sum.
return sqrt(pow(x2-x1,2.0) + pow(y2-y1,2.0));
Your formula is wrong.
You wrote:
sqrt(pow(x2-x1,2.0)) + sqrt(pow(y2-y1,2.0));
It should be:
sqrt(pow(x2-x1,2.0) + pow(y2-y1,2.0));
Anyway, do not use pow there but multiply by hand, that's (probably) faster and more accurate.
sqrt( (x2-x1)*(x2-x1) + (y2-y1)*(y2-y1) );
Also, often you can use squared distances instead of the distance for a small performance-boost.
Why do you think the answer is around 1.14? Given your example, it should return 2.0
sqrt((pow(2.0 - 1.0, 2.0))) + sqrt((pow(2.0 - 1.0, 2.0)))
sqrt((pow(1.0, 2.0))) + sqrt((pow(1.0, 2.0)))
sqrt(1.0) + sqrt(1.0)
1.0 + 1.0
2.0
Tada!
If you are calculating distance, which the function name implies, you need to adjust your formula.
return sqrt(pow(abs(x2 - x1), 2.0) + pow(abs(y2 - y1), 2.0));
You and pythagorus disagree about how to calculate the distance
Given you intend to use "pow" for some esoteric reason, your code should be
return sqrt(abs(pow(x2-x1,2.0)) + abs(pow(y2-y1,2.0)));
or
return sqrt(pow(x2-x1,int(2)) + pow(y2-y1,int(2)));
If you are going to programming you'll probably need a lot of math. you need to know "on paper" the algorithms you are going to use (even simple ones like the one by Pitagora). Also a rounding error with doubles is not going to change a result so much (unless you are using some bad conditioned algorithm, wich is not the case for Pitagora.
I'm compiling this program using Code::Blocks 10.05 however normally I will get about 10 iterations done before it starts producing Nan in every single output. I was wondering if this is a problem caused by using the cos and sin functions and if there was a decent work around to avoid this?
I have to produce a lot of iterates because I am working on a project for University so it has to be accurate too. I looked up a few articles about how to avoid using sin and cos though I need to follow a few formulas rigorously otherwise the results I produce may be inaccurate so I'm not sure whether to compromise.
struct Particle // Need to define what qualities our particle has
{
double dPosition;
double dAngle;
};
Particle Subject;
void M1(double &x, double &y) //Defines movement if particle doesn't touch inner boundary
{
x = x + 2*y;
}
double d = 0.25; //This can and will be changed when I need to find a distance between
// the two cricles at a later stage
void M2(double &x,double &y, double d) //Defines movement of a particle if it impacts the inner boundary
{
double z = asin(-(sin(y)+d*cos(x + y))/0.35);
double y1 = y;
y = asin(-0.35*sin(z) + d*cos(x + y + 2*z));
x = y + y1 + x + 2*z;
}
int main()
{
cout << "Please tell me where you want this particle to start positions-wise? (Between 0 and 2PI" << endl;
cin >> Subject.dPosition;
cout << "Please tell me the angle that you would like it to make with the normal? (Between 0 and PI/2)" << endl;
cin >> Subject.dAngle;
cout << "How far would you like the distances of the two middle circles to be?" << endl;
double d;
cin >> d;
// These two functions are to understand where the experiment begins from.
// I may add a function to change where the circle starts however I will use radius = 0.35 throughout
cout << "So position is: " << Subject.dPosition << endl;
cout << "And angle with the normal is: " << Subject.dAngle <<endl;
int n=0;
while (n <= 100) //This is used to iterate the process and create an array of Particle data points
{ // in order to use this data to build up Poincare diagrams.
{
while (Subject.dPosition > 2*M_PI)
Subject.dPosition = Subject.dPosition - 2*M_PI;
}
{
if (0.35 >= abs(0.35*cos(Subject.dPosition + Subject.dAngle)+sin(Subject.dAngle))) //This is the condition of hitting the inner boundary
M2(Subject.dPosition, Subject.dAngle, d); //Inner boundary collision
else
M1(Subject.dPosition, Subject.dAngle); // Outer boundary collision
};
cout << "So position is: " << Subject.dPosition << endl;
cout << "And angle with the normal is: " << Subject.dAngle <<endl;
n++;
}
return 0;
}
Nan is shown in c++ as an indication of infinite, zero devision, and some other variations of non representable numbers.
Edit:
As pointed by Matteo Itallia, inf is used for infinite/zero division. I found these approaches:
template<typename T>
inline bool isnan(T value) {
return value != value;
}
// requires #include <limits>
template<typename T>
inline bool isinf(T value) {
return std::numeric_limits<T>::has_infinity &&
value == std::numeric_limits<T>::infinity();
}
Reference: http://bytes.com/topic/c/answers/588254-how-check-double-inf-nan
If the value is outside of [-1,+1] and passed to asin(), the result will be nan
If you need to check for Nan, try the following
if( value != value ){
printf("value is nan\n");
}