How can I separate this into 2 functions - c++

I was wondering if anyone could help me with a more elegant way to code this program that I am writing please. The code I have is bellow, I would like to know if there is a way to separate the part that prints out the totals into a new function. I have tried but I always just get the total is 0, so I must be passing things wrong or something.
void printNumbers(int x, double y, double z, double v, int sum, double sum2,int sum3,int sum4){
while(x != 0){
y = sqrt (x);
z = pow (x,2);
v = pow (x,3);
sum = sum + x;
sum2 = sum2 + y;
sum3 = sum3 + z;
sum4 = sum4 + v;
cout << " " << x << setw(12) << setprecision (4) << y << setw(8) << z << setw(8) << v << endl;
x--;
}
cout << " total is" << sum << setw(12) << sum2 << setw(8)<< sum3 << setw(8) << sum4 << endl;
}
This is what I tried, at the time I only had one total to get, but It still did not work just gave the answer 0:
void printFooters(int sum){
cout << " " << "====================================="<< endl;
cout << "Totals " << sum << endl << endl;
cout << " " << "====================================="<< endl;
}
This is how I was calling it in main():
printFooters(sum);

You need to make the sums into references if you want them to be updated.
void printNumbers(int x, double y, double z, double v, int& sum, double& sum2,int& sum3,int& sum4)
If you don't the sums are passed by value, so you just get a copy of the current value of the sums.
Alternatively you can use pointers to the sums, but that would involve changing the syntax when accessing the sum variables.

You should decide first, what variables are input and what variables should carry output. Try to not use one variable for both input and output, it is often more confusing than valuable.
Only input value is x. Everything else is output values. In way you have used that values, content of values is modified only in local copy inside function printNumbers(). They will get lost on end of function. I expect you want to output computed results from function (however then printNumbers is wrong name for that function).
C and C++ always pass variables to function parameters by value. That means, variable is initialized from parameter, but any changes are done only inside function. At the end of function, copy is discarded and will NOT change anything you passed to it.
If you want output from function, you can use return, or use pointers or references to a variable. I suggest to use references in C++, they are easier to understand and easier to use.
Use references instead of copied variables in function. Then, when you modify that value inside function, it will keep modified value after function return.
void f1(int in, int out)
{
out = in + 1;
}
void f2(int in, int &out)
{
out = in + 1;
}
int o1=-1, o2=-1;
f1(1, o1);
f2(1, o2);
cout << o1 << "," << o2 << endl; // will print -1,2
So declare your function as:
void printNumbers(int x, double &y, double &z, double &v, int &sum, double &sum2,int &sum3,int &sum4);
you can then do:
double y,z;
int sum, sum2, sum3, sum4;
printNumbers(4, y, z, sum, sum2, sum3, sum4);
printFooters(sum);
And this time, it should print whatever printNumbers computed. See http://www.cprogramming.com/tutorial/references.html for a bit more, or use google.

You could batch all those parameters into structs, and separate all the calculations and outputs.
This is probably overkill in your case, and is quite a bit of code, but anyway...
struct Powers
{
double sqroot;
int one;
double square;
double cube;
};
Powers calculatePowers(int x)
{
Powers powers;
powers.sqroot = sqrt(x);
powers.one = x;
powers.square = x * x;
powers.cube = x * x * x;
return powers;
}
struct Sums
{
int sum1;
double sum2;
int sum3;
int sum4;
};
Sums addPowers(Sums sums, Powers powers)
{
sums.sum1 += powers.one;
sums.sum2 += powers.sqroot;
sums.sum3 += powers.square;
sums.sum4 += powers.cube;
return sums;
}
void printPowers(Powers powers)
{
cout << " " << powers.one
<< setw(12) << setprecision (4) << powers.sqroot
<< setw(8) << powers.square
<< setw(8) << powers.cube
<< endl;
}
void printTotals(Sums sums)
{
cout << " total is"
<< sums.sum1
<< setw(12) << sums.sum2
<< setw(8) << sums.sum3
<< setw(8) << sums.sum4
<< endl;
}
void doEverything(int x)
{
Sums sums = {0, 0, 0, 0};
while (x > 0)
{
Powers powers = calculatePowers(x);
printPowers(powers);
sums = addPowers(sums, powers);
x--;
}
printTotals(sums);
}

Related

C++17 if init for the while loop?

For some home work I'm doing the following:
int main() {
ofstream file("log.txt");
file << setw(5) << "i"
<< setw(15) << "h"
<< setw(15) << "n"
<< setw(15) << "sum"
<< setw(15) << "diff"
<< endl;
auto write2file = [&file](int i, double h, double n, double sum, double diff) {
file << setw(5) << i
<< setw(15) << h
<< setw(15) << n
<< setw(15) << sum
<< setw(15) << diff
<< endl;
};
double a = 0;
double b = 2;
int n = 1;
double h = (b-a)/n;
double sum = sum_analytic;
double diff = 1;
while (diff > pow(10, -4)) {
h = (b-a)/++n;
sum = ntgrt(a, b, n, h);
diff = abs(sum - sum_analytic);
static int i = 0;
write2file(++i, h, n, sum, diff);
}
}
Considering the C++17 if init feature (http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0305r1.html) I'm kind of seing the same pattern here when I declare h, sum and diff outside the while loop but they are used only inside.
Is there a better way to write it, may be taking advantage of C++17 features?
Then what you want is a for loop:
for(double diff = 1; diff > pow(10, -4);)
{
double h = (b-a)/++n;
double sum = ntgrt(a, b, n, h);
diff = abs(sum - sum_analytic);
....
}
There was no point in adding this capability to while since you can just use for and leave off the increment statement.
I'd start with some C++98 features to reduce repetition.
template <class I, class F>
void write2file(std::ostream &os, I i, F h, I n, F sum, F diff) {
using std::setw;
os << setw(5) << i
<< setw(15) << h
<< setw(15) << n
<< setw(15) << sum
<< setw(15) << diff
<< "\n";
}
// ...
write2file(file, "i", "h", "n", "sum", "diff");
// ...
write2file(file, ++i, h, n, sum, diff);
It would appear that when they're used, i and n always have the same value. I'd just use one of the two rather than both.
Your pow(10, -4) would probably be better off as 1e-4.
I think some good use of C++98 can probably clean up the loop as well. I'd move it into a function template, something on this general order:
template <typename F>
void show_convergence(double a, double b, F f, double sum_a, std::ostream &os) {
double diff = 1.0;
for (int n=1; diff > 1e-4; n++) {
double h = (b-a)/n;
double sum = f(a, b, n, h);
diff = abs(sum-sum_a);
write2file(os, n, h, sum, diff);
}
}
Technically, this wouldn't have to be a template--but it's fairly harmless, and avoids the ugliness of a pointer to a function (which can also lead to a fair degree of inefficiency). Then you'd call this something like this:
show_convergence(0, 2, ntgrt, sum_analytic, file);

Don't print variable if it's zero

double a, b, c, d, x, y;
char operation
cout << setw(6) << a << b
<< setw(3) << operation
<< setw(6) << c << d
<< " = "
<< setw(6) << x << y
<< endl;
I'm making a calculator which takes two complex numbers and adds subtracts etc. My question is how do I format my output so that 0's are not displayed.
I.E. if the input is (a+bi)(c+di) the output is a+bi * c+di = x+yi But a, b, c, d, x, y are only displayed if they are nonzero.
I know I can do it with if statements and stuff but I was hoping there's a shorter, more efficient, path.
I don't think you can avoid doing the condition and printing if non-zero somewhere.
About all you can do is wrap it up so most code doesn't need to deal with it:
class complex {
double x;
double i;
public:
// ...
friend std::ostream &operator<<(std::ostream &os, complex const &c) {
// if both parts are 0, we probably want to print *something*
if (c.x == 0.0 && c.i == 0.0)
return os << 0;
if (c.x != 0.0)
os << c.x;
if (c.i != 0.0)
os << c.i << "i";
return os;
}
};
complex a, b, c;
// ...
cout << a << operation << b << " = " c << "\n";
You'll have to add a little more if you want this to honor (for example) width/precision correctly (though for real use, you undoubtedly want to use the complex class that's already in the standard library instead).
Yes, you can do it by including <complex>
std::complex<double> com_one; // value 0 + 0i
std::complex<double> com_two(3.14); // value 3.14 + 0i
std::complex<double> com_three(1.5, 3.14) // value 1.5 + 3.14i
std::complex<double> com_four(com_two); // value is also 3.14 + 0i
Then to use arithmetic operations, you can just use
std::cout << com_one + com_two << std::endl;
std::cout << com_one - 3.14 << std::endl;
std::cout << 2.75 * com_two << std::endl;
com_one += com_three / 2.0;
Source: http://stdcxx.apache.org/doc/stdlibug/20-2.html
For checking if it's a zero check it using if, and compare it with a zero. This is the most clean technique.

Trying to call functions using a vector of pointers to functions, but it fails to return the correct value--is it my compiler?

EDIT:
So it seems like everyone is getting the correct output, so my question is now this: Why am I getting the wrong output? Why is the second argument, y, getting changed to zero, regardless if I use a variable or a literal? And no, I didn't get confused and put the wrong variable, I double checked. I am using Visual Studio 2013.
I'm doing an exercise from the fifth edition of the C++ primer by Lippman, Lajoie, and Moo on page 250, and my code for the third exercise, 6.56, is returning incorrect values.
I made a vector of pointers to function of type int (int, int), made four functions of that type (addition, subtraction, multiplication, and division), and added pointers to them to my vector. I attempted to move through those pointers with an iterator, dereferencing them to call them, but for add2 and subtract, it returned the value of the first argument, 0 for mult, and the else clause for divide, even though y was not equal to 0.
The code is as follows:
int test(int x, int y);
int add2(int x, int y);
int subtract(int x, int y);
int mult(int x, int y);
int divide(int x, int y);
typedef decltype(test) *FuncP; //type declaration of a ptr to a function that takes two ints and returns int
int main(){
//6.7
vector<FuncP> ptrsToFuncs;
ptrsToFuncs.push_back(*add2);
ptrsToFuncs.push_back(*subtract);
ptrsToFuncs.push_back(*mult);
ptrsToFuncs.push_back(*divide);
vector<FuncP>::iterator fIter;
int test1 = 6, test2 = 8;
int test3 = 0;
cout << "Running four arithmetic functions with " << test1 << " and " << test2 << "\n\n";
for (fIter = ptrsToFuncs.begin(); fIter != ptrsToFuncs.end(); ++fIter)
{
int result = (*fIter)(test1, test2);
cout << result << endl;
}
system("PAUSE");
}
int test(int x, int y)
{
if (y != 0)
{
cout << "Modulo of one and two is: " << x % y << "\n\n";
return x % y;
}
else
{
cout << "Cannot divide by zero.\n\n";
return -1;
}
}
int add2(int x, int y)
{
cout << "Adding " << x << " and " << y << ": ";
return (x + y);
}
int subtract(int x, int y)
{
cout << "Subtracting " << x << " and " << y << ": ";
return (x - y);
}
int mult(int x, int y)
{
cout << "Multiplying " << x << " and " << y << ": ";
return (x * y);
}
int divide(int x, int y)
{
if (y != 0)
{
cout << "Dividing " << x << " and " << y << ": ";
return (x / y);
}
else
{
cout << "Cannot divide by zero.\n";
return -1;
}
}
For example, with test1 = 6 and test2 = 8, the return values would be: 6, 6, 0, "Cannot divide by zero." -1.
I also tried this: (**fIter)(test1, test2). I thought that maybe I didn't dereference enough and needed to dereference the pointer to the function as well as the iterator, but it resulted in the same output.
Thank you.
Your code works fine for me, I think possibly you mixed up your variables inside your iteration (replaced test2 to with test3)
for (fIter = ptrsToFuncs.begin(); fIter != ptrsToFuncs.end(); ++fIter)
{
int result = (*fIter)(test1, test3);
cout << result << endl;
}
would give you
6, 6, 0, "Cannot divide by zero." -1.
If you need to see what your code is doing, try replacing your variables with literals and also adding some couts to your function calls.
for (fIter = ptrsToFuncs.begin(); fIter != ptrsToFuncs.end(); ++fIter)
{
int result = (*fIter)(12, 24);
cout << result << endl;
}
int add2(int x, int y)
{
cout<<"add function called with first variable"<<x<<" and second variable"<<y<<endl;
return (x + y);
}

Converting Object int data members to floating point and dividing appends strange data cout to console

I'm sure I'm doing something wrong, but I just can't figure it out. I've created an object with integer data members, and I want to have a member function return the quotient of it's members as a floating point value, which it does. It then appends some additional stuff. The output is below the program, which should run as is.
#include <iostream>
#include <string>
#include <cstdlib>
using namespace std;
class Rational
{
public:
explicit Rational(int = 0, int = 1);
double getRationalAsDouble() const;
private:
int numerator;
int denominator;
};
Rational::Rational(int numerator, int denominator)
{
if (denominator == 0)
this->denominator = 1;
else
this->denominator = denominator;
this->numerator = numerator;
}
// ******* Problem Function *********
double Rational::getRationalAsDouble() const
{
double a = 0.0, b = 0.0;
a = static_cast<double>(numerator);
b = static_cast<double>(denominator);
cout << endl << "a = " << a;
cout << endl << "b = " << b;
cout << endl << "a/b = " << (a/b);
}
// ******** End Problem Function ********
int main()
{
{ //Create a new Scope so that I can view Destructor Message, not used here
Rational c(2, 6);
int data = 10;
cout << c.getRationalAsDouble(); // prints rational object c as double, but not really
cout << "\n\n";
} // End of Scope
return 0;
} // end main
And here's the output:
a = 2
b = 6
a/b = 0.3333332.31196e-317
I've been playing around, and if I change the function to have any regular division in it, it works fine. What's really interesting is if I add any output after the cout << endl << "a/b = " << (a/b); line, that output is handled before (a/b) part of the line. Any help would be greatly appreciated! Thank you in advance for your time.
Solution:
The function wasn't returning anything. When the code was changed to:
double Rational::getRationalAsDouble()
{
return static_cast<double>(numerator)/denominator;
}
It worked as expected. Thank you tc.
Three problems:
You want to print endl at the end of the line, not the "beginning". Your code ends up doing (effectively) cout << endl << "a/b = " << (a/b); ... cout << c.getRationalAsDouble(); cout << "\n\n"; which prints the two doubles 0.333333 and 2.31196e-317 next to each other with no space.
You want (perhaps) cout << "\n" << endl instead of cout << "\n\n". endl causes the stream to be flushed; plain "\n" might not.
Rational::getRationalAsDouble() is not returning a value. Listen to your compiler warnings.
The fix looks something like
double Rational::getRationalAsDouble() const
{
double a = 0.0, b = 0.0;
a = static_cast<double>(numerator);
b = static_cast<double>(denominator);
cout << "a = " << a << endl;
cout << "b = " << b << endl;
cout << "a/b = " << (a/b) << endl;
return a/b;
}
Your implementation of Rational::getRationalAsDouble() can be simplified to:
double Rational::getRationalAsDouble() const
{
return 1.0*numerator/denominator;
}
I think you had everything else there for debugging purposes, and hence are not really needed.

Variable changes value when passed to function?

I feel like an idiot. When I pass a variable to the function it results in a strange output like 6.2+e003 instead of the value that the variable holds. What am I doing wrong?
The x in main and the x in the function are different?
main:
int x, y;
while(system.WindowOpen())
{
x++;
y++;
bg.Draw2D();
bob.Think(x, y);
riley.Think(x, y);
system.Render(0);
}
class method:
void Organism::Think(double x, double y)
{
std::cout << "X: " << x << "\n";
std::vector<double> food;
food.push_back(x);
food.push_back(y);
std::cout << "VECTOR: " << food[0] << " " << food[1] << "\n";
std::vector<double> path;
if(refresh.IsTime()) {
std::cout << "\nFOOD VECTOR: \n" << food[0]
<< "\n" << food[1] << "\n";
path = brian.GetOutput(food);
organism.Translate2D(path[0], path[1]);
if(organism.IsOffScreen2D(resX, resY) == 'l' )
organism.SetPos2D(resX, organism.GetY());
if(organism.IsOffScreen2D(resX, resY) == 'r')
organism.SetPos2D(0, organism.GetY());
if(organism.IsOffScreen2D(resX, resY) == 't')
organism.SetPos2D(organism.GetX(), resY);
if(organism.IsOffScreen2D(resX, resY) == 'b')
organism.SetPos2D(organism.GetX(), 0);
};
font.DrawNumber2D(x, 50, 50);
font.DrawNumber2D(y, 50, 100);
organism.Draw2D();
}
Both x and y are uninitialized here:
int x, y;
so they can hold any value, and reading from them is undefined behaviour. You should initialize them:
int x = 0
int y = 0;
I was writing outside the bounds of a vector. I switched from using the [] operators to using the .at() and found my bug right away. Just a bit of memory corruption. I feel quite silly. Thanks all!