floats getting rounded to 1 decimal by C++ - c++

I'm writting a C++ program that takes user input and put it inside a file. In this case, it takes in a number (eg. 299.99), but C++ rounds it to 300 (used to be doubles) when using doubles and floats 299.9...
My code:
void Bank::deposit(){
std::cout << "You currently have " << getBalance() << " in your account.\nHow much would you like to deposit? Amount: ";
float amount = optionExists(amount);
if(amount < 1){
std::cout << "Invalid Amount!" << std::endl;
deposit();
}
float moneyInBank = getBalance();
setBalance(moneyInBank + amount);
std::cout << "Your balance of " << moneyInBank << " has been increased to " << getBalance() << std::endl;
std::string theLine = getUsername() + "," + getPassword() + "," + getAccountType() + "," + std::to_string(moneyInBank) + "," + std::to_string(getAdmin());
updateFile(theLine, getUsername(), getPassword(), getAccountType(), getBalance(), (getAdmin()));
displayMenu();
}
When I call the getBalance() method it also returns a float, but as I said, only to one decimal...
Here is a snippet from the text file:
[name,password,type,BALANCE,admin]
lisa,mag24#773,C,24.99,0 ---> What I want (manually entered)
lols,23456,L,30,1 ---> What I got when using doubles
mark,passw0rd,S,24509.9,1 ---> What I got when using floats
Extra Notes: I compile using cmake and code with VSCode

This link may help [link][1]
float iBalance = getBalance();
std::cout<< std::setprecision(2)<<iBalance<< endl;
[1]: https://stackoverflow.com/questions/5907031/printing-the-correct-number-of-decimal-points-with-cout#:~:text=You%20have%20to%20set%20the%20'float%20mode'%20to%20fixed.&text=To%20set%20fixed%202%20digits,ios%3A%3Afixed)%3B%20cout.

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.

c++ why am I getting junk outputting an array?

Here's the code:
#include "stdafx.h"
#include <iostream>
using namespace std;
int main()
{
int keyArray[7] = {1,2,3,4,5,6,7};
int breakPoint;
int counter;
for (counter = 0; counter < 7; counter++)
{
// keyArray[counter] = (rand() % 9) + 1; later
keyArray[counter] = counter; //testing
}
cout << keyArray[0] + "\n";
cout << keyArray[1] + "\n";
cout << keyArray[2] + "\n";
cout << keyArray[3] + "\n";
cout << keyArray[4] + "\n";
cout << keyArray[5] + "\n";
cout << keyArray[6] + "\n";
cin >> breakPoint; //so I can see what the hell is going on before it disappears
return 0;
}
The only reason I gave values to keyArray was that I read in answer to a similar question that you have to initialize an array with data before you use it. But it made no difference. The output is just junk symbols whether you initialize or not.
The compiler is Visual Studio Community 2017. Thanks for any help.
The error is not in your logic but rather in your debugging output. Since the other answers focus on how to fix it, I'll rather explain what happens instead. There seems to be a misunderstanding about the way strings work in C++.
The failure is in this operation:
keyArray[0] + "\n"
Internally, string literals are arrays of characters, in this case const char[2], consisting of the newline and a terminating '\0' null terminator. When you then try to add the integer and this array together, the array will be represented by a pointer to its first element, i.e. it will decay to const char* in order to be used as the second argument to the plus operator used in your code.
So for the compiler, this line will need operator+(int, const char*). But the result of that will be const char*, the input pointer offset by the integer, as that is the operation that happens when adding integers to pointers.
So instead of printing the number and then the string, it will try to access a string that does not exist as the pointer now pointer behind the string "\n" and thus into some arbitrary memory.
Instead of doing
cout << keyArray[0] + "\n"
do:
cout << keyArray[0] << "\n"
or
cout << keyArray[0] << endl
You can't concatanate an integer with a string. That's why you got garbage output
Try this first:
cout << keyArray[0] << "\n";
If you are using compilers that support C++ 11 then try using std::to_string(...) to make a string from an integer before doing the addition:
cout << (std::to_string(keyArray[0]) + "\n");
you cannot concatenate int with string.
change
cout << keyArray[0] + "\n";
cout << keyArray[1] + "\n";
cout << keyArray[2] + "\n";
cout << keyArray[3] + "\n";
cout << keyArray[4] + "\n";
cout << keyArray[5] + "\n";
cout << keyArray[6] + "\n";
to
cout << keyArray[0] << "\n"
<< keyArray[1] << "\n"
<< keyArray[2] << "\n"
<< keyArray[3] << "\n"
<< keyArray[4] << "\n"
<< keyArray[5] << "\n"
<< keyArray[6] << endl;
You need to convert the integers into a string. Using a relatively recent version of C++:
#include "stdafx.h"
#include <iostream>
using namespace std;
int main()
{
int keyArray[7] = {1,2,3,4,5,6,7};
int breakPoint;
int counter;
for (counter = 0; counter < 7; counter++)
{
// keyArray[counter] = (rand() % 9) + 1; later
keyArray[counter] = counter; //testing
}
cout << std::to_string(keyArray[0]) + "\n";
cout << std::to_string(keyArray[1]) + "\n";
cout << std::to_string(keyArray[2]) + "\n";
cout << std::to_string(keyArray[3]) + "\n";
cout << std::to_string(keyArray[4]) + "\n";
cout << std::to_string(keyArray[5]) + "\n";
cout << std::to_string(keyArray[6]) + "\n";
cin >> breakPoint; //so I can see what the hell is going on before it disappears
return 0;
}

C++ How do I create a timestamped directory using a filepath held in a string?

I am trying to set up a program which can create a new directory every time it is used to fill with data. I want the name of the folder to be a timestamp of when it was created. I have already written a function which creates the timestamp and returns it as a string.
string timestamp() {
//create a timecode specific folder
// current date/time based on current system
time_t now = time(0);
struct tm timeinfo;
localtime_s(&timeinfo, &now);
// print various components of tm structure.
cout << "Year: " << 1900 + timeinfo.tm_year << endl;
int Y = 1900 + timeinfo.tm_year;
cout << "Month: " << 1 + timeinfo.tm_mon << endl;
int M = 1 + timeinfo.tm_mon;
cout << "Day: " << timeinfo.tm_mday << endl;
int D = timeinfo.tm_mday;
cout << "Time: " << 1 + timeinfo.tm_hour << ":";
int H = timeinfo.tm_hour;
cout << 1 + timeinfo.tm_min << ":";
int Mi = timeinfo.tm_min;
cout << 1 + timeinfo.tm_sec << endl;
int S = 1 + timeinfo.tm_sec;
string timestampStr;
stringstream convD, convM, convY, convH, convMi, convS;
convD << D;
convM << M;
convY << Y;
convH << H;
convMi << Mi;
convS << S;
cout << "Timestamp:" << endl;
timestampStr = convD.str() + '.' + convM.str() + '.' + convY.str() + '-' + convH.str() + ':' + convMi.str() + ':' + convS.str();
cout << timestampStr << endl;
return timestampStr;
}
This bit works fine and gives me a string with the current timestamp. I also have a second string with the path to the folders location which I combine to give the full path and new folder name in a string eg "C:\\Users\\Daniel\\Documents\\VS17\\25.5.2017-16:47:51"
I know I can use
CreateDirectory(direc, NULL);
to make a directory when I have a file path like the one held in my string but in LPCWSTR format. So really my question is
How do I convert my string into a LPCWSTR format to use in CreateDirectory
Is there some other way I am just missing
Since your folder path string is a char based string, just use CreateDirectoryA() directly, instead of using the TCHAR based CreateDirectory() (which clearly is being mapped to CreateDirectoryW() in your project), eg:
string direc = "C:\\Users\\Daniel\\Documents\\VS17\\" + timestamp();
CreateDirectoryA(direc.c_str(), NULL);

Formatting stream spaces

I have been trying to use .pushback to format my string so that it prints just a space between every word.
So I was trying to use a .push_back, however that doesn't work with integers.
std::string FormatVehicleString(std::string year,
std::string make,
std::string model,
double price,
double mileage)
{
year.push_back(5);
make.push_back(5);
model.push_back(5);
price.push_back(5);
mileage.push_back(5);
}
Can someone point me in the right direction, is there another value type that will incorporate strings and integers?
One option is to use a std::ostringstream.
std::string FormatCarInfo(std::string year,
std::string make,
std::string model,
double price,
double mileage)
{
std::ostingstream out;
out << year << " ";
out << make << " ";
out << model << " ";
out << price << " ";
out << mileag ;
return out.str();
}
Another option is to use std::to_string.
std::string FormatCarInfo(std::string year,
std::string make,
std::string model,
double price,
double mileage)
{
return ( year + " " + make + " " + model + " " +
std::to_string(price) + " " + std::to_string(mileage) );
}

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.