LawOfCosines solving for c, but getting odd answer - c++

I have been trying to code a program that can solve for c using the Law Of Cosines. The program runs correctly, but the answer I get is ridiculously big, noted by how it was in scientific notation.
Here is my code:
#include <iostream>
#include <cmath>
using namespace std;
class TrigMath
{
private:
double a;
double b;
double y;
public:
double LawOfCos()
{
return sqrt(pow(a,2) + pow(b,2) - 2*a*b*cos(y));
}
void seta(double A)
{
A = a;
}
void setb(double B)
{
B = b;
}
void sety(double Y)
{
Y = y;
}
};
int main()
{
TrigMath triangle1;
triangle1.seta(3);
triangle1.setb(4);
triangle1.sety(60);
cout << "c is equal to " << triangle1.LawOfCos() << endl;
return 0;
}

The cos() function there takes input as radians not as degrees.
Try to convert degrees to radians and then supply it as input.
In the class functions seta, setb and sety you have written A = a, B = b and Y = y.
You have to change them to a = A, b = B and Y = y.
So after applying all the changs the code should be like
#include <iostream>
#include <cmath>
using namespace std;
class TrigMath
{
private:
double a = 0;
double b = 0;
double y = 0;
public:
double LawOfCos()
{
return sqrt(pow(a,2) + pow(b,2) - 2*a*b*cos(y));
}
void seta(double A)
{
a = A;
}
void setb(double B)
{
b = B;
}
void sety(double Y)
{
y = Y*3.14/180;
}
};
int main()
{
TrigMath triangle1;
triangle1.seta(3.0);
triangle1.setb(4.0);
triangle1.sety(60.0);
cout << "c is equal to " << triangle1.LawOfCos() << endl;
return 0;
}

Related

Return pointer to array virtual template function

I would like to return an array to a pointer, in a virtual function that is a member of a derived class of a template class. In details, my classes definition is:
Sampler.h
#ifndef SAMPLER_H
#define SAMPLER_H
template <class T>
class Sampler
{
public:
virtual T getnumber()=0;
virtual T* simulation(int n)=0;
};
class UniformSampler:public Sampler<double>
{
public:
virtual double getnumber();
virtual double* simulation(int n);
UniformSampler(double a=0.0, double b=1.0);
private:
double low_bound;
double up_bound;
};
#endif
The class Sampler is a template class in order to be able to derive an other sampler with vectors later. The implementation is:
Sampler.cpp
#include "Sampler.h"
#include<iostream>
#include<cstdlib>
#include<cmath>
using namespace std;
//Uniform
UniformSampler::UniformSampler(double a, double b)
{
low_bound=a;
up_bound=b;
}
double UniformSampler::getnumber()
{
int myrand=rand();
while((myrand==0)||(myrand==RAND_MAX)){myrand = rand(); } //We want a number in (0, RAND_MAX).
double myuni = myrand/static_cast<double>(RAND_MAX); //Create a number in (0,1).
return low_bound + myuni*(up_bound-low_bound);
}
double* UniformSampler::simulation(int n){
double simulations[n];
for(int i=0; i<n; i++){
simulations[i] = this->getnumber();
}
return simulations;
}
My problem is that, when I try to call this program in the main(), it looks like the assignment of the pointer doesn't work. Here is my main.cpp:
#include <iostream>
#include <math.h>
#include <cstdlib>
#include <time.h>
using namespace std;
#include "Sampler.h"
int main(){
srand(time(0));
int n=10;
double *unif = new double[n];
UniformSampler uni;
unif = uni.simulation(n);
for ( int i = 0; i < n; i++ ) {
cout << "*(p + " << i << ") : ";
cout << *(unif + i) << endl;
}
delete[] unif;
return 0;
}
When I run it, it doesn't print any of the elements that unif points to. I don't understand what is wrong there.
UniformSampler::simulation is twice wrong:
double simulations[n]; uses VLA extension, so not C++ standard compliant.
you return pointer on local variable, so dangling pointer.
Solution: use std::vector instead.
#include <vector>
template <class T>
class Sampler
{
public:
virtual ~Sampler() = default;
virtual T getnumber() = 0;
virtual std::vector<T> simulation(int n) = 0;
};
class UniformSampler:public Sampler<double>
{
public:
explicit UniformSampler(double a=0.0, double b=1.0);
double getnumber() overrid;
std::vector<double> simulation(int n) override
{
std::vector<double> res(n);
for (auto& val : res){
res = getnumber();
}
return res;
}
private:
double low_bound;
double up_bound;
};
int main(){
srand(time(0));
constexpr int n = 10;
UniformSampler uni;
auto unif = uni.simulation(n);
for (int i = 0; i < n; i++ ) {
std::cout << "p[" << i << "]: " << unif[i] << endl;
}
}

Set method in a simple c++ class file returning strange values

I am having trouble using a set function in a class file. So far I have the following. I am trying to write a quadratic class that has three private data members and can calculate both the value of a quadratic and the number of real roots in the quadratic. I'm not stuck on the math part as much as I am getting the set methods to not give me weird values. When I test using main, the values for a, b, and c are numbers that I didn't input when I created the object.
Quadratic.hpp
#ifndef QUADRATIC_HPP
#define QUADRATIC_HPP
class Quadratic
{
private:
double a;
double b;
double c;
public:
Quadratic();
Quadratic(double, double, double);
void setA(double);
void setB(double);
void setC(double);
double getA();
double getB();
double getC();
double valueFor(double);
int numRealRoots();
};
#endif
Quadratic.cpp
#include <cmath>
#include <iostream>
Quadratic::Quadratic()
{
setA(1.0);
setB(1.0);
setC(1.0);
}
Quadratic::Quadratic(double A, double B, double C)
{
a = A;
b = B;
c = C;
}
void Quadratic::setA(double A)
{
a = A;
}
void Quadratic::setB(double B)
{
a = B;
}
void Quadratic::setC(double C)
{
c = C;
}
double Quadratic::getA()
{
return a;
}
double Quadratic::getB()
{
return b;
}
double Quadratic::getC()
{
return c;
}
double Quadratic::valueFor(double x)
{
return (a*(pow(x,2)) + b*x + c);
}
int Quadratic:: numRealRoots()
{
double discriminant = pow(b,2) - (4*a*c);
double epsilon = 0.00001;
int realRoots;
if (discriminant <= epsilon && discriminant > 0)
realRoots = 1;
else if (discriminant > epsilon)
realRoots = 2;
else
realRoots = 0;
return realRoots;
}
Your setB method is wrong - it updates a instead of b:
void Quadratic::setB(double B)
{
b = B; // Was "a = B;" in the original code
}

reassign value not work in operator = overloading

The MWE is
#include <iostream>
using namespace std;
class N {
public:
float x;
N() { x = 0.0; }
N(float a) { x = a; }
//N(N &n) { x = n.x; }
N &operator=(float f) { cout << "########";return *new N(f); }
};
int main() {
N a;
a = 3.0;
cout << a.x;
return 0;
}
What I expect is: it prints 3, but it actually prints 0. It seems the value didn't change.
Then I change it into
x = f; return *this;
It worked, why?
Of course it doesn't change. You don't change it in your assignment operator. Instead you return a pointer to a new value allocated on the heap...and ignore that result.

Order: An Analysis on Point Sorting

So I've made for myself a point printing class, that is supposed to have the user enter in 2-tuples; that is, x and y, that then prints them back to the user in ^order,^ where order means p1=(x,y)
#include <iostream>
#include <vector>
#include <string>
#include <cmath>
#include <algorithm>
using namespace std;
class Point2D {
public:
Point2D();
Point2D(double a, double b);
double getx();
double gety();
void setx(double a);
void sety(double b);
virtual void print();
virtual void print(int a);
double angle();
private:
double x;
double y;
};
bool operator<( Point2D a , Point2D b );
int main() {
double my_x=-999;
double my_y=-999;
string my_color;
double my_weight;
vector<Point2D*> points;
cout << "Welcome to Point Printer! Please insert the x-and y-coordinates for your points and I will print them in sorted order! Just one rule, the point (0,0) is reserved as the terminating point, so when you are done enter (0,0).\n";
while(true)
{
cout << "x = ";
cin>>my_x;
cout << "y = ";
cin>>my_y;
if((my_x == 0)&&(my_y==0))
{
break;
}
points.push_back(new Point2D(my_x, my_y));
}
sort(points.begin(), points.end());
cout << "\n\n";
cout << "Your points are\n\n";
for(int i=0;i<points.size();i++)
{
cout<<i+1<<": ";
(*points[i]).print(); cout<<endl; // this is the printing gadget
}
for(int i=0; i<points.size(); i++)
{
delete points[i];
}
cout << endl << endl;
return 0;
}
double Point2D::angle()
{
double Angle = atan2(y,x);
if(Angle < 0)
{
return Angle + 3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679;
}
return Angle;
}
bool operator< (Point2D a, Point2D b)
{
if (a.getx()*a.getx()+a.gety()*a.gety() < b.getx()*b.getx()+b.gety()*b.gety())
{
return true;
}
else if (a.getx()*a.getx()+a.gety()*a.gety() > b.getx()*b.getx()+b.gety()*b.gety())
{
return false;
}
if (a.getx()*a.getx()+a.gety()*a.gety() ==b.getx()*b.getx()+b.gety()*b.gety())
{
if (a.angle() < b.angle())
{
return true;
}
else if (a.angle() > b.angle())
{
return false;
}
}
return true;
}
Point2D::Point2D() { x = 0; y = 0; return;}
Point2D::Point2D(double a, double b) { x = a; y = b; return;}
double Point2D::getx() { return x;}
double Point2D::gety() { return y;}
void Point2D::setx(double a) { x = a; return; }
void Point2D::sety(double b) { y = b; return; }
void Point2D::print() {
cout<<"("<<x<<","<<y<<")";
return;
}
void Point2D::print(int a) {
print(); cout<<endl;
}
What I'm having trouble with is either one of the following:
sort
angle()
operator<(Point2D a, Point2D b)
Something different entirely...
In particular, the following points:
x = 1
y = 2
x = 2
y = 3
x = 1.1
y = 2.2
x = -10
y = 10
x = -5
y = -3
x = -5
y = 3
x = 5
y = -3
x = 5
y = 3
x = 0
y = 0
are not sorted in the correct order.
Any help would be much appreciated. Thank you.
The problem (or one of them) is the final statement in your comparison function.
return true;
Look at this block:
if (a.getx()*a.getx()+a.gety()*a.gety() ==b.getx()*b.getx()+b.gety()*b.gety())
{
if (a.angle() < b.angle())
{
return true;
}
else if (a.angle() > b.angle())
{
return false;
}
}
First of all, if we've gotten to this point, we've determined that the (x*x + y*y) calculations for both a and b are equal. Now let's assume that the angle is also equal. What happens? The first test fails because a.angle() is not less than b.angle(). Then the second test fails because a.angle() is not greater than b.angle(). Then you return true. In other words, you're saying that it is true that a is less than b, even though by all rights, they should be considered equal, and so you should return false. Instead of multiple tests on the angle, you can just return a.angle() < b.angle();, and that should do the trick. With some additional simplifications, your function should look something like this:
bool operator<(Point2d a, Point2d b)
{
double A = a.getx()*a.getx()+a.gety()*a.gety();
double B = b.getx()*b.getx()+b.gety()*b.gety();
if (A < B) return true;
if (A > B) return false;
return a.angle() < b.angle();
}
The problem is probably that you are storing and sorting pointers, not objects. The points will be compared not with your operator but their addresses. Try change points to vector<Point2d>
First of all just use (if your are just planning to sort 2D points) :
(Edit : See Benjamin Lindley comments below.)
bool operator < ( Point2D a, Point2D b)
{
return a.getx() < b.getx() ||
(a.getx()==b.getx() && a.gety()< b.gety() );
}
Another thing if use use std::cout in operator < ( Point2D a, Point2D b), you will notice it won't be called anytime.
The reason is this:
vector<Point2D*> points; // Vector of Point2D*
but bool operator< (Point2D a, Point2D b) is used for comparision.
Suggested Fixes:
vector<Point2D> points;
points.push_back(Point2D(my_x, my_y));
And accordingly, wherever applicable.
Also you can't define anything like
bool operator<(const Point2D* a, const Point2D* b)
Because of this:
C++03 standard, ยง13.5 [over.oper] p6:
An operator function shall either be a non-static member function or
be a non-member function and have at least one parameter whose type is
a class, a reference to a class, an enumeration, or a reference to an
enumeration.

What's wrong with my temperature conversions?

In this program Iam trying to take 78 degrees Fahrenheit and return them in a class with the Celsius version and kelvin. But for some odd reason I'm just getting this as the output. What am I doing wrong?
This is my output.
78
0
273.15
#include <iostream>
using namespace std;
class Temperature
{
public:
double getTempKelvin();
double getTempFahrenheit();
double getTempCelcius();
void setTempKelvin(double k);
void setTempFahrenheit(double f);
void setTempCelcius(double c);
private:
double kelvin, fahrenheit, celcius;
double c, f, k;
};
int main ()
{
double c, f, k;
Temperature Conv;
Conv.setTempFahrenheit(f);
Conv.setTempCelcius(c);
Conv.setTempKelvin(k);
cout << Conv.getTempFahrenheit() << endl;
cout << Conv.getTempCelcius() << endl;
cout << Conv.getTempKelvin() << endl;
return 0;
}
void Temperature::setTempFahrenheit(double f)
{
f = 78;
fahrenheit = f;
}
void Temperature::setTempCelcius(double c)
{
c = (5/9) * ( f - 32);
celcius = c;
}
void Temperature::setTempKelvin(double k)
{
k = c + 273.15;
kelvin = k;
}
double Temperature::getTempFahrenheit()
{
return fahrenheit;
}
double Temperature::getTempCelcius()
{
return celcius;
}
double Temperature::getTempKelvin()
{
return kelvin;
}
5/9 is integer division and will result in 0. You need to use doubles, Try:
void Temperature::setTempCelcius(double c)
{
c = (5.0/9.0) * ( f - 32);
celcius = c;
}
Aside from the 5/9 issue, you have three sets of variables called 'c', 'f', and 'k'. One set are the member variables in the class. Another set are the variables in main. The third set are the parameters inside the various get* functions.
It's not clear what purpose the variables in main serve, why the functions take parameters at all, or why your class has two sets of variables for the temperatures (both c and celsius, and so on) but if you give the sets of variables different names, it will become easier to understand why your program isn't working.
Seems that my problem was that i was clearning the k c and f double so i just removed them from the functions.
#include <iostream>
using namespace std;
double c, f, k;
class Temperature
{
public:
double getTempKelvin();
double getTempFahrenheit();
double getTempCelcius();
void setTempKelvin();
void setTempFahrenheit();
void setTempCelcius();
private:
double kelvin, fahrenheit, celcius;
double c, f, k;
};
int main ()
{
Temperature Conv;
Conv.setTempFahrenheit();
Conv.setTempCelcius();
Conv.setTempKelvin();
cout << Conv.getTempFahrenheit() << endl;
cout << Conv.getTempCelcius() << endl;
cout << Conv.getTempKelvin() << endl;
return 0;
}
void Temperature::setTempFahrenheit(){
f = 78;
fahrenheit = f;
}
void Temperature::setTempCelcius()
{
c = (5.0/9.0) * ( f - 32);
celcius = c;
}
void Temperature::setTempKelvin()
{
k = c + 273.15;
kelvin = k;
}
double Temperature::getTempFahrenheit()
{
return fahrenheit;
}
double Temperature::getTempCelcius()
{
return celcius;
}
double Temperature::getTempKelvin()
{
return kelvin;
}
#include<iostream>
using namespace std;
class temperature
{
public :
virtual void calculate(float)=0;
};
class ftoc : public temperature
{
public :
float c;
void calculate(float f)
{
c=(f-32)*5/9;
cout<<"Temperature in celcius is : "<<c<<" `C "<<endl;
}
};
class ftok : public temperature
{
public :
float k;
void calculate(float f)
{
k=(f+459.67)*5/9;
cout<<"Themperature in kelvin is : "<<k<<" K "<<endl;
}
};
int main()
{
float f;
ftoc a;
ftok b;
cout<<"Enter the temperature : ";
cin>>f;
a.calculate(f);
b.calculate(f);
return 0;
}