Output is a trash value when high precision is required in C++ - c++

I have this code-snippet as part of a bigger program. I've searched the Web for finding a solution for my code and used long float, long double, long long int and also setprecision(10), but no success!
In this code I'm going to put that floating point number (0.000098765) into the stringstream ss;(for some purpose) and then put it to output, but when I run the code, a trash value (very very big) will be shown that is clear to be wrong.
It's as bellow:
How to solve my problem please?
int main()
{
stringstream ss;
int temp = 0;
long double d = 0.000098765;
long int n = d;
long double r = d - n;
ss << n;
if (d > n)
{
if (r < 0.0001)
{
ss << '.';
do {
r *= 10;
if (r < 1)
ss << 0;
else
{
temp = r;
ss << temp;
r -= temp;
}
} while (r != 0);
}
}
cout << setprecision(10) << ss.str() << endl;
system("pause");
return 0;
}

Try something like this:
#include <iostream>
#include <iomanip>
using namespace std;
// ...
long double d = 0.000098765;
// ...
stringstream ss2;
ss2 << setprecision(10) << fixed << d;
cout << ss2.str() << endl;
The manipulators operate on the thing fed to the stream, which in your case was a string -- and so 'setprecision' had no effect.
Note also that the 'fixed' manipulator makes the output fixed width, not scientific notation.

Related

C++ That Is Plaguing Me To This Day

What is the correct solution?
What is the correct solution?
What is the correct solution?
My Code (which is obviously wrong):
<iostream> and <fstream> libraries are included.
int main() {
int num = 0;
int totalCount = 0;
std::ifstream inFile;
double average = 0.0;
int totalTwo = 0;
double total = 0.0;
const double VALUE_ONE = 858.5;
std::cout << "What is the number? ";
std::cin >> num;
std::cout << std::endl;
inFile.open("numbers.txt");
while (inFile >> num) {
totalCount += num;
}
total = num * VALUE_ONE;
average = total/totalCount;
totalTwo = total * num;
inFile.close();
return 0;
}
numbers.txt
When you do this:
std::cin >> num;
std::cout << std::endl;
inFile.open("numbers.txt");
while (inFile >> num) {
totalCount += num;
}
you're reading into num and then immediately overwriting it with data from the input file. Use two variables for the two inputs.
Your code doesn't really match what the instructions say to do.
You are reading the user's chosen multiplier into num, and then you are reading the numbers from the text file into num as well, losing the multiplier. And you are not keeping track of how many numbers are read from the file, which you need in order to calculate the average.
You need to add a few more variables to your code to separate things. Also, there is no need for your VALUE_ONE constant at all.
Try something more like this:
#include <iostream>
#include <fstream>
int main()
{
int multiplier = 0;
int total = 0, totalTwo = 0;
int quantity = 0;
int num = 0;
double average = 0.0;
std::cout << "After all numbers are read, what number would you like to multiply the total by? ";
std::cin >> multiplier;
std::cout << std::endl;
std::ifstream inFile("numbers.txt");
while (inFile >> num) {
total += num;
++quantity;
}
inFile.close();
average = double(total) / quantity;
totalTwo = total * multiplier;
std::cout << "Total = " << total << "\n" << "Average = " << average << "\n" << "Total * " << multiplier << " = " << totalTwo;
return 0;
}
Live Demo

C++ Mastermind For Loop

Edit
I've included #include <sstream> now. This helped. But still an issue displaying the correct information. I've stepped it out, and it has to deal with some sort of program error. I have the text file already made inside of the same folder path. I've tried setting it to a direct C:/ path such as
C:\Users\Matt\Documents\Visual Studio 2015\Projects\listofcolors.txt
I'm having problem opening my file and displaying data. I recently downloaded Microsoft Visual Basic C++ to write the program I need for Mastermind. My goal is to create numbers that represent 9 to the 5th and put them within a text file. (Essentially, 5 columns of 9 numbers, 9 I've written this so far.
#include <iostream>
#include <fstream>
#include <sstream>
using namespace std;
int main() {
int a = 0;
int b = 0;
int c = 0;
int d = 0;
int e = 0;
std::string result;
std::stringstream sstm;
ofstream myfile;
myfile.open("listofcolors.txt");
if (myfile.is_open())
{
for (a = 0; a<9; a++) {
sstm << a << b << c << d << e;
result = sstm.str();
myfile << result << '\n';
for (b = 0; b<9; b++) {
sstm << a << b << c << d << e;
result = sstm.str();
myfile << result << '\n';
for (c = 0; c<9; c++) {
sstm << a << b << c << d << e;
result = sstm.str();
myfile << result << '\n';
for (d = 0; d<9; d++) {
sstm << a << b << c << d << e;
result = sstm.str();
myfile << result << '\n';
for (e = 0; e<9; e++) {
sstm << a << b << c << d << e;
result = sstm.str();
myfile << result << '\n';
}
}
}
}
myfile.close();
return 0;
}
}
else cout << "Unable to open file";
return 0;
}
For some reason, nothing is outputted. Any ideas??? Thank you!!
We can get clever by borrowing this arbitrary base conversion code that will output numbers in base 9 - see the cout version online here:
#include <iostream>
#include <iomanip>
#include <fstream>
#include <algorithm>
using namespace std;
/**
* C++ version 0.4 std::string style "itoa":
* Contributions from Stuart Lowe, Ray-Yuan Sheu,
* Rodrigo de Salvo Braz, Luc Gallant, John Maloney
* and Brian Hunt
*/
std::string itoa(int value, int base) {
std::string buf;
// check that the base if valid
if (base < 2 || base > 16) return buf;
enum { kMaxDigits = 35 };
buf.reserve( kMaxDigits ); // Pre-allocate enough space.
int quotient = value;
// Translating number to string with base:
do {
buf += "0123456789abcdef"[ std::abs( quotient % base ) ];
quotient /= base;
} while ( quotient );
// Append the negative sign
if ( value < 0) buf += '-';
std::reverse( buf.begin(), buf.end() );
return buf;
}
int main() {
ofstream myfile("listofcolors.text");
if (myfile.is_open())
{
for (int i = 0; i <= 9 * 9 * 9 * 9 * 9; i++)
{
// Formats the number to five places, filled with leading zeroes
myfile << setw(5) << setfill('0') << itoa(i, 9) << '\n';
}
myfile.close();
}
else
cout << "Unable to open file";
return 0;
}
Note that the file is created in the working directory; here is how to check and set where it is.
Also note that your code had the myfile.close() inside the first loop, so it would only have printed from 00000 to 08888.
Finally, since you are on Windows, use File Explorer to search for listofcolors.txt, just in case it is being created in an unexpected location.
On Windows, text files have a .txt file extension, not .text. Also, you are creating the file using a relative path, so it will be created in the process's current working directory, which may not be what you are expecting it to be. Always use absolute paths.
Your loop code is unnecessarily complex, it can be simplified to something more like this:
#include <iostream>
#include <fstream>
using namespace std;
int main() {
ofstream myfile("C:\\some path\\listofcolors.txt", ios_base::trunc);
if (myfile.is_open())
{
for (int a = 0; a < 9; a++)
for (int b = 0; b < 9; b++)
for (int c = 0; c < 9; c++)
for (int d = 0; d < 9; d++)
for (int e = 0; e < 9; e++) {
if (!(myfile << a << b << c << d << e << '\n')) {
cout << "Unable to write to file";
return 0;
}
}
myfile.close();
cout << "File created";
}
else
cout << "Unable to create file";
return 0;
}

ifstream, getline, and istringstream slow performance on big file in c++

I want to ask about my code below: (The code below basically read an input file named inputVelocity.dat with format stated in the code. The code reads with istringstream to pass each value to each particular arrays)
std::ifstream inputVelocity("input/inputVelocity.dat");
std::string lineInputVelocity;
while (std::getline(inputVelocity, lineInputVelocity)) {
std::istringstream issVelocity(lineInputVelocity);
double a, b, c, d, e;
if (!(issVelocity >> a >> b >> c >> d >> e)) {
std::cout << "ISS ERROR" << std::endl;
}
for (int k=0; k<=nz+1; k++) {
for (int j=0; j<=ny+1; j++) {
for (int i=0; i<=nx+1; i++) {
ux[i][j][k] = a;
uy[i][j][k] = b;
uz[i][j][k] = c;
pressure[i][j][k] = d;
temperature[i][j][k] = e;
}
}
}
}
inputVelocity.close();
The code is fine when reading around 20000 lines, but when I change the file into around 1.6 million lines, the code run very slow even on a server.
I did std::cout on each getline loop and it read like 5 lines/second, with around 1.6 million lines.
I have found some related questions here but still can't understand what's the problem source and how to fix it. Anyone can help?
Thank you.
I changed the code into this:
std::ifstream inputVelocity("input/inputVelocity.dat");
std::string lineInputVelocity;
int getI, getJ, getK;
getI = 0;
getJ = 0;
getK = 0;
while (std::getline(inputVelocity, lineInputVelocity)) {
std::istringstream issVelocity(lineInputVelocity);
double a, b, c, d, e;
if (!(issVelocity >> a >> b >> c >> d >> e)) {
std::cout << "ISS ERROR" << std::endl;
}
std::cout << getI << " " << getJ << " " << getK << std::endl;
ux[getI][getJ][getK] = a;
uy[getI][getJ][getK] = b;
uz[getI][getJ][getK] = c;
pressure[getI][getJ][getK] = d;
temperature[getI][getJ][getK] = e;
getK = getK + 1;
if (getK == nz+2) {
getJ = getJ + 1;
getK = 0;
}
if (getJ == ny+2) {
getI = getI + 1;
getJ = 0;
}
}
inputVelocity.close();
And that worked really well :)
If anyone has a more efficient solution, I would be very glad to see! :)

Using strtol to get long double in c++

I am trying to get the long double out of an array.
long double num;
char * pEnd;
char line[] = {5,0,2,5,2,2,5,4,5,.,5,6,6};
num = strtold(line1, &pEnd);
For some reason the num i am getting is rounded to 502522545.6
I am quite new to C++ so is there something i am doing wrong ? What needs to be done to get the entire number in the num instead of the rounded up?
Thank you for the help !!!
Sorry that's my first post here =)
So the entire program code is as following :
class Number
{
private:
long double num ;
char line[19], line2[19];
int i, k;
public:
Number()
{}
void getData()
{
i = 0;
char ch= 'a';
cout << "\nPlease provide me with the number: ";
while ((ch = _getche()) != '\r')
{
line[i] = ch;
line2[i] = ch;
i++;
}
}
void printData() const
{
cout << endl;
cout << "Printing like an Array: ";
for (int j = 0; j < i; j++)
{
cout << line[j];
}
cout << "\nModified Array is: ";
for (int j = 0; j < (i-k); j++)
{
cout << line2[j];
}
cout << "\nTHe long Double is: " << num;
}
void getLong()
{
char * pEnd;
k = 1;
for (int j = 0; j < i; j++)
{
if (line2[j+k] == ',')
{
k++;
line2[j] = line2[j + k];
}
line2[j] = line2[j + k];
}
line2[i -k] = line2[19];
num = strtold(line2, &pEnd);
}
};
int main()
{
Number num;
char ch = 'a';
while (ch != 'n')
{
num.getData();
num.getLong();
num.printData();
cout << "\nWould you like to enter another number ? (y/n)";
cin >> ch;
}
return 0;
}
The idea is that the number entered is in the following format ($50,555,355.67) or any other number. The program then removes all signs apart of numbers and "."
Then i tried to get the long double num out of an array.
If you run the program you always get the rounded number from num.
The C++ way of doing this is pretty simple:
#include <sstream>
#include <iostream>
#include <iomanip>
int main() {
const std::string line = "502522545.566";
long double num;
std::istringstream s(line);
s >> num;
std::cout << std::fixed << std::setprecision(1) << num << std::endl;
}
Using modern C++ you can simply do:
auto line = "502522545.566"s;
auto num = std::stold(line);
Live example
Theres probably a more C++ way, but sscanf will work:
const char *str = "3.1459";
long double f;
sscanf(str, "%Lf", &f);

Having trouble with converting a decimal number to a binary

I'm making a program that converts a string that the user enters such as "APPLE" into a binary number through the corresponding ASCII numbers that represent each character of the string "APPLE." For example A = 65 in ascii etc.. I've created a function that converts the string into a binary but it doesn't seem to be working. It displays "The equivalent binary number is: 0031F240for A" in an infinite loop and gives me "0031F240for" instead of being in the binary version of 65. I know this function works for converting a decimal number into binary because I've tried it, but I think my implementation of the bin[] array is messing things up. Any help would be appreciated.
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <string>
#include <fstream>
using namespace std;
class RandomString
{
private:
string input;
string bin[100];
public:
RandomString() : bin(), input("")
{
}
void getData()
{
cout << "Enter the word to be encoded into a binary file.";
cin >> input;
}
void numToBin()
{
int i = 0;
int len = input.length();
int num = int(input[i]);
for(int i = 0; i < len; i++)
{
while(num != 0)
{
if (num % 2 == 0)
bin[i].insert(0, "0");
else
bin[i].insert(0, "1");
num = num / 2;
cout << "The equivalent binary number is: " << bin << "for " << input[i] << endl;
}
}
}
void display()
{
}
};
I haven't test if the result is correct but this code convert a string to binary. Probably you have to modify it to fit with ASCII codes.
void DecimalToBinary(char a,std::vector<char>& v)
{
if(a==0)
v.push_back(0);
if(a==1)
v.push_back(1);
else
{
v.push_back(a%2);
DecimalToBinary(a/2,v);
}
}
int main()
{
std::vector<char> v;
std::string line;
getline(std::cin,line);
std::istringstream input(line);
char c;
while(input >> c)
{
DecimalToBinary(c,v);
}
std::copy(v.begin(),v.end(),std::ostream_iterator<int>(std::cout,""));
}
First Your while loop never stops because you don't change the value of i inside the while loop, so int(input[i]) has always the same value, you have to use break somewhere or i++, but I don't know if the result is correct,I think recursion is better than while in this situation, but anyway try the following:
void numToBin()
{
int i = 0;
int len = input.length();
int num = int(input[i]);
for(int i = 0; i < len; i++)
{
while(int(input[i]) != 0)
{
if (num % 2 == 0)
{
bin[i].insert(0, "0");
break;
}
else
{
bin[i].insert(0, "1");
num = num / 2;
}
cout << "The equivalent binary number is: " << bin << "for " << input[i] << endl;
}
}
}
Second, doing std::cout << bin you print a memory address, not the contents of the bin.
while(int(input[i]) != 0)
{
if (num % 2 == 0)
bin[i].insert(0, "0");
else
{
bin[i].insert(0, "1");
}
num = num / 2;// this line should be in both case.
cout << "The equivalent binary number is: " << bin << "for " << input[i] << endl;
}
I've changed num = num / 2 for both cases. Please check it.
You may want to change the 'bin' in
cout << "The equivalent binary number is: " << bin
to 'bin[i]'.
Because 'bin' is a string array, also the pointer/address to the string array, so 'cout << bin' will always output the address.