Thread: writing long double into ofstream file?

  1. #1
    Registered User
    Join Date
    May 2006
    Posts
    23

    Question writing long double into ofstream file?

    Dear All!

    I defined a log double variable. That variable takes some values like :
    long double varr = 0.038918918918916

    i would like to write it to a file

    Code:
    long double varr = 0.038918918918916
    ofstream out; 
    out.open("ktr.txt");
    
    out<< varr;
    however, it writes as 0.389189. truncated.

    How can I write it with originally in long format?

    thank you

  2. #2
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Using operator << stores it in string format, which is typically bad. Try write instead to store it in binary format (then read with get/read).
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  3. #3
    Deathray Engineer MacGyver's Avatar
    Join Date
    Mar 2007
    Posts
    3,210
    Storing it as a string (or text of any kind) is the most portable method. Unfortunately, I'm not very well versed in C++ formatting stuff, and have more knowledge of the printf() family of functions.

    This type of stuff should get you started:

    http://www.cprogramming.com/tutorial/iomanip.html
    http://www.devx.com/cplus/10MinuteSo...6/1954?pf=true

    And of course:

    http://www.google.com/search?q=C&#37;2B%...matting+string
    http://www.google.com/search?q=C%2B%...atting+numbers

  4. #4
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by MacGyver View Post
    Storing it as a string (or text of any kind) is the most portable method.
    And unfortunately, also make it more prone to errors when reading it again.
    "0.389189" == 9 bytes.
    double == 8 bytes.
    So you get an offset error if you try to read a long double again using >>. You'd have to into a string instead.

    Anyway, either use printf for formating or write binary. It's up to you, wolfindark. Whichever suits your purpose best.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  5. #5
    Deathray Engineer MacGyver's Avatar
    Join Date
    Mar 2007
    Posts
    3,210
    Quote Originally Posted by Elysia View Post
    And unfortunately, also make it more prone to errors when reading it again.
    "0.389189" == 9 bytes.
    double == 8 bytes.
    How do you count that as 9 bytes? If you're counting '\0' that doesn't get written to a text file (unless you mess up).

    Even so, I have no idea what you're talking about 9 bytes vs 8 bytes and how that applies to this discussion at all. A double may be 8 bytes, but floating point representation is usually done in a special manner (ie. IEEE representation with the sign, exponent, and mantissa.... etc. etc..).

    If your read and write functions are complements of each other, then there is no issue. Dumping something to a binary file and then trying to read it back is guarenteed to cause errors if you try to transfer that file to a different system that uses a different endian orientation, while attempting to use it in the same manner.

    Quote Originally Posted by Elysia View Post
    So you get an offset error if you try to read a long double again using >>. You'd have to into a string instead.
    If you write a string, it would make sense to read a string.

    Stealing code from the examples I provided, here's a simple demonstration.

    As a reminder to the OP, floating point representations are approximations. This is why the original number isn't printed exactly as it appears.

    Code:
    #include <iostream>
    #include <fstream>
    #include <limits>
    #include <sstream>
    #include <iomanip>
    
    std::string readLongDouble(long double);
    void writeLongDouble(long double);
    
    long double readLongDouble()
    {
    	long double d;
    	std::ifstream in("double.txt");
    	std::string s;
    	std::stringstream ss;
    	
    	getline(in, s);
    	ss << s;
    	ss >> d;
    	
    	in.close();
    	return d;
    }
    
    void writeLongDouble(long double d)
    {
    	std::ofstream out("double.txt");
    	std::stringstream ss;
    	
    	ss.precision(std::numeric_limits<long double>::digits10);//override the default
    	ss << d;
    	
    	out << ss.str(); //extract string from stream
    	out.close();
    }
    
    int main()
    {
    	long double d = 0.038918918918916;
    	
    	std::cout << std::setprecision(std::numeric_limits<long double>::digits10);
    	
    	std::cout << "The original long double comes out to: " << d << std::endl;
    	writeLongDouble(d);
    	std::cout << "Written... check double.txt for string..." << std::endl;
    	std::cout << "Press <Enter> when ready to continue...." << std::endl;
    	std::cin.ignore();
    	std::cout << "This is what is read from double.txt, converted to a long double: " <<  readLongDouble() << std::endl;;
    	
    	return 0;
    }
    You don't lose out when converting to a string. This is the most portable way to do it.

    Apologies for any errors. I'm quite used to char arrays and the printf() family of functions.

  6. #6
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by MacGyver View Post
    If you write a string, it would make sense to read a string.
    But it isn't obvious you're writing a string, is it!
    You're writing a double and you expect to be able to read it back as a double, but obviously this is not how the stream operators works and that's what you need to be careful about!
    You can write using << with any type, but you should always read using >> to a string.
    I don't even understand why the heck they convert the darn thing to a string and later allow you to read back to a non-string.

    The C++ I/O (and strings!) are just so flawed in my opinion. But enough of that.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  7. #7
    Registered User
    Join Date
    Aug 2005
    Location
    Austria
    Posts
    1,990
    Quote Originally Posted by Elysia View Post
    I don't even understand why the heck they convert the darn thing to a string and later allow you to read back to a non-string.
    Some magic inside the >> operators convert the string to the right datatype.
    Quote Originally Posted by Elysia View Post
    The C++ I/O (and strings!) are just so flawed in my opinion. But enough of that.
    Could it be that your understanding of C++ I/O is somehow incomplete ?
    Kurt

  8. #8
    Deathray Engineer MacGyver's Avatar
    Join Date
    Mar 2007
    Posts
    3,210
    This is why most input and output should be done in text representation. Numerical values should only be used for math purposes really.

  9. #9
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by ZuK View Post
    Some magic inside the >> operators convert the string to the right datatype.
    Yes, it works, but can give you offset errors. Try writing two UINT64 = 1 using << and then reading them back using >>. Boom! Offset error.

    Could it be that your understanding of C++ I/O is somehow incomplete ?
    Kurt
    Maybe, but I think I know enough. Anyway, I shrug.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  10. #10
    Registered User
    Join Date
    Aug 2005
    Location
    Austria
    Posts
    1,990
    Quote Originally Posted by Elysia View Post
    Yes, it works, but can give you offset errors. Try writing two UINT64 = 1 using << and then reading them back using >>. Boom! Offset error.
    Could you explain what an offset error should be. After all when using << and >> you're dealing with text streams. calculating offsets in a text file doesn't make much sense.
    Kurt

  11. #11
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    The first variable will read 11 (or something - two characters [or strings] each, containing '1'), and the last reading will fail since it tries to read beyond the end of file, so the last variable will be whatever you initialized it to.
    If I write two UINT64, then I expect to be able to read two UINT64 back the same way, no? This is where the << and >> are dangerous. They're only really made to work with strings and then you should only write strings imo.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  12. #12
    Registered User
    Join Date
    Aug 2005
    Location
    Austria
    Posts
    1,990
    Code:
    int main() {
        unsigned long ui1 = 1;
        unsigned long ui2 = 2;
        ofstream ofstr("out");
        ofstr << ui1 << " " << ui2;    // writing exactly 3 bytes. wonder why you are taking about 11
        ifstream ifstr("out");
        ifstr >> ui1 >> ui2;                // reading 
    }
    Kurt

  13. #13
    Deathray Engineer MacGyver's Avatar
    Join Date
    Mar 2007
    Posts
    3,210
    Quote Originally Posted by ZuK View Post
    Could you explain what an offset error should be. After all when using << and >> you're dealing with text streams. calculating offsets in a text file doesn't make much sense.
    Kurt
    Indeed.

    C suffers from the same problem:

    Code:
    #include <stdio.h>
    
    void writeInt(int);
    int readInt(void);
    
    void writeInt(int x)
    {
    	FILE *f = fopen("int.txt", "a");
    	if(f)
    	{
    		fprintf(f, "%d", x);
    		fclose(f);
    	}
    }
    
    int readInt(void)
    {
    	int x = -1;
    	FILE *f = fopen("int.txt", "r");
    	if(f)
    	{
    		fscanf(f, "%d", &x);
    		fclose(f);
    	}
    	return x;
    }
    
    int main(void)
    {
    	writeInt(1);
    	writeInt(2);
    	printf("The first int written was: %d\n", readInt());
    	
    	return 0;
    }
    Output:

    Code:
    The first int written was: 12
    Elysia, I believe this is the kind of thing you're talking about, but I think you're putting too much demand on the standard IO functions.

    How does either the standard IO functions from C or C++ know 12 is really 1 and 2 written side by side if that is your format? If you put two UINT64 variables together side by side, how does it know that you've actually done that? Given text to read and convert to a numerical value, the standard library will do what it can based upon some rules to interpret that text. There's not much more you can ask of it.

    Be explicit and make sure you know what you're doing when you come up with a file format.

  14. #14
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Code:
    	UINT64 ui1 = 1;
    	UINT64 ui2 = 2;
    	ofstream ofstr("C:\\out.txt");
    	ofstr << ui1 << ui2;
    	ofstr.close();
    	ifstream ifstr("C:\\out.txt");
    	ui1 = ui2 = 0;
    	ifstr >> ui1 >> ui2;
    	cout << ui1 << endl << ui2 << endl; // Prints 12, 0
    This is exactly what I'm referring to.
    LOGIC would say that if I write two UINT64 beside each other, I can read them back just as well. But truth is, I can't. That isn't how the I/O works.
    To make matters worse, the doc doesn't mention this (or does it very poorly) that it converts it to text format and writes it.
    If I were a newbie, I would expect exactly this behavior as above - the code should work. Or, in other words, I'd be confused as come complaining here "why doesn't this work!!??!!".
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  15. #15
    Deathray Engineer MacGyver's Avatar
    Join Date
    Mar 2007
    Posts
    3,210
    Logic indicates a string "12" be converted to an integer as 12.

    Your expectation is completely unrealistic. Text streams inherently deal with text. Text is text. You should know you're writing to and reading from a text file. Demanding that the IO library somehow figure out the difference between different interpretations of text is rather silly.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 2
    Last Post: 05-20-2008, 08:57 AM
  2. gcc link external library
    By spank in forum C Programming
    Replies: 6
    Last Post: 08-08-2007, 03:44 PM
  3. Dev-cpp - compiler options
    By tretton in forum C Programming
    Replies: 7
    Last Post: 01-06-2006, 06:20 PM
  4. Possible circular definition with singleton objects
    By techrolla in forum C++ Programming
    Replies: 3
    Last Post: 12-26-2004, 10:46 AM
  5. Unknown Memory Leak in Init() Function
    By CodeHacker in forum Windows Programming
    Replies: 3
    Last Post: 07-09-2004, 09:54 AM