Dividing a Float by Itself Produces Very Large Integers - c++

So I'm having what seems to me to be a very bizarre problem. I've got a crude system for applying forces to objects on 2D planes, and one of the simplest calculations seems to be causing one of my variables to overflow. I have the following line:
int ySign = m_Momentum.y / abs(m_Momentum.y);
Where Momentum has two data members, x y (m_Momentum is an SFML sf::Vector2 of floats). Now, normally the formula should always return either 1 or -1, depending on the sign of Momentum.y (unless I'm grossly mistaken).
However, it occasionally returns insanely high numbers such as -2147483648. In that particular case, the value of m_Momentum.y was 0.712165 (both values were obtained by sending to std::cout); I tried again, m_Momentum.y was -0.578988 and ySign was still -2147483648. There is a corresponding xSign that also flips out sometimes, often with the same final value. I can't confirm 100% that this is always the result, but at the moment that seems to be the case.
I'm sort of stumped as to why this is happening, and when it does, it basically invalidates my program (it instantly sends objects millions of pixels in the wrong direction). It seems logically impossible that the line above is returning such strange results.
Below is the function I am working on. Probably the wrong way to do it, but I didn't expect it to go so horribly wrong. The printout it produces reveals that all numbers look normal until the signs are printed out; one of them is invariably massive, and afterwards you see numbers like -2.727e+008 (which, as far as I'm aware, is scientific notation - i.e. -2.727 * 10 ^ 8).
///MODIFY MOMENTUM
//Reset, if necessary
if (Reset == true)
{
m_Momentum.x = 0;
m_Momentum.y = 0;
}
sf::Vector2<float> OldMoment = m_Momentum;
//Apply the force to the new momentum.
m_Momentum.x += Force.x;
m_Momentum.y += Force.y;
sf::Vector2<float> NewMoment = m_Momentum;
//Calculate total momentum.
float sqMomentum = m_Momentum.x * m_Momentum.x + m_Momentum.y * m_Momentum.y;
float tMomentum = sqrt(sqMomentum);
//Preserve signs for later use.
int xSign = m_Momentum.x / abs(m_Momentum.x);
int ySign = m_Momentum.y / abs(m_Momentum.y);
//Determine more or less the ratio of importance between x and y components
float xProp;
float yProp;
if (abs(tMomentum) > m_MaxVelocity)
{
//Get square of maximum velocity
int sqMax = m_MaxVelocity * m_MaxVelocity;
//Get proportion of contribution of each direction to velocity
xProp = (m_Momentum.x * m_Momentum.x) / sqMomentum;
yProp = (m_Momentum.y * m_Momentum.y) / sqMomentum;
//Reset such that the total does not exceed maximum velocity.
m_Momentum.x = sqrt(sqMax * xProp) * xSign;
m_Momentum.y = sqrt(sqMax * yProp) * ySign;
}
///SANITY CHECK
//Preserve old tMomentum
float tOld = tMomentum;
//Calculate current tMomentum
sqMomentum = m_Momentum.x * m_Momentum.x + m_Momentum.y * m_Momentum.y;
tMomentum = sqrt(sqMomentum);
//If it's still too high, print a report.
if (tMomentum > m_MaxVelocity)
{
std::cout << "\n\nSANITY CHECK FAILED\n";
std::cout << "-\n";
std::cout << "Old Components: " << OldMoment.x << ", " << OldMoment.y << "\n";
std::cout << "Force Components: " << Force.x << ", " << Force.y << "\n";
std::cout << "-\n";
std::cout << "New Components: " << NewMoment.x << ", " << NewMoment.y << "\n";
std::cout << "Which lead to...\n";
std::cout << "tMomentum: " << tOld << "\n";
std::cout << "-\n";
std::cout << "Found these proportions: " << xProp << ", " << yProp << "\n";
std::cout << "Using these signs: " << xSign << ", " << ySign << "\n";
std::cout << "New Components: " << m_Momentum.x << ", " << m_Momentum.y << "\n";
std::cout << "-\n";
std::cout << "Current Pos: " << m_RealPosition.x << ", " << m_RealPosition.y << "\n";
std::cout << "New Pos: " << m_RealPosition.x + m_Momentum.x << ", " << m_RealPosition.y + m_Momentum.y << "\n";
std::cout << "\n\n";
}
///APPLY FORCE
//To the object's position.
m_RealPosition.x += m_Momentum.x;
m_RealPosition.y += m_Momentum.y;
//To the sprite's position.
m_Sprite.Move(m_Momentum.x, m_Momentum.y);
Can somebody explain what's going on here?
EDIT: RedX helpfully directed me to the following post: Is there a standard sign function (signum, sgn) in C/C++? Which led me to write the following lines of code:
//Preserve signs for later use.
//int xSign = m_Momentum.x / abs(m_Momentum.x);
//int ySign = m_Momentum.y / abs(m_Momentum.y);
int xSign = (m_Momentum.x > 0) - (m_Momentum.x < 0);
int ySign = (m_Momentum.y > 0) - (m_Momentum.y < 0);
Thanks to the above, I no longer have the strange problem. For an explanation/alternative solution, see Didier's post below.

You should use fabs() instead of abs() to get the absolute value of a floating point number. If you use the integer absolute function, then the result is an integer ...
For instance, -0.5 / abs(-0.5) is treated as -0.5 / 0 which results in negative infinity (as a floating point value) that is converted to the minimum value of an int 0x80000000 = -2147483648

Taking absolute values and dividing sounds like an awful waste of cycles to me. What's wrong with
x > 0 ? 1 : -1
which you could always put in a function
template <class T>
inline int sgn(const T &x) { return x > 0 ? : 1; }

Related

Results are off

Is something off with my formula for the variables especially for change_in_pennies or is the problem with my choices of the datatypes for the variables? When I input 270 or 280 I get almost everything correct except for the value of pennies where it's a completely random value or number where it should be zero
enter image description here
const double quarter_value {0.25};
const double dime_value {0.1};
const double nickle_value {0.05};
const double penny_value {0.01};
int main() {
int amount{}, change_in_dollars{}, change_in_quarters{},
change_in_dimes{}, change_in_nickles{};
double total{}, change_in_pennies{};
cout << "Enter an amount in cents : ";
cin >> amount;
cout << "You can provide change for this"
" change as follows: " << endl;
total = (static_cast <double> (amount) / 100);
cout << "total: " << total << endl;
change_in_dollars = (amount / 100);
cout << "dollars : " << change_in_dollars << endl;
change_in_quarters = (total - change_in_dollars) / quarter_value;
cout << "quarters : " << change_in_quarters << endl;
change_in_dimes = (total - change_in_dollars - (quarter_value * change_in_quarters)) / dime_value;
cout << "dimes : " << change_in_dimes << endl;
change_in_nickles = (total - change_in_dollars - (quarter_value * change_in_quarters) - (dime_value * change_in_dimes)) / nickle_value;
cout << "nickles : " << change_in_nickles << endl;
change_in_pennies = (total - (change_in_dollars) - (quarter_value * change_in_quarters) - (dime_value * change_in_dimes) - (nickle_value * change_in_nickles)) / penny_value;
cout << "pennies: " << change_in_pennies << endl;
return 0;
}
Like others have commented, the problem is likely that your double-to-int conversions are truncated rather than rounded, making even a tiny round-off error lead to a different result. To avoid this, use purely int arithmetic and work in units of cents. Or if you use doubles, make sure to apply std::round() before casting back to ints.

Creating a C++ program to solve an equation of motion using Euler's method

I am trying to compute the time history of the velocity described by the equation:
dV/dt = g − (C_d/m) * V^2. g = 9.81, m = 1.0, and C_d = 1.5.
To do this I need to create a program in c++ that uses the Euler explicit method to numerically solve the equation. I am trying to find the velocity from t = 0 to t = 1 seconds with three different step sizes of delta_t = 0.05, 0.1, and 0.2 seconds. And then you are supposed to show your percent error to the analytical solution given as: V(t) = sqrt((m*g)/C_d) * tanh(sqrt((g*C_d)/m) * t).
My problem is I am not sure how to iterate through Euler's method multiple times with different time intervals. So far I have solved the analytical equation, but am unsure where to go from here. If anyone could help point me in the right direction it would be greatly appreciated.
#include <iomanip>
#include <cmath>
#include <math.h>
using namespace std;
int main() {
double m = 1.0; // units in [kg]
double g = 9.81; // units in [m/s^2]
double C_d = 1.5; // units in [kg/m]
double t; // units in [s]
double v; // units in [m/s]
cout << "The velocity will be examined from the time t = 0 to t = 1 seconds." << endl;
cout << "Please select either 0.05, 0.1, or 0.2 to be the time interval:" << endl;
cin >> t;
cout << "You have chosen the time interval of: " << t << " seconds." << endl;
v = sqrt((m * g) / C_d) * tanh(sqrt((g * C_d) / m) * t);
cout << "The velecity at a time of "<< t << " seconds is equal to: " << v << " m/s." << endl;
return 0;
} ```
If you want to iterate over t with increments of A, calculating the result of the formula with each t, you would write a for loop.
#include <iostream>
int main()
{
double m = 1.0; // units in [kg]
double g = 9.81; // units in [m/s^2]
double C_d = 1.5; // units in [kg/m]
std::cout << "The velocity will be examined from the time t = 0 to t = 1 seconds." << std::endl;
std::cout << "Please select the time interval:" << std::endl;
std::cout << "1: 0.05" << std::endl;
std::cout << "2: 0.1" << std::endl;
std::cout << "3: 0.2" << std::endl;
double A = 0; // increment in for loop
int x;
std::cin >> x;
switch (x) { // check what the input is equal to
case 1: A = 0.05; break;
case 2: A = 0.1; break;
case 3: A = 0.2; break;
default: std::cout << "Unknown option!" << std::endl; return 1;
}
std::cout << "You have chosen the time interval of: " << A << " seconds." << std::endl;
std::cout << "Results of V(t):" << std::endl;
// this initializes a variable t as 0,
//and while t is lower than or equal to 1,
//it will increment it by a and execute the logic within the scope of the loop.
for (double t = 0; t < (1 + A); t += A) {
std::cout << "at t = " << t << ": " << sqrt((m*g) / C_d) * tanh(sqrt((g*C_d) / m) * t) << std::endl;
}
return 0;
}
Refer to https://beginnersbook.com/2017/08/cpp-for-loop/ for more information. Note: I've also introduced a switch statement into the code to prevent unknown values from being input. https://beginnersbook.com/2017/08/cpp-switch-case/

Simple Floating Point Calculations Produce Different Results

I'm using Visual Studio 2008 and have encountered a case where the same code in two different versions of the same class library apparently produces different answers.
The following code reflects my attempts to reproduce the problem. It simply takes two pairs of numbers, (cx, cy) and (rx, ry), subtracts them, and displays the results (tx, ty) in decimal and hex format.
#include <iostream>
#include <fstream>
#include <sstream>
#include <iomanip>
using namespace std;
string dhex(double x) { // double to hex
union {
unsigned long long n;
double d;
} value;
value.d = x;
std::ostringstream buf;
buf << "0x" << std::hex << std::setfill('0') << std::setw(16) << value.n;
return buf.str();
}
double i64tod(unsigned long long n) { // hex to double
double *DP = (double *) &n;
return *DP;
}
int main(int argc, char **argv) {
double tx, ty, cx, cy, rx, ry;
cx = i64tod(0x3fb63f141205bc02); cy = i64tod(0x40019eb851eb851f);
rx = i64tod(0x3fa222fa84a5161c); ry = i64tod(0x40011f8441720667);
tx = cx - rx;
ty = cy - ry;
cout << setprecision(22);
cout << " cx = " << setw(22) << cx << ", cy = " << setw(22) << cy
<< " (" << dhex(cx) << ", " << dhex(cy) << ")" << endl;
cout << " rx = " << setw(22) << rx << ", ry = " << setw(22) << ry
<< " (" << dhex(rx) << ", " << dhex(ry) << ")" << endl;
cout << " tx = " << setw(22) << tx << ", ty = " << setw(22) << ty
<< " (" << dhex(tx) << ", " << dhex(ty) << ")" << endl;
return 0;
}
The output from this code is:
cx = 0.086900000000000005, cy = 2.2025000000000001 (0x3fb63f141205bc02, 0x40019eb851eb851f)
rx = 0.035423115436554492, ry = 2.1403889763758346 (0x3fa222fa84a5161c, 0x40011f8441720667)
tx = 0.051476884563445513, ty = 0.06211102362416554 (0x3faa5b2d9f6661e8, 0x3fafcd041e5fae00)
The application with the problem has a class library which is a "pool engine", ie. it simulates the physics of pool/snooker shots.
A recent set of changes to that library resulted in a failure of a verification test, which involves a particular sequence of shots that should produce a particular table state.
I tracked it down to that simple subtraction operation. When the new version executes the subtraction, it produces:
cx = 0.086900000000000005, cy = 2.2025000000000001 (0x3fb63f141205bc02, 0x40019eb851eb851f)
rx = 0.035423115436554492, ry = 2.1403889763758346 (0x3fa222fa84a5161c, 0x40011f8441720667)
tx = 0.051476884563445513, ty = ?0.062111023624165547 (0x3faa5b2d9f6661e8, 0x3fafcd041e5fae01)
As you can see the difference is in the least significant bit (of ty), but sometimes more than that. This is the result of another pair of point values:
cx = 1.0641, cy = -0.0545 (0x3ff1068db8bac711, 0xbfabe76c8b439581)
rx = 1.0878512271746064, ry = 0.022594280641953058 (0x3ff167d6b03a0dee, 0x3f9722f481bc3f0d)
tx = -0.023751227174606315, ty = -0.077094280641953061 (0xbf98523ddfd1b740, 0xbfb3bc736610da84)
The program above, and the older library version agree on this case too, but the new library version gives a different answer (for tx) in this case:
tx = -0.023751227174606343, ty = -0.077094280641953061 (0xbf98523ddfd1b748, 0xbfb3bc736610da84)
Both versions of the library have the same compiler options, and the function in question (a collision handler) was not altered by the changes (I was just simplifying the library by replacing a class that had no methods with a struct).
I should add that when the new version gets a different result, at least it is consistent, ie. it ALWAYS produces those different answers.
I could simply accept the new version and replace the verification test with one that matches, but I would really like to know why this is happening.
For the record, I've tried to get the standalone program above to give the "alternative" answers by changing compiler options, etc, but no luck. It only fails in situ, in the new library version.

Access violation of printing variable

I have the following problem where I will get an access violation exception when trying to print a variable, but only after a loop has run a specific number of times.
Specifically on the 211th iteration, the line:
cout << "Frame " << i << ", Recall: " << recall << ", Precision: " << precision << ", IoU: " << iou << endl;
Gives the error:
0xC0000005: Access violation reading location 0x3F09C003.
The weird thing is, this only occurs if I am printing a variable, and it always occurs at the 211th iteration. If I remove the print statement completely, or even just print a string, it works fine. But if I print any variable (i, recall, precision, etc.), it throws this exception. It will also throw the same exception if I remove the printing from the loop completely, and just have a single print statement outside of the loop. Any suggestions?
Code below:
template <typename T>
template <typename T2>
void Rect<T>::GetPerformance(const Rect<T2>& actual,
float &iou, float &precision, float &recall) const {
float numDetections = Area();
float numActual = actual.Area();
iou = Overlap(actual);
float numCorrect = iou *(actual.Area() + Area()) / (1 + iou);
precision = numCorrect / numDetections;
recall = numCorrect / numActual;
}
...
In Main
...
Mat frame;
Mat newFrame;
int i = 0;
float recall;
float precision;
float iou;
float avgRecall = 0;
float avgPrecision = 0;
float avgIoU = 0;
while (1)
{
iFrame = cvQueryFrame(capture);
if (!iFrame) break;
frame = iFrame;
FloatRect bb = carTracker.Track(frame);
bb.GetPerformance(gts[i], iou, precision, recall);
avgRecall += recall;
avgPrecision += precision;
avgIoU += iou;
cout << "Frame " << i << ", Recall: " << recall << ", Precision: " << precision << ", IoU: " << iou << endl;
i++;
}

What to do when an equation returns nan as an answer?

I've been having a slight issue with my program, what I'm trying to do is develop a way for users to simulate the possible strengths of passwords. This is assuming that all passwords are permutations (weird I know, but I presume that this is to stop data from becoming even more unwieldy.) using the equation...
//n!/(n-r)! when n! = (e^-n)*(n^n) sqrt(2(pi)n). When n is number of characters in use and r is length of password
No matter what I put I receive nan as an answer. I thought that perhaps my equation was off (maybe somehow I was dividing by zero) so I reworked it and simplified it a great deal. But that didn't seem to be the problem, though I feel that this got me closer to being correct. But I had the thought that maybe numeric overflow is having an effect here? But I really don't know how to fix something like that. I tried jumping from different data types but nothing seemed to work.
I have a problem with the modulus too. It returns back numbers less than zero for time, so with my noobish knowledge that tells me that maybe I'm overflowing it again but how else am I going to use % without defining it as an int? Maybe fixing the above problem will work out this one?
I would be beyond grateful for any help given to me. How does one go about dealing with return values of nan? Is there a step by step status quo for solving it? Is it pretty much always overflow or could it be something else?
The code itself.
#include <iostream>
#include <cmath>
using namespace std;
const int SECONDS_IN_YEAR = 31556926;
const int SECONDS_IN_DAY = 86400;
const int SECONDS_IN_HOUR = 3600;
const int SECONDS_IN_MIN = 60;
int main()
{
int passwordLength ,characterSymbols;
double instructionsPerSecond, instructionSuccess;
////////////////////////////////////////////////////////////////////////////////
//Equations needed
// n!/(n-r)!
//n is the number of letters in the alphabet
//and r is the number of letters in the password
// n! = (e^-n)*(n^n) sqrt(2(pi)n)
double numeratorFactorial = (pow(M_E,-characterSymbols))
*(pow(characterSymbols,characterSymbols))
*(sqrt(2*M_PI*characterSymbols));
// (n-r)
double characterMinusLength= (characterSymbols-passwordLength);
// (n-r)! = (e^-(n-r)) * ((n-r)^(n-r)) * sqrt(2(pi)(n-r))
double denominatorFactorial = ((pow(M_E, -(characterMinusLength)))*
(pow((characterMinusLength),(characterMinusLength)))
* (sqrt(2*M_PI*(characterMinusLength))));
// n!/(n-r)!
long double passwordPermutation = (numeratorFactorial / denominatorFactorial);
// (passwords)* (instructions/Password) * (seconds/instruction) = sec
int passwordSeconds = (passwordPermutation * instructionSuccess)
*(1/instructionsPerSecond);
int passwordMin = passwordSeconds / SECONDS_IN_MIN ;
int passwordHour = passwordSeconds / SECONDS_IN_HOUR;
int passwordDay = passwordSeconds / SECONDS_IN_DAY ;
int passwordYear = passwordSeconds / SECONDS_IN_YEAR;
////////////////////////////////////////////////////////////////////////////////
//Explain purpose of program
cout << "This program is designed to simulate the strength of passwords." << endl;
//Ask for alphabet
cout << "But first, share with me the max number of characters you'd be using."
<< endl;
cin >> characterSymbols;
//Reflect information
cout << "We will be using " << characterSymbols << " character symbols to "
<< " construct the password.\n" << endl;
///////////////////////////////////////////////////////////////////////////////
//Input length of password
cout << "\n\nWill you give me the length of proposed password?" << endl;
cin >> passwordLength;
//Repeat information
cout << "The password length will be " << passwordLength << "." <<endl;
//cout permutations
cout << "This would lead to " << passwordPermutation << " unique password\n"
<< endl;
////////////////////////////////////////////////////////////////////////////////
//Ask for computer strength
cout << "How powerful is this computer? How many instructions per second " << endl;
cout << "can it accomplish?" << endl;
cin >> instructionsPerSecond;
//Read out computer strength
cout << "The computer can do " << instructionsPerSecond << " instructions/second"
<< endl << endl;
////////////////////////////////////////////////////////////////////////////////
//Ask for instructions/password
cout << "The number of instructions needed to test your password is." << endl
<< endl;
cin >> instructionSuccess;
//reflect
cout << "This computer can do " << instructionSuccess
<< " instructions/password" << endl;
////////////////////////////////////////////////////////////////////////////////
cout << "\n\nThe amount of seconds it'll take to crack this passcode is... "
<< endl << passwordSeconds << " seconds.\n\n\n\n\n" << endl;
////////////////////////////////////////////////////////////////////////////////
//Reflect all information in an easily readable table
cout << "Number of character symbols using... " << characterSymbols << endl;
cout << "Length of password... " << passwordLength << endl;
cout << "Number of permutations... " << passwordPermutation << endl;
cout << "Instructions per second... " << instructionsPerSecond << endl;
cout << "Instructions per password..." << instructionSuccess << endl;
cout << endl << endl << endl;
////////////////////////////////////////////////////////////////////////////////
//Add in conversions for min, hour, day, years
cout << "Number of seconds to break..." << passwordSeconds << endl;
cout << "Converted to minutes..." << passwordMin << endl;
passwordMin = passwordSeconds / SECONDS_IN_MIN;
passwordSeconds = passwordSeconds % SECONDS_IN_MIN;
cout << "Converted to hours..." << passwordHour << endl;
passwordHour = passwordSeconds / SECONDS_IN_HOUR;
passwordSeconds = passwordSeconds % SECONDS_IN_MIN;
cout << "Converted to days..." << passwordDay << endl;
passwordDay = passwordSeconds / SECONDS_IN_DAY;
passwordSeconds = passwordSeconds % SECONDS_IN_DAY;
cout << "Converted to years..." << passwordYear << endl;
passwordYear = passwordSeconds / SECONDS_IN_YEAR;
passwordSeconds = passwordSeconds % SECONDS_IN_YEAR;
return (0);
}
"nan" stands for "not a number". This is happening because you have declared the variables characterSymbols and passwordLength without giving them an initial value.
You must initialize any variable before you use it - if you don't then you will have undetermined behavior. For example:
int x;
int y;
int z = x + y;
There is no way to predict what z will be equal to here because we don't know what x or y are equal to. In the same way, your code should be something like:
int characterSymbols = 10; //or whatever you want the initial value to be
...
double numeratorFactorial = (pow(M_E,-characterSymbols))
*(pow(characterSymbols,characterSymbols))
*(sqrt(2*M_PI*characterSymbols));
In this way, numeratorFactorial will have a valid value.
It appears you think you are declaring "equations" when you are actually declaring variables. You write:
double numeratorFactorial = (pow(M_E,-characterSymbols))
*(pow(characterSymbols,characterSymbols))
*(sqrt(2*M_PI*characterSymbols));
But characterSymbols isn't defined, only "declared". characterSymbols is declared above it, but it doesn't have a value... yet. Later on you use cin to get a value into it, but when you first declare numeratorFactorial you can't simply expect the program to insert the value into numeratorFactorial when characterSymbols changes.
Some definitions are probably in order: The statement double numeratorFactorial = some_value; creates a variable named numeratorFactorial and uses some_value to fill that variable immediately. What you want is a function, a logical statement that you can "pass values" to so values are generated when you need them. For example, for your numerator factorial:
double numeratorFactorial(double characterSymbols) {
return (pow(M_E,-characterSymbols))
*(pow(characterSymbols,characterSymbols))
*(sqrt(2*M_PI*characterSymbols));
}
int main() {
std::cout << "Numerator Factorial test: " << numeratorFactorial(5.0) << std::endl;
}
Note that you cannot declare a function within the main function.
This sort of thing is programming fundamentals, and it seems like you are trying to run before you've learned to walk. Get a good book like C++ Primer and pace yourself.