Reading double from file - c++

For my homework I should read double values from a file and sort them. These are the some of the values. But when read them with my code, when a print it for testing they are written in integer form.
std::ifstream infile (in_File);
double a;
while(infile>>a)
{
std::cout<<a<<std::endl;
}
My doubles are started with 185261.886524 then 237358.956723
And my code print the 185262 then 237359 then so on.

Try adding this at the top of your main():
setlocale(LC_ALL, "C");
This will give your program the "C" locale instead of your local one. I imagine your local one uses "," as a decimal point instead of "." as in your data.
You will need to add #include <clocale> at the top of your file as well.
Edit: then, to get more precision, you can do #include <iomanip> and do this at the top of your program:
std::cout << std::setprecision(20);
setprecision changes how many total digits are printed.

Your problem is not the input, but the output: cout by default prints 6 digits of a double, this is why you see the rounded value 185262, not 185261 as you would expect from incorrect input. Use std::setprecision to increase output precision.

This can happen if on your system your localization settings have a different decimal separator than .. Try add the following include:
#include <locale>
and then use the imbue method:
std::ifstream infile (in_File);
infile.imbue(std::locale("C"));
double a;
while(infile>>a)
{
std::cout<<a<<std::endl;
}

Related

Concatenate float with string and round to 2 decimal places

So I have a function below formatted as polymorphic void display(string& outStr). The output from this function should basically be formatted into one large string, which will be saved to the outStr parameter and returned to the calling function.
I have successfully formatted my large string into multiple lines but I would like to round my float value to 2 decimal places but I can't figure out how with the way I'm currently appending my strings. I tried using the round() and ceil() functions as some posts online have suggested, but 6 zeros still appear after each decimal place. I would appreciate some help with this as I've been looking for solutions for a while but none of them have worked.
Additionally, I was wondering if the to_string() function I used to convert my float to a string would compile and execute correctly in C++98? I'm using C++11 but my teacher is using C++98 and I'm extremely worried that it won't compile on her end.
If not, can anyone suggest how else I could achieve the same result of turning a float into a string while still formatting multiple lines into the outStr string parameter and returning it to the function? I am not allowed to change the function's parameters, it must stay as display(string& outStr)
My output is a lot longer and complex but I simplified the example for the sake of getting a short and easy solution.
Again, I would appreciate any help!
#include <iostream>
using namespace std;
#include <string>
#include <sstream>
#include <cmath>
#include "Math.h"
void Math::display(string& outStr){
float numOne = 35;
float numTwo = 33;
string hello = "Hello, your percent is: \n";
outStr.append(hello);
string percent = "Percent: \n";
outStr.append(percent);
float numPercent = ceil(((numOne / numTwo) * 100) * 100.0) / 100.0;
outStr.append(to_string(numPercent));
outStr.append("\n");
}
Output should look like:
Hello, your percent is:
Number:
106.06%
There is no need to do any crazy conversions. Since the function is called display, my guess is that it's actually supposed to display the value instead of just save it to a string.
The following code demonstrates how that can be accomplished by just formatting your printing.
#include <cstdio>
#include <iomanip>
#include <iostream>
int main() {
double percentage = 83.1415926;
std::cout << "Raw: " << percentage << "%\n";
std::cout << "cout: " << std::fixed << std::setprecision(2) << percentage << "%\n";
printf("printf: %.2f\%%\n", percentage); // double up % to print the actual symbol
}
Output is:
Raw: 83.1416%
cout: 83.14%
printf: 83.14%
If the function is as backwards as you describe it, there are two possibilities. You don't understand what's actually required and are giving us a bad explanation (my guess given that function signature), or the assignment itself is pure garbage. As much as SO likes to rag on professors, I find it difficult to believe that what you've described and written is what the professor wants. It makes no sense.
A couple notes: there is nothing polymorhpic about the code you've shown. to_string() exists as of C++11, which is easily seen by looking up the function (Link). There is also a discrepancy between what your code attempts to print versus what your output is, and that's before we even get to the number formatting portion. "Percent" or "Number"?

removing trailing zeroes for a float value c++

I am trying to set up a nodemcu module to collect data from a temperature sensor, and send it using mqtt pubsubclient to my mqtt broker, but that is not the problem.
I am trying to send the temperature in a format that only has one decimal, and at this point I've succesfully made it round up or down, but the format is not right. as of now it rounds the temp to 24.50, 27.80, 23.10 etc. I want to remove the trailing zereos, so it becomes 24.5, 27.8, 23.1 etc.
I have this code set up so far:
#include <math.h>
#include <PubSubClient.h>
#include <ESP8266WiFi.h>
float temp = 0;
void loop {
float newTemp = sensors.getTempCByIndex(0);
temp = roundf((newTemp * 10)) / 10;
serial.println(String(temp).c_str())
client.publish("/test/temperature", String(temp).c_str(), true);
}
I'm fairly new to c++, so any help would be appreciated.
It's unclear what your API is. Seems like you want to pass in the C string. In that case just use sprintf:
#include <stdio.h>
float temp = sensors.getTempCByIndex(0);
char s[30];
sprintf(s, "%.1f", temp);
client.publish("/test/temperature", s, true);
Regardless of what you do to them, floating-point values always have the same precision. To control the number of digits in a text string, change the way you convert the value to text. In normal C++ (i.e., where there is no String type <g>), you do that with a stream:
std::ostrstream out;
out << std::fixed << std::setprecision(3) << value;
std::string text = out.str();
In the environment you're using, you'll have to either use standard streams or figure out what that environment provides for controlling floating-point to text conversions.
The library you are using is not part of standard C++. The String you are using is non-standard.
As Pete Becker noted in his answer, you won't be able to control the trailing zeros by changing the value of temp. You need to either control the precision when converting it to String, or do the conversion and then tweak the resultant string.
If you read the documentation for the String type you are using, there may be options do do one or both of;
control the precision when writing a float to a string; or
examine characters in a String and manually remove trailing zeros.
Or you could use a std::ostrstream to produce the value in a std::string, and work with that instead.

C++ Convert string to float

I am trying to convert a string based number to float. Unfortunately I am getting either the rounded off value or truncated value. How can I fix this.
std::string text = "199102.92";
float v = std::stof(text);
std::cout<<v<<std::endl;
This results in 199103
Even if I use setprecision and fixed then it only affects the output stream but the value passed into the float variable remains 199103. How can i resort this problem.
I have also used stringstream in c++ but results seem to be the same except it just displays off well.
I need to preserve the decimal upto 2 places.
I have used stof,stod, they all do the same thing.
You may assume that I am working with currencies.
I assume that you use std::setprecision and std::fixed incorrectly.
Following works for me:
#include <iostream>
#include <iomanip>
#include <string>
string text = "199102.92";
float v = std::stof(text);
std::cout << std::setprecision(2) << std::fixed << v << std::endl;
The result is 199102.92
Compiler info: g++ 5.4.0, --std=c++11.

How to work with large numbers when writing and reading a file?

I have written a codes to write my data from one input file to another output file, I used to read all lines of my input file
while (!inputfile.eof())
but in my output file, the last line is missing. So I would like to know, how to prevent this error?
My second question is: for writing data into file, I used
Outputfile.write((char*)&a,sizeof(double));
Outputfile.write((char*)&b,sizeof(double));
here a = 289814.150 and b = 4320978.613 but in the output file, it shows like
289814 4.32098e+006
(value of a is rounded and b value shows with e values) so what is the reason for this and how to fixed this problem?
Here i tried to use cout.setf(ios::fixed);, but if this works for data written on the screen, I don’t know how to fix this to write double data inside my file.
I want to write real values with 3 decimals only in my output file. Please anyone can help thanks.
Okay, based on comments, the intent here has (at least I hope) become reasonably clear: to convert pairs of numbers in text format to binary format, and be able to verify that the converted numbers accurately represent the originals.
There are a number of ways to do that, but the first thing to keep in mind is that no matter what else you do, converting floating point numbers to/from text (decimal) format can and normally will lead to some degree of inaccuracy. The problem is fairly simple: floating point is (normally) done in binary. This means it can only represent fractions in which the denominator is a power of 2 (or a sum of powers of 2). Decimal, obviously enough, uses base 10, so fractions can be composed of a sum of powers of 2 and powers of 5. Any of those that involves a power of 2 (e.g., 0.2) can only be approximated in binary -- pretty much like trying to represent 1/3rd in decimal.
This means your only reasonable choice is to allow some discrepancy between the decimal and binary versions. The best you can hope for is to keep the errors to a minimum. To test for that, what you probably need/want to do is convert the binary floating point back to decimal in the original format, and check whether it's close to the original (e.g., ignore errors in the final digit, at least errors of +/- 1).
The conversion itself should be pretty trivial:
#include <fstream>
int main(int argc, char **argv) {
// checking argc omitted for clarity.
std::ifstream infile(argv[1]);
std::ofstream outfile(argv[2], std::ios::binary);
double a, b;
while (infile >> a && infile >> b) {
outfile.write((char const *)&a, sizeof(a));
outfile.write((char const *)&b, sizeof(b));
}
return 0;
}
Verifying the data isn't nearly so easy. One possibility would be something like this (starting from the two files, one binary and one text):
#include <iostream>
#include <fstream>
#include <sstream>
#include <iomanip>
int main(int argc, char **argv) {
std::string text;
std::ostringstream converter;
std::ifstream text_file(argv[1]);
std::ifstream bin_file(argv[2], std::ios::binary);
double bin_value;
while (text_file >> text) {
bin_file.read((char *)&bin_value, sizeof(bin_value));
// the manipulators will probably need tweaking to match original format.
converter << std::fixed << std::setw(3) << std::setprecision(3) << bin_value;
if (converter.str() != text)
;// they're identical
else if (converter.str().substr(0,3) == text.substr(0,3))
;// the first three digits are equal
else
;// bigger error
}
return 0;
}
That's much more likely to need some tweaking to work the way you want, but the general idea should be in the ballpark as long as you're sure the original numbers are all formatted consistently.

Only 2 digits in exponent in scientific ofstream

So according to cplusplus.com when you set the format flag of an output stream to scientific notation via
of.setf(ios::scientific)
you should see 3 digits plus and a sign in the exponent. However, I only seem to get 2 in my output. Any ideas? Compiled on Mac OS using GCC 4.0.1.
Here's the actual code I am using:
of.setf(ios::scientific);
of.precision(6);
for (int i=0;i<dims[0];++i) {
for (int j=0;j<dims[1];++j) {
of << setw(15) << data[i*dims[1]+j];
}
of << endl;
}
and an example line of output:
1.015037e+00 1.015037e+00 1.395640e-06 -1.119544e-06 -8.333264e-07
Thanks
I believe cplusplus.com is incorrect, or at least is documenting a particular implementation - I can't see any other online docs which specifically state the number of exponent digits which are displayed - I can't even find it in the C++ specification.
Edit:
The C++ Standard Library: A Tutorial and Reference doesn't explicitly state the number of exponent digits; but all it's examples display two exponent digits.
It's implementation specific.
This is a bug in M$ implementation AFAIK
http://groups.google.com/group/comp.lang.c++/browse_thread/thread/624b679a4faf03d
I'm getting 3 in MSVC++08 and g++ 4.4.0 with this code:
#include <algorithm>
#include <cstdlib>
#include <iomanip>
#include <iostream>
#include <iterator>
#include <vector>
typedef float NumberType;
double generate_number(void)
{
return static_cast<NumberType>(std::rand()) / RAND_MAX;
}
void print_number(NumberType d)
{
std::cout << std::setw(15) << d << std::endl;
};
int main(void)
{
std::vector<NumberType> data;
std::generate_n(std::back_inserter(data), 10, generate_number);
// print
std::cout.setf(std::ios::scientific);
std::cout.precision(6);
std::for_each(data.begin(), data.end(), print_number);
}
You can easily change the number type it uses. It gives me three places with both float and double, and the standard says nothing on the actual formatting, so I'd go with mgb's answer.
I have just had a thought - since I am printing floats, why would it display 3 exponent values since the max/min exponent is ~38. I bet if the data array were type double there would be 3.