Possible rounding error? C++ - c++11

I'm still very new to c++, so forgive me if this should is an ignorant question. The purpose of this short code is to calculate a monthly car payment based on 6 user inputs.
Using these inputs, 623.72 is output, however I was expecting 626.81
Inputs, in order: 20000,
0.06,
1000,
100,
0.07,
36.
Can anyone shed any light on why my answer is slightly off? Am I running into a rounding error? Am I rounding in the wrong place or using a wrong variable type?
Thanks!
The formula for monthly payment is broken down into steps which made it easier to write. It's based off this formula:
monthly_payment =
Final_price_minus_downpayment * ( (monthly_rate * (1 + monthly_rate)^num_months / (1 + monthly_rate)^num_months - 1 )
#include <iostream>
#include <iomanip>
#include <cmath>
using std::cout;
using std::cin;
using std::endl;
using std::pow;
using std::fixed;
using std::setprecision;
int main() {
//Initializing the 6 user inputs
double carPrice;
double salesTaxRate;
double downPayment;
double titleAndFees;
double yearlyInterestRate;
double loanDuration;
//Getting the 6 user inputs
cin >> carPrice;
cin >> salesTaxRate;
cin >> downPayment;
cin >> titleAndFees;
cin >> yearlyInterestRate;
cin >> loanDuration;
//Calculate the monthly Payment
double salesTax = carPrice * salesTaxRate;
double totalPrice = carPrice + salesTax;
double finalPriceMinusDown = totalPrice - downPayment;
double monthlyInterestRate = yearlyInterestRate / 12.0;
//Formula broken down into steps
double step1 = pow((1+monthlyInterestRate),loanDuration);
cout << step1 << endl;
double step2 = monthlyInterestRate * step1;
cout << step2 << endl;
double step3 = step1 - 1;
cout << step3 << endl;
double step4 = step2 / step3;
cout << step4 << endl;
double step5 = finalPriceMinusDown * step4;
cout << step5 << endl;
double monthlyPayment = step5;
//cout << "The monthly payment is: ";
cout << fixed << setprecision(2) << monthlyPayment;
}

Related

Incorrect result with cpp_dec_float division

I'm having a problem with boost cpp_dec_float division producing wrong results.
#include <boost/multiprecision/cpp_dec_float.hpp>
#include <iostream>
int main()
{
using namespace boost::multiprecision;
using namespace std;
cpp_dec_float_50 a = 15; // exactly 5 * 3
cpp_dec_float_50 b = 3;
cpp_dec_float_50 c = a / b; // should be exactly 5
cpp_dec_float_50 d = 5;
cout << setprecision(std::numeric_limits<cpp_dec_float_50>::max_digits10);
cout << "c: " << c << endl;
cout << "d: " << d << endl;
cout << "c == d: " << (c == d ? "true" : "false") << endl;
return 0;
}
This produces
c: 4.999999999999999999999999999999999999999999999999999999999999999999999995
d: 5
c == d: false
I saw this question which discusses it for a fractional result. While some comments there were trying to explain it as an effect of truncation, that was not convincing IMO.
And in my case, all values, including the result, are integers, so if there is a decimal arithmetic performed, no truncation should happen.
Any ideas to make boost produce the correct/expected results?

Trying to add fractions while also printing LCD

I'm a beginner trying to figure out this program of adding fractions while also making their output print the result in it's lowest common denominator form. Running it in this form never runs properly...
using namespace std;
class Fraction { //Creates class Fraction
private: //Makes data members private
int num;
int denm;
};
int main()
{
int num;
int denm;
int num2;
int denm2;
int plus;
int plus2;
cout << "Please enter the numerator and denominator of the first fraction: " << endl;
cin >> num >> denm;
cout << "Please enter the numerator and denominator of the second fraction: " << endl;
cin >> num2 >> denm2;
plus = num*denm2 + denm*num2;
plus2 = denm*denm2;
cout << num << "/" << denm << " + " << num2 << "/" << denm2 << " = " << plus << "/" << plus2;
cout << "Hit 'enter' to exit..." << endl;
}
You'll need to run the program in a fashion that keeps the output window open or modify it to accomplish this. See here for examples:
How to keep the console window open in Visual C++?
One way to do this in any environment would be to cin another value before the final return 0 - this would, of course, require you to press something other than enter first, but it serves the purpose.

Linear interpolation is not working as expected

I have a map that represents the values of a coefficient Y for a given range of temperatures. I'm trying to get the coeff_Y whenever the input key designTempfalls anywhere between the upper and lower limits of keys. I was able to get the three cases: a) when the value of the input designTemp is below the first key then coeff_Y is the first value, b) if the value of the input designTemp is beyond the last key then coeff_Y is the last value and c) if designTemp matches a key then the coeff_Y becomes the corresponding value. The case if the key falls anywhere within the key range is not working. The code showing the failed attempt of interpolation is shown below. Please note that I'm not a programmer, I'm a piping engineer just trying to write my own programs and trying to become proficient at coding with C++. Also, if there is any better solution please show so.
`cout << "\n Enter design temp. in degF: ";
float designTemp;
cin.clear(); cin.ignore(10000, '\n'); cin >> designTemp;
map<float, float> ferriticsteels_Y = { {900, 0.4}, {950, 0.5}, {1000, 0.7} };
if (ferriticsteels_Y.find(designTemp) != ferriticsteels_Y.end())
{
float coeff_Y = ferriticsteels_Y[designTemp];
cout << "\n Y: " << coeff_Y << endl;
}
if (designTemp < ferriticsteels_Y.begin()->first)
{
float coeff_Y = ferriticsteels_Y.begin()->second;
cout << "\n Y: " << coeff_Y << endl;
}
if (designTemp > ferriticsteels_Y.rbegin()->first)
{
float coeff_Y = ferriticsteels_Y.rbegin()->second;
cout << "\n Y: " << coeff_Y << endl;
}
auto lower = ferriticsteels_Y.lower_bound(designTemp) == ferriticsteels_Y.begin() ? ferriticsteels_Y.begin() : --(ferriticsteels_Y.lower_bound(designTemp));
auto upper = ferriticsteels_Y.upper_bound(designTemp);
float coeff_Y = lower->second + (upper->second - lower->second) * float(designTemp - lower->first)/fabs(upper->first - lower->first);
time_t rawtime_end;
struct tm * timeinfo_end;
time(&rawtime_end);
timeinfo_end = localtime(&rawtime_end);
cout << "\n" << asctime(timeinfo_end);
cout << "\nEnter any character and hit enter to exit: ";
char ans;
//cin.clear(); cin.ignore(numeric_limits<streamsize>::max(), '\n'); cin >> ans;...giving error at 'max()'
cin.clear(); cin.ignore(10000, '\n'); cin >> ans;
return 0;}`
It works. I just was making stupid mistake. It only required to revise the nesting of the if-statements and to add a cout for looking the interpolated value at the last else. Below is the code which works as expected:
#include "../../std_lib_facilities.h"
#include <Windows.h>
#include <map>
int main()
{
SetConsoleTitle(TEXT("PipeTran™_v0.1"));
system("CLS");
system("color F1");
time_t rawtime_start;
struct tm * timeinfo_start;
time(&rawtime_start);
timeinfo_start = localtime(&rawtime_start);
printf(asctime(timeinfo_start));
cout << "\n Enter design temp. in degF: ";
float designTemp;
cin >> designTemp;
map<float, float> ferriticsteels_Y = { { 900, 0.4 },{ 950, 0.5 },{ 1000, 0.7 } };
if (ferriticsteels_Y.find(designTemp) != ferriticsteels_Y.end()) {
float coeff_Y = ferriticsteels_Y[designTemp];
cout << "\n Y: " << coeff_Y << endl;
}
else if (designTemp < ferriticsteels_Y.begin()->first) {
float coeff_Y = ferriticsteels_Y.begin()->second;
cout << "\n Y: " << coeff_Y << endl;
}
else if (designTemp > ferriticsteels_Y.rbegin()->first) {
float coeff_Y = ferriticsteels_Y.rbegin()->second;
cout << "\n Y: " << coeff_Y << endl;
}
else {
auto lower = ferriticsteels_Y.lower_bound(designTemp) == ferriticsteels_Y.begin() ? ferriticsteels_Y.begin() : --(ferriticsteels_Y.lower_bound(designTemp));
auto upper = ferriticsteels_Y.upper_bound(designTemp);
float coeff_Y = lower->second + (upper->second - lower->second) * float(designTemp - lower->first) / fabs(upper->first - lower->first);
cout << "\n Y: " << coeff_Y << endl;
}
time_t rawtime_end;
struct tm * timeinfo_end;
time(&rawtime_end);
timeinfo_end = localtime(&rawtime_end);
cout << "\n" << asctime(timeinfo_end);
cout << "\nEnter any character and hit enter to exit: ";
char ans;
cin.clear(); cin.ignore(10000, '\n'); cin >> ans;
return 0;
}

How to use SetConsoleTextAttribute C++

I have searched countless forums and websites but I can't seem to find the answer. I'm trying to use SetConsoleTextAttribute but it only affects the text. How can I affect the whole screen like the command color 1f would? My code is:
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <wincon.h>
using namespace std;
int main()
{
SetConsoleTitle("C++ CALCULATOR"); // Title of window
int x; // Decision
int a; // First Number
int b; // Second Number
int c; // Answer
HANDLE Con;
Con = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleTextAttribute(Con, BACKGROUND_BLUE | FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED);
cout << "CALCULATOR" << endl << endl;
cout << "1:ADDITION" << endl << "2:SUBTRACTION" << endl << "3:MULTIPLICATION";
cout << endl << "4:DIVISION" << endl << "5:EXIT" << endl;
cin >> x;
switch (x)
{
case 1: // Addition code
cout << endl << "ADDITION" << endl << "FIRST NUMBER:";
cin >> a;
cout << endl << "SECOND NUMBER:";
cin >> b;
c = a + b;
cout << endl << "ANSWER:" << c;
break;
case 2: // Subtraction code
cout << endl << "SUBTRACTION" << endl << "FIRST NUMBER:";
cin >> a;
cout << endl << "SECOND NUMBER:";
cin >> b;
c = a - b;
cout << endl << "ANSWER:" << c;
break;
case 3: // Multiplication code
cout << endl << "MULTIPLICATION" << endl << "FIRST NUMBER:";
cin >> a;
cout << endl << "SECOND NUMBER:";
cin >> b;
c = a * b;
cout << endl << "ANSWER:" << c;
break;
case 4: // Division code
cout << endl << "DIVISION" << endl << "FIRST NUMBER:";
cin >> a;
cout << endl << "SECOND NUMBER:";
cin >> b;
c = a / b;
cout << endl << "ANSWER:" << c;
break;
case 5: // Exit code
return 0;
}
}
This solution relies on these WinAPI functions and structures:
GetConsoleScreenBufferInfo to get screen dimensions
FillConsoleOutputAttribute to fill screen with an attribute
CONSOLE_SCREEN_BUFFER_INFO structure to store screen information
The code is as follows:
HANDLE hCon;
CONSOLE_SCREEN_BUFFER_INFO csbiScreenInfo;
COORD coordStart = { 0, 0 }; // Screen coordinate for upper left
DWORD dwNumWritten = 0; // Holds # of cells written to
// by FillConsoleOutputAttribute
DWORD dwScrSize;
WORD wAttributes = BACKGROUND_BLUE | FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED;
hCon = GetStdHandle(STD_OUTPUT_HANDLE);
// Get the screen buffer information including size and position of window
if (!GetConsoleScreenBufferInfo(hCon, &csbiScreenInfo))
{
// Put error handling here
return 1;
}
// Calculate number of cells on screen from screen size
dwScrSize = csbiScreenInfo.dwMaximumWindowSize.X * csbiScreenInfo.dwMaximumWindowSize.Y;
// Fill the screen with the specified attribute
FillConsoleOutputAttribute(hCon, wAttributes, dwScrSize, coordStart, &dwNumWritten);
// Set attribute for newly written text
SetConsoleTextAttribute(hCon, wAttributes);
The inline comments should be enough to understand the basics of what is going with the supplied documentation links. We get the screen size with GetConsoleScreenBufferInfo and use that to determine the number of cells on the screen to update with a new attribute using FillConsoleOutputAttribute . We then use SetConsoleTextAttribute to ensure that all new text that gets printed matches the attribute we used to color the entire console screen.
For brevity I have left off the error check for the calls to FillConsoleOutputAttribute and SetConsoleTextAttribute. I put a stub for the error handling for GetConsoleScreenBufferInfo . I leave it as an exercise for the original poster to add appropriate error handling if they so choose.
SetConsoleTextAttribute changes the attribute for new characters that you write to the console, but doesn't affect existing contents of the console.
If you want to change the attributes for existing characters already being displayed on the console, use WriteConsoleOutputAttribute instead.

OpenCV perspectiveTransform broken function

Im trying to use perspectiveTransform but I keep getting error. I tried to follow the solution from this thread http://answers.opencv.org/question/18252/opencv-assertion-failed-for-perspective-transform/
_players[i].getCoordinates() is of type Point
_homography_matrix is a 3 x 3 Mat
Mat temp_Mat = Mat::zeros(2, 1, CV_32FC2);
for (int i = 0; i < _players.size(); i++)
{
cout << Mat(_players[i].get_Coordinates()) << endl;
perspectiveTransform(Mat(_players[i].get_Coordinates()), temp_Mat, _homography_matrix);
}
Also, how do I convert temp_Mat into type Point ?
OpenCV Error: Assertion failed (scn + 1 == m.cols) in cv::perspectiveTransform
Basically you just need to correct from
Mat(_players[i].get_Coordinates()) ...
to
Mat2f(_players[i].get_Coordinates()) ...
In the first case you are creating a 2x1, 1 channel float matrix, in the second case (correct) you create a 1x1, 2 channel float matrix.
You also don't need to initialize temp_Mat.
You can also use template Mat_ to better control the types of your Mats. E.g. creating a Mat of type CV_32FC2 is equivalent to create a Mat2f.
This sample code will show you also how to convert back and forth between Mat and Point:
#include <opencv2\opencv.hpp>
#include <vector>
using namespace std;
using namespace cv;
int main()
{
// Some random points
vector<Point2f> pts = {Point2f(1,2), Point2f(5,10)};
// Some random transform matrix
Mat1f m(3,3, float(0.1));
for (int i = 0; i < pts.size(); ++i)
{
cout << "Point: " << pts[i] << endl;
Mat2f dst;
perspectiveTransform(Mat2f(pts[i]), dst, m);
cout << "Dst mat: " << dst << endl;
Point2f p(dst(0));
cout << "Dst point: " << p << endl;
}
return 0;
}

Resources