Mantain the original value in a recursive function c++ - c++

I am trying to solve a square root in a recursive way. I do not want the code to solve that! I am almost done, but I do not know how to mantain the original value of the function:
float raizCuadrada(float num, float err) {
float nuevo = num / 2;
float resta=(nuevo*nuevo)-num;
if(resta>err){
return (raizCuadrada(nuevo, err));
}
else if (resta <= err) {
return (nuevo);
}
}
I basicly want to know how to "save" that first "num" call, somewhere, to use it ALWAYS in the "resta", the "- num" should be always the number that 1st put.
NOTES: I cannot input more inputs. I can only input 1 number and the error.

You can define a global variable at the top of your code.
float num_fixed;
float raizCuadrada(float num, float err) {
float nuevo = num / 2;
float resta=(nuevo*nuevo)-num_fixed;
if(resta>err){
return (raizCuadrada(nuevo, err));
}
else {
return (nuevo);
}
}
int main(void){
float num = 2.0;
float err = 0.000001;
float output;
num_fixed = num;
output = raizCuadrada(num, err);
}

I would recommend the two solutions that have been proposed. Either overload a function that takes three arguments or use a global.
If you for some reason don't want to do that, you can use some trickery:
float raizCuadrada(float num, float err) {
static float org = -1;
if(org<0)
org = num;
float nuevo = num / 2;
float resta=(nuevo*nuevo)-org;
float ret;
if(resta>err)
ret = raizCuadrada(nuevo, err);
else
ret = nuevo;
if(org>=0)
org=-1;
return ret;
}
I would not recommend this method unless you really have a special need for it. It is quite easy to do mistakes, and I cannot think of any real benefit. But since it is possible, I wanted to show it.

I basicly want to know how to "save" that first "num" call, somewhere,
to use it ALWAYS in the "resta", the "- num" should be always the
number that 1st put.
NOTES: I cannot input more inputs. I can only input 1 number and the
error. c++
The solution I most often use is to separate the two 'efforts' into two methods:
1) Start with a method (use your original method name) to save the first variable to a safe space. I will leave the 'where' up to you. Here I have simply made up a new variable name (origNum), in a scope available to the code of each method. In C++, I would expect that the class containing these methods would 'save' and use an instance data attribute.
float raizCuadrada(float num, float err) // same name as original
{
origNum = num; // "save" original 'num'
return (raizCuadrada2(num, err)); // continue normally
}
2) Then a mild re-factor of your previous code uses the "saved" value. Since you can not change the parameters, I suggest a slight method name change, here I created raizCuadrada with suffix '2'.
float raizCuadrada2(float num, float err) {
float nuevo = num / 2;
float resta=(nuevo*nuevo)-origNum; // use origNum here
if(resta>err){
return (raizCuadrada(nuevo, err));
}
else if (resta <= err) {
return (nuevo);
}
}
note - not compiled. not tested.

Related

C ++ simple function returning huge value - always the same value no matter the inputs - 4309838

I am learning to code and this is a very simple function but it keeps returning the same answer every time, 4309838, and I don't know why. It is meant to calculate a paycheck, adding 50 whenever there is overtime. Any help is appreciated.
float payCheck(int ratePar, float hoursPar)
{
if (hoursPar>40)
payCheck = ratePar*hoursPar + 50;
else
payCheck = ratePar*hoursPar;
return payCheck;
}
int main()
{
int rate;
float hours, pay;
cout<<"Enter hours worked and pay rate "<<endl;
cin>>hours>>rate;
pay = payCheck(rate, hours);
cout<<"Your paycheck is "<<pay<<endl;
}
You have not declared payCheck variable in payCheck method. This works:
float payCheck(int ratePar, float hoursPar)
{
float payCheck;
if (hoursPar>40)
payCheck = ratePar*hoursPar + 50;
else
payCheck = ratePar*hoursPar;
return payCheck;
}
You need to declare the variable which you are returning in the function.
float payCheck(int ratePar, float hoursPar)
{
float payCheck; //Observe this
if (hoursPar>40)
payCheck = ratePar*hoursPar + 50;
else
payCheck = ratePar*hoursPar;
return payCheck;
}
While the missing declaration of the payCheck local variable is the primary cause for the problem in the question I disagree with the answers that just introduce such a local variable like this (variable name changed to disambiguate from the function name):
float payCheckAmount;
// or alternatively:
// float payCheckAmount = 0.0f // looks better at first, but is not
// ... do something in an if-else
return payCheckAmount;
The problem is that payCheckAmount is in a nonsensical state (from the point of view of the function’s purpose) until an actual assignment of a calculated value happens somewhere in the if construct. This is an error waiting to happen. At some point someone will change the if construct in a way that doesn’t cover all possible conditions anymore and the nonsensical initial value of payCheckAmount value will be returned, leading to a hard to track down error somewhere else in the program.
Whenever possible write your program in a way that makes it impossible to end up in an illegal state. When doing that try to anticipate likely future changes to the code as well.
For the payCheck() function you could get rid of the local variable entirely:
float payCheck(int ratePar, float hoursPar)
{
if (hoursPar > 40) {
return ratePar*hoursPar + 50;
}
return ratePar*hoursPar;
}
However, this has the disadvantage that the rate*hours calculation is duplicated in the code. If it ever changes you’ll have to remember to change both locations. For that reason I’d go for this implementation:
float payCheck(int ratePar, float hoursPar)
{
float payCheckAmount = ratePar*hoursPar;
if (hoursPar > 40) {
payCheckAmount += 50;
}
return payCheckAmount;
}
As long as the basic logic of your calculation remains “base pay per hour plus overtime bonus” you can’t end up returning a nonsensical value.

Return error code as double

I wonder if I can return error code as double in the following way in C:
double getValue()
{
double ret = 0;
if (error1)
{
return -1;
}
if (error2)
{
return -2;
}
return ret = ....;
}
int main(void)
{
double val = getValue();
if (-1 == val)
{
printf("getValue: error1\n")
return -1;
}
else if (-2 == val)
{
printf("getValue: error2\n");
return -2;
}
......
return 0;
}
so when the return value is >= 0 then it is correct value which can be used for calculations. When value is less than zero error occurred.
Will I get the floating-point-comparison problem when I compare return value with -1 or -2 ?
Flag values are a bad idea. Flag values that are floating point are doubly so, even if double precision.
If you are using IEEE double precision floating point values, the values -1 and -2 are exactly representable as doubles, and comparison is well defined. No "magic error" will slip in if you merely copy the double around or only read the value. In fact, on a system with conventional 2s complement 32 bit ints, every int can be represented exactly as a IEEE double precision floating point value.
Now, transformations you think wouldn't matter like x /3. * 3. will ruin the identity, so the code is very fragile: fragile both because flag values are fragile, and because floating point equivalence is often fragile in practice.
In C++, there are a myriad of ways to do this that are less fragile.
enum error_code {a,b,c};
boost::variant<double, error_code> getValue();
is a tagged union that can hold either a double or an error_code. There is a std::expected proposal you can look at which is a tagged union with a "bias" towards the first value being the only valid one (sort of a cross between std::experimental::optional and boost::variant).
Both of these result in the value being returned in a type-safe way, where an error is a different type of value than the non-error return type.
Alternative solutions include returning the error code separately (as the return value, or taking a pointer-to-error-code as a parameter (what I call ICU style)). The double could be set to some innocuous value in that case (say, NaN) rather than left uninitialized.
double getValue( error_code* e );
or
error_code getValue( double* out );
where enum error_code { a = -1, b = -2 } is an enumeration of the error codes.
#LightnessRacesinOrbit beat me to it, but having typed it I post it anyway.
You can do it by taking the value to be set as a pointer argument, and returning a status. That way, no values of *ret are barred.
int getValue(double *ret)
{
*ret = ...;
if (error1)
return -1;
if (error2)
return -2;
return 0;
}
Then the calling code can be such as
double myval;
int err;
if ((err = getValue(&myval)) == 0)
printf ("getValue() returned %f\n", myval);
else
printf ("getValue() returned error %d\n", err);
Yes, you could get floating-point errors.
So consider using exceptions instead, or perhaps return an int error code and populate a double "out parameter" on success:
int getValue(double& ret)
{
if (error1)
return -1;
if (error2)
return -2;
ret = ....;
return 0;
}
Doing that is not necessary and makes error handling difficult, you should create an enum where you can add or remove error codes as needed, and also you don't really need to remeber what -1 is or what does -2 mean, just give each error a descriptive name, and do this
enum ErrorCodes {NoError, Error1, Error2, ... , ErrorN};
enum ErrorCodes getValue(double *value)
{
if (error1)
return Error1;
if (error2)
return Error2;
.
.
.
if (errorN)
return ErrorN;
*value = resultOfCalculation;
return NoError;
}
then
enum ErrorCode code;
double value;
code = getValue(&value);
switch (code)
{
case NoError:
/* use value here */
break;
case Error1:
/* handle error 1 */
break;
/* and so on */
}
I think this is a lot better and elegant, because you can apply it anytime you want to have robust error checking, no matter what type the target value is, this would work exactly the same for a struct or a double or an int array.

c++ oop beginner - return the output sum of each created objects in the vector within one function call

I have a simple class
#ifndef _VOICE
#define _VOICE
#include "maximilian.h"
class voice{
public:
voice(int waveType);
void setNote(double pitch,double amplitude);
void triggerNote();
void releaseNote();
double getOutput();
bool getState();
private:
maxiOsc op;
convert mtof;
double amp;
double freq;
double out;
int type;
bool state;
};
#endif // _VOICE
#include "voice.h"
voice::voice(int waveType){
type=waveType;
state=false;
out=0;
}
void voice::setNote(double pitch,double amplitude){
freq=pitch;
amp=amplitude;
}
void voice::triggerNote(){
if(type==1)
out=op.sinewave(mtof.mtof(freq))*amp;
if(type==2)
out=op.triangle(mtof.mtof(freq))*amp;
if(type==3)
out=op.saw(mtof.mtof(freq))*amp;
if(type==4)
out=op.square(mtof.mtof(freq))*amp;
state=true;
}
void voice::releaseNote(){
out=0;
state=false;
}
bool voice::getState(){
return state;
}
double voice::getOutput(){
return out;
}
I then store these voices in a vector
I wish to find a more effective way to acces the output sum of all objects within the vector
it looks something like this:
double PreMaster;
PreMaster=voices[0].getOutput()+voices[1].getOutput()+voices[2].getOutput()+voices[3].getOutput()....(n-object)...;
(in my program it goes to 34)
(for) does not work since I need to output the value simultaneously in each objects...
there should be a way inside the class to have a global function that will return the output sum of each created objects within one function call...
I am a beginner at oop so please pardon me if solution seems obvious.
And thanks in advance if you can point me in a useful direction.
EDIT:
I have a callback that gets called at sampling rate (44100hz).
I have a vector of voice object (they output simple synth waveforms)
to form a sounding chord I need to sum the output of each voice "simultaneously".
I then feed the sum to my soundcard every sample at sampling rate frequency.
void testApp::audioOut (float * output, int bufferSize, int nChannels){
for (int i = 0; i < bufferSize; i++){
for(int j=0;j<voices.size();j++){
if(keys[j]==true){
voices[j].triggerNote();
}
else if(keys[j]==false)
voices[j].releaseNote();
}
PreMaster=voices[0].getOutput()+voices[1].getOutput()+voices[2].getOutput()+voices[3].getOutput()
+voices[4].getOutput()+voices[5].getOutput()+voices[6].getOutput()+voices[7].getOutput()
+voices[8].getOutput()+voices[9].getOutput()+voices[10].getOutput()+voices[11].getOutput()
+voices[12].getOutput()+voices[13].getOutput()+voices[14].getOutput()+voices[15].getOutput()
+voices[16].getOutput()+voices[17].getOutput()+voices[18].getOutput()+voices[19].getOutput()
+voices[20].getOutput()+voices[21].getOutput()+voices[22].getOutput()+voices[23].getOutput()
+voices[24].getOutput()+voices[25].getOutput()+voices[26].getOutput()+voices[27].getOutput()
+voices[28].getOutput()+voices[29].getOutput()+voices[30].getOutput()+voices[31].getOutput()
+voices[32].getOutput()+voices[33].getOutput();
MasterOut.stereo(PreMaster, outputs, 0.5);
lAudioOut[i] = output[i*nChannels ] = outputs[0]; /* You may end up with lots of outputs. add them here */
rAudioOut[i] = output[i*nChannels + 1] = outputs[1];
}
}
hope this clarify a bit...
Yeah I forgot about += so I tested it and it stop my program form outputing sounds.when I do it with my ugly method it works though...
You can perform a simple loop, since there is no reason to believe that a for does not work, given your code example:
double sum = 0;
for (const auto& v : voices) {
sum += v.getOutput();
}
Another option is to use std::accumulate and a suitable functor:
// function to sum voice's getOutput() to get running total
double addOutput(double sum, const voice& v) { return sum + voice.getOutput(); }
....
double sum = std::accumulate(voices.begin(), voices.end(), 0.0, addOutput);
An example:
int sum = 0;
for(std::vector<voice>::iterator i = voices.begin(); i != voices.end(); i++)
sum += i->getOutput();

c++ method sometimes returns unexpected high values

I've traced a bug down to a function which should be returning float values between 20 and 100 or so, but is sometimes (1 time in 10) returning values much much higher than that. The problem exists when I have an expression in the last line of the method, like this:
return snap(baseNumber, targets) + (octave * NOTES_PER_OCTAVE);
If I store the return value in a variable first, then return that variable, the problem goes away:
float ret = snap(baseNumber, targets) + (octave * NOTES_PER_OCTAVE);
return ret;
Here's the complete method:
static inline float octaveSnap(float number, std::vector<float>* targets){
static const int NOTES_PER_OCTAVE = 12;
int octave = number / NOTES_PER_OCTAVE;
float baseNumber = number - (octave * NOTES_PER_OCTAVE);
float ret = snap(baseNumber, targets) + (octave * NOTES_PER_OCTAVE);
return ret;
}
and here's 'snap':
// given a single value and a list of values (a scale), return the member of the list which is closest to the single value
static inline float snap(float number, std::vector<float>* targets){
float ret;
float leastDistance = -1;
for(int i = 0; i<targets->size(); i++){
float distance = targets->at(i) - number;
if(distance < 0){
distance = -distance;
}
if(leastDistance == -1){
leastDistance = distance;
}
if(distance < leastDistance){
leastDistance = distance;
ret = targets->at(i);
}
}
return ret;
}
I'm completely baffled by this. Any idea why the first explodes and the second works perfectly?
My psychic debugging powers tell me that when you use the temp variable the problem only appears to go away and that either you're accidentally doing targets[<foo>] inside snap or you use it correctly but rarely run off the end, returning garbage.
EDIT for comment:
I should elaborate a bit: targets is a pointer to vector so using [] on it will select one of several vectors, NOT elements from the vector. That said I can't understand how you could call .at on such a pointer, so I suspect the code in your program is not the code you showed us.
In snap() the local variable ret is never initialized so if the input vector is either zero-sized or the "found" element is the first one then your return value is unspecified.
Try modifying snap to be:
static inline float snap(float number, std::vector<float>* targets){
float ret = 0;
float leastDistance = -1;
for(int i = 0; i<targets->size(); i++){
float distance = targets->at(i) - number;
if(distance < 0){
distance = -distance;
}
if(leastDistance == -1){
leastDistance = distance;
ret = targets->at(i);
}
else if(distance < leastDistance){
leastDistance = distance;
ret = targets->at(i);
}
}
return ret;
}
and see if that fixes things.
Edit: I realized this doesn't address why adding a temporary variable appears to fix things in the original question. The uninitialized ret will probably take on whatever value is left on the stack: this, of course, is unspecified and system/platform dependent. When a new local variable is added to store the result of snap(), however, this shifts the stack such that ret has a different position, most likely, a different uninitialized value. The return result is still "wrong" but it may simply appear "less wrong" due to whatever uninitialized value ret has.

c++ type error message from compiler, what does it mean?

I'm using g++ on fedora linux 13.
I'm just practicing some exercises from my c++ textbook
and can't get this one program to compile. Here is the code:
double *MovieData::calcMed() {
double medianValue;
double *medValPtr = &medianValue;
*medValPtr = (sortArray[numStudents-1] / 2);
return medValPtr;
}
Here is the class declaration:
class MovieData
{
private:
int *students; // students points to int, will be dynamically allocated an array of integers.
int **sortArray; // A pointer that is pointing to an array of pointers.
double average; // Average movies seen by students.
double *median; // Median value of movies seen by students.
int *mode; // Mode value, or most frequent number of movies seen by students.
int numStudents; // Number of students in sample.
int totalMovies; // Total number of movies seen by all students in the sample.
double calcAvg(); // Method which calculates the average number of movies seen.
double *calcMed(); // Method that calculates the mean value of data.
int *calcMode(); // Method that calculates the mode of the data.
int calcTotalMovies(); // Method that calculates the total amount of movies seen.
void selectSort(); // Sort the Data using selection sort algorithm.
public:
MovieData(int num, int movies[]); // constructor
~MovieData(); // destructor
double getAvg() { return average; } // returns the average
double *getMed() { return median; } // returns the mean
int *getMode() { return mode; } // returns the mode
int getNumStudents() { return numStudents; } // returns the number of students in sample
};
Here is my constructor and destructor and selectSort():
MovieData::MovieData(int num, int movies[]) {
numStudents = num;
// Now I will allocate memory for student and sortArray:
if(num > 0) {
students = new int[num];
sortArray = new int*[num];
// The arrays will now be initialized:
for(int index = 0;index < numStudents;index++) {
students[index] = movies[index];
sortArray[index] = &students[index];
}
selectSort(); // sort the elements of sortArray[] that point to the elements of students.
totalMovies = calcTotalMovies();
average = calcAvg();
median = calcMed();
mode = calcMode();
}
}
// Destructor:
// Delete the memory allocated in the constructor.
MovieData::~MovieData() {
if(numStudents > 0) {
delete [] students;
students = 0;
delete [] sortArray;
sortArray = 0;
}
}
// selectSort()
// performs selection sort algorithm on sortArray[],
// an array of pointers. Sorted on the values its
// elements point to.
void MovieData::selectSort() {
int scan, minIndex;
int *minElement;
for(scan = 0;scan < (numStudents - 1);scan++) {
minIndex = scan;
minElement = sortArray[scan];
for(int index = 0;index < numStudents;index++) {
if(*(sortArray[index]) < *minElement) {
minElement = sortArray[index];
minIndex = index;
}
}
sortArray[minIndex] = sortArray[scan];
sortArray[scan] = minElement;
}
}
The compiler is giving this error:
moviedata.cpp: In memberfunction
'double * MovieData::calcMed()':
moviedata.cpp:82: error: invalid
operands of types 'int*' and 'double'
to binary 'operator/'
I'm not sure what to make of this error, i've tried static casting the types with no luck, what does this error message mean?
you are trying to divide a pointer by a double, which the compiler is saying it does not know how todo.
sortArray is probably defined by
int ** sortArray;
its also worth noting you are returning a pointer to a stack variable, who's value will be undefined as soon as you return out of the function.
sortArray[numStudents - 1] is a pointer to int, which can't be on the left side of a division (when you remember pointers are addresses, this makes sense). If you post more of your code, we can help you correct it.
Perhaps you want something like:
int *MovieData::calcMed() {
return sortArray[(numStudents - 1) / 2];
}
This returns the middle element in your array, which should be a pointer to the middle student. I'm not clear why you're sorting lists of pointers (not the actual values), or why you're returning a pointer here. The return value + 1 will be a pointer to the next value in students, which is not the next greater value numerically. So you might as well return the actual student (int from students). If you do this, you can also average the two middle elements when the count is even (this rule is part of the typical median algorithm).
Note that I changed the return type to int *, the type of sortArray's elements. Also, your comment is incorrect. This is the median, not the mean.
Also, your selection sort is wrong. The inner loop should start at scan + 1.
Your code shows a lack of understanding of pointers. You need to do more reading and practice on simpler examples.
More specifically:
double medianValue; creates a double variable. What for? You're apparently going to return a double * and returning a pointer to a local variable is always wrong, because local variables are "recycled" when their function ends.
double *medValPtr = &medianValue; creates a pointer called medValPtr and sets it to the location of medianValue. Well.
Due to the current contents of medValPtr, *medValPtr = (sortArray[numStudents-1] / 2); has the same effect as typing medianValue = (sortArray[numStudents-1] / 2); (supposing it were to compile at all).
Which it doesn't because sortArray[numStudents-1] is, at a guess, the last item in the array sortArray but happens to be a pointer to something else. You can't divide a pointer (numerically you can, but C++ disallows it's always wrong).
Finally you return medValPtr; which is wrong because medValPtr is pointing to a local variable.
You probably want something like:
int *MovieData::calcMed() {
return sortArray[numStudents/2];
}