All is in the title. How to check a possible overflow when using the two functions exp() and log()?
#include <errno.h>
When an oferflow occurs, then errno is set to ERANGE.
Next time, do your homework before asking.
Googling: "c++ exp" returned this as the first result http://www.cplusplus.com/reference/cmath/exp/
In the middle of the page, there is EXACTLY what you're looking for.
To expand the answer of #TheOtherGuy, you can cancel the operation if overflow occurs.
#include <stdio.h>
#include <math.h>
#include <errno.h>
int main(void)
{
double param, result;
errno = 0;
param = 1e3;
result = exp (param);
if (errno == ERANGE) {
printf("exp(%f) overflows\n", param);
result = param;
}
printf ("The exponential value of %f is %f.\n", param, result );
return 0;
}
The best way to check for overflow beforehand is to do so intelligently on a case-by-case basis.
Using your knowledge of logarithms and exponents, you should be able to identify potential overflows using properties like INT_MAX: examine these C++ Limitations
I threw a rough sample c++ execution together, assuming you know beforehand what limits you are attempting to follow.
#include <iostream>
// nTh root calculator
bool is_exp_overflow(int input_val, int exponent)
{
my_max = pow(INT_MAX, (1/exponent);
if (input_val > my_max)
{
return true;
}
else
return false;
}
void runExp(int my_input, int my_exp)
{
// Do maths
}
int main()
{
int my_input = 0;
int my_exp = 0;
std::cout << "Enter test value\n";
std::cin >> my_input;
std::cout << "Enter test exponent\n";
std::cin >> my_exp;
bool exp_unsafe = 1;
exp_unsafe = is_exp_overflow(my_input, my_exp);
if (!exp_unsafe)
runExp(my_input, my_exp);
else
std::cout << "Code is unsafe\n";
return 0;
}
If you're looking to catch the errors post mortem, examine errno in range.
For the exp() handling:
Just compare against a variable which you assign to log(FLT_MAX). FLT_MAX is biggest float.
You can do this before calculating an exp(). Because log() is inverse of exp() .
#include <iostream>
#include <math.h>
using namespace std;
int main()
{
float a=1E+37f; // an example of maximum finite representable floating-point number.
//max value can change with platform so,
//either use definitions or use a function you wrote
// a= getMaxFloat(); or a=FLT_MAX
float b=log(a); // limit of float to give in exp();
float c=3242325445.0f; // test variable
cout << "Hello world!" << endl;
if(c>b){cout<<"you should not take exp of "<<c<<endl;}else{cout<<"go on"<<endl;}
return 0;
}
For the log() handling:
1)You cannot everflow log(x) before overflowing x. (for the upper bound)
2)Float's/Double's (x) precision is not enough to overflow to negative-infinity for log(x).
3)Make sure x is bigger than zero.
Better than prevent, you can catch the exception:
try {
z=exp(n);
} catch (...) {
puts("Can't calcute exp...");
}
Related
So I am new to c++, coming from C#. This is giving me several errors when compiling, which all seem to relate to this object declaration. Anyone able to show me the right way to do this?
I get an undeclared identifier where i declare tri(sideLength).
I have used this as a reference for object declaration, but it doesn't seem to be helping me.
Thanks.
#include <iostream> // Provides cout
#include <iomanip> // Provides setw function for setting output width
#include <cstdlib> // Provides EXIT_SUCCESS
#include <cassert> // Provides assert function
#include <stdexcept>
#include <math.h>
using namespace std; // Allows all standard library items to be used
void setup_cout_fractions(int fraction_digits)
// Precondition: fraction_digits is not negative.
// Postcondition: All double or float numbers printed to cout will now be
// rounded to the specified digits on the right of the decimal.
{
assert(fraction_digits > 0);
cout.precision(fraction_digits);
cout.setf(ios::fixed, ios::floatfield);
if (fraction_digits == 0)
cout.unsetf(ios::showpoint);
else
cout.setf(ios::showpoint);
}
int main()
{
const int MAX_SIDE_LENGTH = 6;
const int INITIAL_LENGTH = 1;
const int DIGITS = 4;
const int ARRAY_SIZE = 6;
// Set up the output for fractions and print the table headings.
setup_cout_fractions(DIGITS);
// Each iteration of the loop prints one line of the table.
for (int sideLength = 0; sideLength < MAX_SIDE_LENGTH; sideLength += 1)
{
EquilateralTriangle tri(sideLength);
//Square sq(sideLength);
//Pentagon_Reg pent(sideLength);
//Hexagon_Reg hex(sideLength);
//Heptagon_Reg hept(sideLength);
//Octagon_Reg octa(sideLength);
cout << "Type: " << tri.Name() << "has area: " << tri.Area() << " with SideLength = " << sideLength;
}
return EXIT_SUCCESS;
}
//Template
class GeometricFigure
{
public:
GeometricFigure() { }
double SideLength;
virtual double Area() { return 0; };
virtual char* Name() { return ""; };
};
class EquilateralTriangle : public GeometricFigure {
public:
EquilateralTriangle(double sideLength)
{
SideLength = sideLength;
}
char* Name() { return "Equilateral Triangle"; }
double Area() { return (sqrt(3) / 2 * pow(SideLength, 2)); }
};
In C++, the compiler reads your code from top-to-bottom, once. This is a holdover from when early C compilers only had a few kilobytes of memory to work with - C was designed so that a compiler would only need to look at a little bit of the code at a time.
Because of this, things must have been declared or defined as necessary, before you try to use them.
Move both classes somewhere before main. GeometricFigure must be before EquilateralTriangle, and EquilateralTriangle must be before main.
You would need to "declare" or tell the compiler, where to look for the EquilateralTriangle and GeometricFigure, "before" you use it first. you might want to take a look at the similar discussion at - C# declarations vs definitions
At present I am working on piece of C++ code in which I need to read data from a database, and if database value is non-zero, then I need to apply some further logic.
But in the database there are values which are being calculated and can come out as -0.0. And this negative zero is being treated as Garbage value in C++ double variable. I have already initialized the value as 0.0 in constructor.
Sample Code:
for(Sample::List<BalanceSheet>::Iterator i((Sample::List<BalanceSheet> &) Balance.Entries()); i.HaveItem(); ++i) // This list is being populated from Database
{
if (SomeCondition != "")
{
if (i->GetBalance() != 0) // This is where am getting Garbage values since GetBalance() returns -0.0
{
DoOperation();
}
}
}
-0.0 is perfectly valid value for a double. The problem you are having is that you are comparing doubles for inequality.
What you should do is something like this:
i->GetBalance() > std::numeric_limits<double>::epsilon()
First off, you should never be using == or != with floating point variables. They are essentially meaningless operations, as the limitations of floating point types mean that even seemingly innocuous values might not compare identically. It is completely possible that 2 + 2 isn't 4, at least as far as == would identify it.
The real issue here is that you are making use of the sign of a "zero" value, which as per above, might not actually be exactly zero in the first place, but more importantly, is difficult to test for using standard comparison operators. See this related question for some discussion.
The best solution for this, if you have access to C++11 or a compiler supporting it, is to use copysign as per Vlad's answer on that question. This function takes 2 parameters. The first represents the magnitude of the return value, and the second the sign. Here is an example:
#include "iostream"
#include <math.h>
using namespace std;
int main()
{
double posZero = +0.0d;
double negZero = -0.0d;
if( copysign( 1, posZero ) < 0 )
{
cout << "posZero is negative\n";
}
else
{
cout << "posZero is positive\n";
}
if( copysign( 1, negZero ) < 0 )
{
cout << "negZero is negative\n";
}
else
{
cout << "negZero is positive\n";
}
}
posZero is positive
negZero is negative
In this example, copysign creates a value of +/- 1, according to the sign on the second argument. The first argument for your purposes could be any non-zero value, but might as well be 1.
Alternatively, you could use signbit, which is honestly probably more direct. A version of the above using this function:
#include "iostream"
#include <math.h>
using namespace std;
int main()
{
double posZero = +0.0d;
double negZero = -0.0d;
if( signbit( posZero ) )
{
cout << "posZero is negative\n";
}
else
{
cout << "posZero is positive\n";
}
if( signbit( negZero ) )
{
cout << "negZero is negative\n";
}
else
{
cout << "negZero is positive\n";
}
}
With the same output.
A problem set for people learning C++ is
Write a short program to simulate a ball being dropped off of a tower. To start, the user should be asked for the initial height of the tower in meters. Assume normal gravity (9.8 m/s2), and that the ball has no initial velocity. Have the program output the height of the ball above the ground after 0, 1, 2, 3, 4, and 5 seconds. The ball should not go underneath the ground (height 0).
Before starting C++ I had a reasonable, but primarily self taught, knowledge of Java. So looking at the problem it seems like it ought to be split into
input class
output class
calculations class
Physical constants class (recommended by the question setter)
controller ('main') class
The input class would ask the user for a starting height, which would be passed to the controller. The controller would give this and a number of seconds (5) to the calculations class, which would create an array of results and return this to the controller. The controller would hand the array of results to the output class that would print them to the console.
I will put the actual code at the bottom, but it's possibly not needed.
You can probably already see the problem, attempting to return an array. I'm not asking how to get round that problem, there is a workaround here and here. I'm asking, is the problem a result of bad design? Should my program be structured differently, for performance, maintenance or style reasons, such that I would not be attempting to return an array like object?
Here is the code (which works apart from trying to return arrays);
main.cpp
/*
* Just the main class, call other classes and passes variables around
*/
#include <iostream>
#include "dropSim.h"
using namespace std;
int main()
{
double height = getHeight();
int seconds = 5;
double* results = calculateResults(height, seconds);
outputResults(results);
return 0;
}
getHeight.cpp
/*
* Asks the user for a height from which to start the experiment
* SI units
*/
#include <iostream>
using namespace std;
double getHeight()
{
cout << "What height should the experiment start at; ";
double height;
cin >> height;
return height;
}
calculateResults.cpp
/*
* given the initial height and the physical constants, the position of the ball
* is calculated at integer number seconds, beginning at 0
*/
#include "constants.h"
#include <cmath>
#include <iostream>
using namespace std;
double getPosition(double height, double time);
double* calculateResults(double height, int seconds)
{
double positions[seconds + 1];
for(int t = 0; t < seconds + 1; t++)
{
positions[t] = getPosition(height, t);
}
return positions;
}
double getPosition(double height, double time)
{
double position = height - 0.5*constants::gravity*pow(static_cast<double>(time), 2);
if( position < 0) position = 0;
//Commented code is for testing
//cout << position << endl;
return position;
}
outputResults.cpp
/*
* Takes the array of results and prints them in an appropriate format
*/
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
void outputResults(double* results){
string outputText = "";
//The commented code is to test the output method
//Which is working
//double results1[] = {1,2,3,4,5};
//int numResults = sizeof(results1)/sizeof(results1[0]);
int numResults = sizeof(results)/sizeof(results[0]);
//cout << numResults; //= 0 ... Oh
for(int t = 0; t < numResults; t++)
{
ostringstream line;
line << "After " << t << " seconds the height of the object is " << results[t] << "\r";
outputText.append(line.str());
}
cout << outputText;
}
And finally a couple of headers;
dropSim.h
/*
* dropSim.h
*/
#ifndef DROPSIM_H_
#define DROPSIM_H_
double getHeight();
double* calculateResults(double height, int seconds);
void outputResults(double* results);
#endif /* DROPSIM_H_ */
constants.h
/*
* Contains physical constants relevant to simulation.
* SI units
*/
#ifndef CONSTANTS_H_
#define CONSTANTS_H_
namespace constants
{
const double gravity(9.81);
}
#endif /* CONSTANTS_H_ */
I would say that you're over-engineering a big solution to a little problem, but to answer your specific question:
Should my program be structured differently, for performance, maintenance or style reasons, such that I would not be attempting to return an array like object?
Returning an array-like object is fine. But that doesn't mean returning an array, nor does it mean allocating raw memory with new.
And it's not restricted to return values either. When you're starting out with C++, it's probably best to just forget that it has built-in arrays at all. Most of the time, you should be using either std::vector or std::array (or another linear collection such as std::deque).
Built-in arrays should normally be viewed as a special-purpose item, included primarily for compatibility with C, not for everyday use.
It may, however, be worth considering writing your computation in the same style as the algorithms in the standard library. This would mean writing the code to receive an iterator to a destination, and writing its output to wherever that iterator designates.
I'd probably package the height and time together as a set of input parameters, and have a function that generates output based on those:
struct params {
double height;
int seconds;
};
template <class OutIt>
void calc_pos(params const &p, OutIt output) {
for (int i=0; i<p.seconds; i++) {
*output = get_position(p.height, i);
++output;
}
}
This works somewhat more clearly along with the rest of the standard library:
std::vector<double> results;
calc_pos(inputs, std::back_inserter(results));
You can go a few steps further if you like--the standard library has quite a bit to help with a great deal of this. Your calc_pos does little more than invoke another function repeatedly with successive values for the time. You could (for example) use std::iota to generate the successive times, then use std::transform to generate outputs:
std::vector<int> times(6);
std::iota(times.begin(), times.end(), 0);
std::vector<double> distances;
std::transform(times.begin(), times.end(), compute_distance);
This computes the distances as the distance dropped after a given period of time rather than the height above the ground, but given an initial height, computing the difference between the two is quite trivial:
double initial_height = 5;
std::vector<double> heights;
std::transform(distances.begin(), distances.end(),
std::back_inserter(heights),
[=](double v) { return max(initial_height-v, 0); });
At least for now, this doesn't attempt to calculate the ball bouncing when it hits the ground--it just assumes the ball immediately stops when it hits the ground.
You should get rid of self-allocated double * and use std::vector<double> instead. It's not difficult to learn and a basic step in modern C++
This is how I would solve the problem:
#include <cmath>
#include <iostream>
#include <iomanip>
using std::cin;
using std::cout;
using std::endl;
using std::sqrt;
using std::fixed;
using std::setprecision;
using std::max;
using std::setw;
static const double g = 9.81;
class Calculator {
public:
Calculator(double inh) : h(inh)
{
}
void DoWork() const {
double tmax = sqrt(h / ( g / 2));
for (double t=0.0; t<tmax; t+=1.0) {
GenerateOutput(t);
}
GenerateOutput(tmax);
}
private:
void GenerateOutput(double t) const {
double x = g * t * t / 2;
double hremaining = max(h - x, 0.0);
cout << fixed << setprecision(2) << setw(10) << t;
cout << setw(10) << hremaining << endl;
}
double h;
};
int main() {
double h(0.0);
cout << "Enter height in meters: ";
cin >> h;
if (h > 0.0) {
const Calculator calc(h);
calc.DoWork();
} else {
return 1;
}
return 0;
}
It's been a while since I used C++. I was asked for job interview to create a C++ struct for a downsampling routine which would meet the following interface:
struct deterministic_sample
{
deterministic_rate( double rate );
bool operator()();
};
-- with the following behaviour:
We have an object of that class: deterministic_sample s;
We call s() N times, and it returns true, M times. M / N is roughly equal to the rate
The sequence is deterministic, not random and should be the same each time
The class should be "industrial strength", for use on a busy stream.
My solution, version 2:
#include <iostream>
#include <cmath>
#include <climits>
using namespace std;
struct deterministic_sample
{
double sampRate;
int index;
deterministic_sample() {
sampRate = 0.1;
index = 0;
}
void deterministic_rate( double rate ) {
this->sampRate = rate; // Set the ivar. Not so necessary to hide data, but just complying with the interface, as given...
this->index = 0; // Reset the incrementer
};
bool operator()() {
if (this->index == INT_MAX) {
this->index = 0;
}
double multiple = this->index * this->sampRate;
this->index++; // Increment the index
if (fmod(multiple, 1) < this->sampRate) {
return true;
} else {
return false;
}
};
};
int main()
{
deterministic_sample s; // Create a sampler
s.deterministic_rate(0.253); // Set the rate
int tcnt = 0; // Count of True
int fcnt = 0; // Count of False
for (int i = 0; i < 10000; i++) {
bool o = s();
if (o) {
tcnt++;
} else {
fcnt++;
}
}
cout << "Trues: " << tcnt << endl;
cout << "Falses: " << fcnt << endl;
cout << "Ratio: " << ((float)tcnt / (float)(tcnt + fcnt)) << endl; // Show M / N
return 0;
}
The interviewer said this v2 code "partly" addressed the requirements. v1 didn't have the constructor (my error), and didn't deal with overflow of the int ivar.
What have I missed here to make this class robust/correct? I think it is some aspect of "industrial strength" that I've missed.
ps. for any ethical types, I've already submitted my second-chance attempt... It's just bothering me to know why this was "partly"...
What you have is far more complex than necessary. All you need to do is keep track of the current position, and return true when it goes past the threshold.
struct deterministic_sample
{
double sampRate;
double position;
deterministic_sample() : sampRate(0.1), position(0.0) {
}
void deterministic_rate( double rate ) {
assert(rate <= 1.0); // Only one output is allowed per input
sampRate = rate; // Set the ivar. Not so necessary to hide data, but just complying with the interface, as given...
// No need to reset the position, it will work with changing rates
};
bool operator()() {
position += sampRate;
if (position < 1.0)
return false;
position -= 1.0;
return true;
}
};
Use unsigned and integer overflow is a well-defined wraparound. This is very fast on normal CPU's.
The second problem I see is the mix of floating-point and integer math. That's not really efficient. It may be more efficient to store multiple as a member and just do multiple += rate. This saves you one integer to double conversion.
However, the fmod is still quite expensive. You can avoid that by keeping int trueSoFar instead. Now the rate so far is double(trueSoFar)/double(index) and you can check double(trueSoFar)/double(index) > rate or more efficiently trueSoFar> int(index * rate). As we already saw, rate*index can be replaced by multiple += rate.
This means we have one double addition (multiple +=), one FP to int conversion int(multiple) and one integer comparison.
[edit]
You can also avoid FP math altogether by keeping a 32/32 rational approximation of rate, and comparing that to the realised rate (again stored as a 32/32 ratio). Since a/b > c/d when a*d > b*c you can use a 64 bit multiply here. Even better, for the target ratio you can choose 2^32 as a fixed denominator (i.e. unsigned long targetRate = rate*pow(2^32), b=2^32 implicit) so that you now have unsigned long(unsigned long long(a)*index) >> 32) > trueSoFar. Even on a 32 bit CPU, this is fairly quick. >>32 is a no-op there.
OK, so it seems there are some improvements to the efficiency which could be made (certainly), that "industrial strength" has some implications though nothing concrete (possibly the problem...), or that the constructor was incorrectly named in the question (also possible).
In any case, no one has jumped on some glaring omission that I made to my constructor (like, I see there are two ways to do a C++ constructor; you should do both to be really bullet-proof, etc.)
I guess I'll just cross my fingers and hope I still progress to the soft-skills interview!
Thanks all.
Write a program that simulates flipping a coin repeatedly and continues until three consecutive heads are tossed, in C++
#include <iostream>
#include <cmath>
#include <string>
#include <cstdlib>
#include "random.h"
using namespace std;
bool FlipCoin(int flip);
int main(){
int flip;
int heads = 0;
int total_flips = 0;
while( heads < 3){
total_flips++;
if(FlipCoin(flip) == "heads"){
heads++;
} else{
heads = 0;
}
}
cout << "it took " << total_flips << "to get 3 consecutive heads. " << endl;
}
bool FlipCoin(int flip) {
if (randomChance(0.50)) {
return "heads";
} else {
return "tails";
}
}
I am getting this error in the main body of my code that states that
ISO C++ forbids comparison between pointer and integer
at the if (FlipCoin(flip) == "heads") part. If anyone can help me correct this that would be great.
Since strings are inefficient and error-prone (one typo and your comparison fails, while the compiler stays absolutely silent) and bools do not represent coin sides very well (is true heads or tails?), the best way to write this is using an enum:
enum class CoinSide { heads, tails };
CoinSide FlipCoin() { // note: you don't need the "flip" parameter
if (randomChance(0.50)) {
return CoinSide::heads;
} else {
return CoinSide::tails;
}
}
int main() {
...
if (FlipCoin() == CoinSide::heads) {
...
}
}
You have defined FlipCoin() with a return type of bool, but you're returning char* from it. You have a couple of options:
Change FlipCoin() to return char*. Then use if (strcmp(FlipCoin(flip), "heads") == 0). "heads" == "heads" works in C/C++, but only because of luck because the compiler optimizes the string table. So the pointers are equal, but it's not exactly correct. strcmp() returns 0 if the strings are equal, non-zero if they are not.
Change FlipCoin to return std::string, then use if (FlipCoin(flip) == "heads").
You should be getting a few compiler warnings from this code, about returning char* from a bool function, and about an unused parameter (flip) being passed into FlipCoin().
You wrote:
bool FlipCoin [....] return "heads";
Do you believe that "heads" / "tails" qualifies as a boolean type?
You should decide if FlipCoin is going to return true / false, or return a string.
After you've resolved that, you can fix your if-statement comparison:
if(FlipCoin(flip) == "heads"){
To either compare against a bool or a string.
But right now, it does not make any sense to declare FlipCoin to return a bool, actually return a string, try to convert the string to a bool, then try to compare the bool to a string.