read long double from a file, then write to another file - c++

i have following part of code:
string v;
getline(linestream,v,' ');
double d=atof(v.c_str());
fprintf(writeFile3,"%f\n",(double)d);
but lets say first line has value 0.08012901 but d=0.080129 last 2 values are omitted, how can i get full double value?
Thank you

If you want the digits copied exactly, by far the easiest way to go is to just leave the digits in string form:
string v;
getline(instream, v, ' ');
outstream << v;
Almost anything that converts the digits to a double, then prints out the value has at least some chance of producing a result that's slightly different from the input.

It's not that the decimal places are not stored in the d. It's just that fprintf only prints 6 decimal places by default. To print 8, try
fprintf(writeFile3, "%.8f\n", d);
You don't have to cast d as a double since it already is of type double.

I would add to the answer above that whatever you put after the variable call is what you will display. By default C++ will show 6.
ie
fprintf(writeFile3, "%.3f\n", (double)d); will display 3 decimal points at the end. It will also pad so if there is possible for longer than 8 decimal places you will want to make it more than that. That I know of you cannot set a flag to just display all decimal points. It has to be explicit.

Related

How to assign exact content of a string to a double in c++

I dont' have much experience with C++, I have the following problem.
With the following code :
double d = 0.0000000;
stringstream ss;
ss << std::fixed << std::setprecision( 2 ) << d;
ss >> d;
or
std::string content = ss.str();
d = atof( content.c_str() );
Either of the two ways while debuging in MS Visual Studio , I see the value of d is 0.0000000 not 0.00 as in the string content
How do I get exact content of string assigned to double d?
May be I should ask a broader question :
I am writing a method that returns a double with precision as needed. For example if I have 2.446343434 as value of d and precision is 2, how can I get my method return d as 2.45 ?
After reading the below answers : I came to know that it is not possible to do such thing. So the next question is :
Even if my above code tries to put 2.45 into double, the C++ runtime will append zeros ( how many ? ) to 2.45 and return right? Is there a way to control appending zeros to the double?
I see the value of d is 0.0000000 not 0.00 as in the string
But both of those numbers have exactly the same value. So, a number can have the value 0.0000000 if and only if it also has the value 0.00.
How do I get exact content of string assigned to double d?
You cannot. double represents a numeric value. It does not represent a character string.
Also, in more general, that is not possible because floating point numbers cannot represent all the numbers that can be represented by a character string. But that is not a problem with 0, which is indeed representable.
I am writing a method that returns a double with precision as needed. For example if I have 2.446343434 as value of d and precision is 2, how can I get my method return d as 2.45
You cannot get your method to return a double with the value 2.45 unless the format of the double can represent 2.45. The binary64 format specified by IEEE 754 can not represent 2.45. In such case, the best that you can do, is to return the representable number closest to the number with 2 significant fractional digits, which in the case of IEEE 754 would be 2.45000000000000017763568394003. The program in your question achieves that.
If that's not what you want, then floating point is not appropriate for your use case.
The human-readable value for d that you're seeing in the debugger, "0.0000000", is just a representation, and a fairly arbitrary one at that. The actual double object does not store this string, nor anything with a fixed number of decimal places.
Its actual identity, at the lowest level, is (a) in binary, (b) encoded according to the floating-point specification, and (c) irrelevant for your purposes. The value is zero; period.
The debugger has simply chosen to use seven decimal places when converting the number into something you can read with your eyes and brain. When using printf or std::cout to similarly output the number for reading, you can pick some other format if you like, including a format with two decimal places to match your original string input. That's just different ways of saying the same thing.
Do not confuse value with representation.
Also, your insistence on specifically two decimal places makes me suspicious: if you're planning on using double to store currency, just don't. Floating-point types are not appropriate for that.

Is it possible to Store 0 as the first digit in integer variable

I want to assign a value of 097 to an integer variable. I don't want it to get implicitly converted to 97. Is this possible?
int i=097;
cout<<i;
OUTPUT as 097 : Possible?
I need to put the value in the link list in reverse order. So if the user is inputting 097 I need to parse it digit wise and store in link list as 7->9->0. Its not the exact program but its something I am trying to achieve. There can be other ways like using arrays and all. But I was just wondering if I can parse 0 via using int variable.
No, this is not possible.
Integers are stored in binary, not as individual digits. Therefore, all information not related to the value of the integer is not stored.
Perhaps you would like to store your value in a string instead?
It doesn't make sense to say that the value of an int is 97 or 097. What you want is a way to format your output. To do that, can std::setwidth and std::setfill.
cout << setwidth(3) << setfill('0') << i;
Not with an integer variable. To achieve this, you could either use a string or some other method of tracking how many leading zeros the number should have.
Incidentally, a leading zero in a C++ integer literal turns it into an octal literal. This makes your program malformed since it's trying to use a non-octal digit 9 in an octal literal.
As others have suggested, try using a string to display the value.Use to_string function to convert the integer to a string and just insert a leading zero at the beginning.
int i = 97;
std::string s = std::to_string(i);
s.insert(0,"0");
EDIT: You can then store the digits into the list by iterating through the string.

How to convert the double to become integer

It is hard to explain the question, i would like to convert a double number to integer without rounding the value after the decimal point.
For example
double a = 123.456
I want to convert become
int b = 123456
I want to know how many digit there is, and move it back after calculated to become 123.456
PS:I just want pure mathematical method to solve this issue, without calculating the character of it.
Sorry, there's no solution to your problem because the number 123.456 does not exist as a double. It's rounded to 123.4560000000000030695446184836328029632568359375, and this number obviously does not fit into any integer type after you remove the decimal point.
If you want 123.456 to be treated as the exact number 123.456, then the only remotely simple way to do this is to convert it to a string and remove the decimal point from the string. This can be achieved with something like
snprintf(buf, sizeof buf, "%.13f", 123.456);
Actually figuring out the number of places you want to print it to, however, is rather difficult. If you use too many, you'll end up picking up part of the exact value I showed above. If you use too few, then obviously you'll drop places you wanted to keep.
try this :
double a = 123.456;
int i;
char str[20];
char str2[20];
sptrintf(str,"%d",a);
for(i=0;i<strlen(str);i++)
{
if(!str[i] == '.')
{
sptrintf(str2,%c,str[i]);
}
}
int b = atoi(str2);
I believe the canonical way to do this would be
#include <math.h>
#include <stdio.h>
int main()
{
double d = 123.456;
double int_part;
double fract_part;
fract_part = modf(d, &int_part);
int i = (int)int_part*1000 + (int)(fract_part*1000);
printf("%d", i);
}
where the literal 1000 is a constant determining the number of desired decimals.
If you have the text "123.456" you can simply remove the decimal point and convert the resulting text representation to an integer value. If you have already converted the text to a floating-point value (double a = 123.456;) then all bets are off: the floating-point value does not have a pre-set number of decimal digits, because it is represented as a binary fraction. It's sort of like 1/3 versus .3333 in ordinary usage: they do not have the same value, even though we usually pretend that .3333 means 1/3.
Multiply each time original value with 10^i, increasing each time i until abs(value' - abs(value')) < epsilon for a very small epsilon. value' should be computed from the original each time, e.g.
value' = value * pow(10, i)
if ( abs(value' - abs(value')) < epsilon ) then stop
Originally I suggested that you should simply multiply by ten, but as R.. suggested, each time the numerical error gets accumulated. As result you might get a result of e.g. 123.456999 for an epsilon = .0000001 instead of 123.456000 due to floating point math.
Please note that you might exceed int type boundaries this way and might want to handle infinity values as well.
As Ignacio Vazquez-Abrams noted this might lead to problems with scenarios where you want to convert 123.500 to 123500. You might solve it by adding a very small value first (and it should be smaller than epsilon). Adding such a value could lead to a numeric error though.

C++ decimal output formatting

i'm writing a double value to a file. The numeric value is written with a point as a decimal separator. I would like to use a comma. How i can do that?
The usual way is to use a locale with the decimal separator set to the comma. If your machine is configured for that generally, you can probably just use the nameless locale for it:
std::cout.imbue(std::locale(""));
std::cout << 12345.67;
You can find the answer in an earlier question
This basically changes the locale used by the streams you are using.
I think in the library cmath
there is a function called modf which takes a float or double, and a pointer to an float or double, and returns an integer.
double intPart;
double fractPart;
fractPart = modf(doubleValue, &intPart);
So you pass in the double value, it returns the decimal part as an integer, and the integer value is stored in the pointer you passed in.
You could then write these to file however you want, with a comma in the middle or whatever, just write it as two separate numbers.
float or double

Fixed Length Float in C/C++?

I was wondering whether it is possible to limit the number of characters we enter in a float.
I couldn't seem to find any method. I have to read in data from an external interface which sends float data of the form xx.xx. As of now I am using conversion to char and vice-versa, which is a messy work-around. Can someone suggest inputs to improve the solution?
If you always have/want only 2 decimal places for your numbers, and absolute size is not such a big issue, why not work internally with integers instead, but having their meaning be "100th of the target unit". At the end you just need to convert them back to a float and divide by 100.0 and you're back to what you want.
This is a slight misunderstanding. You cannot think of a float or double as being a decimal number.
Most any attempt to use it as a fixed decimal number of precision, say, 2, will incur problems as some values will not be precisely equal to xxx.xx but only approximately so.
One solution that many apps use is to ensure that:
1) display of floating point numbers is well controlled using printf/sprintf to a certain number of significant digits,
2) one does not do exact comparison between floating point numbers, i.e. to compare to the 2nd decimal point of precision two numbers a, b : abs(a-b) <= epsilon should generally be used. Outright equality is dangerous as 0.01 might have multiple floating point values, e.g. 0.0101 and 0.0103 might result if you do arithmetic, but be indistinguishable to the user if values are truncated to 2 dp, and they may be logically equivalent to your application which is assuming 2dp precision.
Lastly, I would suggest you use double instead of float. These days there is no real overhead as we aren't doing floating point without a maths coprocessor any more! And a float under 32-bit architectures has 7 decimal points of precision, and a double has 15, and this is enough to be significant in many case.
Rounding a float (that is, binary floating-point number) to 2 decimal digits doesn't make much sense because you won't be able to round it exactly in some cases anyway, so you'll still get a small delta which will affect subsequent calculations. If you really need it to be precisely 2 places, then you need to use decimal arithmetic; for example, using IBM's decNumber++ library, which implements ISO C/C++ TR 24773 draft
You can limit the number of significant numbers to output:
http://www.cplusplus.com/reference/iostream/manipulators/setprecision/
but I don't think there is a function to actually lop off a certain number of digits. You could write a function using ftoa() (or stringstream), lop off a certain number of digits, and use atof() (or stringstream) and return that.
You should checks the string rather than the converted float. It will be easier to check the number of digits.
Why don't you just round the floats to the desired precision?
double round(double val, int decimalPlaces)
{
double power_of_10 = pow(10.0, static_cast<double>(decimalPlaces));
return floor(val * power_of_10 + 0.5) / power_of_10;
}
int main()
{
double d;
cin >> d;
// round d to 3 decimal places...
d = round(d, 3);
// do something with d
d *= 1.75;
cout << setprecision(3) << d; // now output to 3 decimal places
}
There exist no fixed point decimal datatype in C, but you can mimic pascal's decimal with a struct of two ints.
If the need is to take 5 digits [ including or excluding the decimal point ], you could simply write like below.
scanf( "%5f", &a );
where a is declared as float.
Fo eg:
If you enter 123.45, scanf will consider the first 5 characters i.e., 4 digits and the decimal point & will store 123.4
If entered 123456, the value of a will be 12345 [ ~ 12345.00 ]
With printf, we would be able to control how many characters can be printed after decimal as well.
printf( "%5.2f \n", a );
The value of 123.4 will be printed as 12.30 [ total 5, including the decimal & 2 digits after decimal ]
But this have a limitation, where if the digits in the value are more than 5, it will display the actual value.
eg: The value of 123456.7, will be displayed as 123456.70.
This [ specifying the no. of digits after the decimal, as mentioned for printf ] I heard can be used for scanf as well, I am not sure sure & the compiler I use doesn't support that format. Verify whether your compiler does.
Now, when it comes to taking data from an external interface, are you talking about serialization here, I mean transmission of data on netwrok.
Then, to my knowledge your approach is fine.
We generally tend to read in the form of char only, to make sure the application works for any format of data.
You can print a float use with printf("%.2f", float), or something similar.