CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 10 of 10
  1. #1
    Join Date
    Jun 2002
    Location
    Germany
    Posts
    1,557

    Truncated floating point with C++ streams

    Hello,

    Can anyone please tell me the appropriate flag combination for formating truncated floating point values using C++ streams. I do not want any rounding.

    Thanks 1*10^6 (thanks a million).

    Chris.

    Code example with questions within the comments:

    Code:
    #include <iostream>
    #include <iomanip>
    using namespace std;
    
    int main(int argc, char* argv[])
    {
      // Have nine nines.
      double d = 0.999999999;
    
      // Want eight nines but don't get it.
      // How do I get the truncation?
      // Is it possible using streams?
      cout << std::setprecision(8) << std::fixed << d << endl;
    
      return 1;
    }
    You're gonna go blind staring into that box all day.

  2. #2
    Join Date
    Jun 2002
    Posts
    224
    I do not think you’ll manage to do this in one line of code. Streams ultimately are using sprintf (at least the library I have) to convert the data: >> is not smarter than sprintf.

    How about truncating a string that contains your converted number (with a large enough precision… say 80)?

    Regards,
    ZDF

    What is good is twice as good if it's simple.
    "Make it simple" is a complex task.

  3. #3
    Join Date
    Jun 2002
    Location
    Germany
    Posts
    1,557
    Hi zdf,

    Thank you.

    Indeed it's no problem to use ::sprintf(...) and related functions. Or some combination of stringstreams and strings (see sample below).

    But it must be possible to get a truncated floating point value from a stream using a single line of code. I would really like to do this kind of thing using a single line.

    Does anyone know how to set a stream's flags appropriately to truncate double without rounding?

    Thanks. Chris.

    UGLY sample:

    Code:
    #include <iostream>
    #include <string>
    #include <sstream>
    #include <iomanip>
    using namespace std;
    
    int main(int argc, char* argv[])
    {
      stringstream ss;
      string       str;
    
      // Have nine nines.
      double d = 0.999999999;
    
      ss << std::fixed << std::setprecision(80) << d << endl;
      ss >> str;
    
      str = str.substr(str.find('.'), 9);
    
      // Want eight nines but don't get it.
      cout << str << endl;
    
      return 1;
    }
    You're gonna go blind staring into that box all day.

  4. #4
    May you have trabble of default values?
    as I know compiler has default value 'int' and 'float' and if there is some number with uncnown type it convert it to 'int' or 'float'. So may be for initialization you need to do this:
    double a = 1.0;
    a = a - 1.0e-5;

  5. #5
    Join Date
    May 2001
    Posts
    472
    The L suffix will tell the compiler that the value is of the type double. Also, make the precision 9 for this example instead of 8.
    Code:
    #include <iostream>
    #include <iomanip>
    using namespace std;
    
    int main(int argc, char* argv[])
    {
    	double d = 0.999999999L;
    	cout << std::setprecision(9) << d << endl;
    
    	return 0;
    }
    Ce n'est que pour vous dire ce que je vous dis.

  6. #6
    Join Date
    Jun 2002
    Posts
    224
    Originally posted by Alexey B
    Also, make the precision 9 for this example instead of 8.
    Hi Alexey B!

    What Chris needs, is to display the truncated value (9 digits, truncated to 8). Something like:
    Code:
    double d = double( int( .999 * 100 ) ) / 100. ;
    ::sprintf as well as streams is rounding to the nearest value; i.e.:
    .996 is displayed 1 if the precison is 2.
    .994 is displayed .99 if the precision is 2.

    To my shame I did not manage to find the "one line" solution.

    Regards,
    Last edited by zdf; August 15th, 2002 at 12:07 PM.
    ZDF

    What is good is twice as good if it's simple.
    "Make it simple" is a complex task.

  7. #7
    Join Date
    May 2001
    Posts
    472
    Sorry, I misinterpreted the OP. Would this solution be acceptible?
    Code:
    #include <iostream>
    #include <iomanip>
    #include <math.h>
    using namespace std;
    
    int main(int argc, char* argv[])
    {
    	double d = 0.999999999L;
    	cout << std::setprecision(8) << floor(d * 1e8L) / 1e8L << endl;
    	return 0;
    }
    Last edited by Alexey B; August 15th, 2002 at 12:46 PM.
    Ce n'est que pour vous dire ce que je vous dis.

  8. #8
    Join Date
    Jun 2002
    Location
    Germany
    Posts
    1,557

    Thumbs up Nine lives...

    Nice solution!

    Thanks to everyone.

    The solution also works in the digit range 15 where the actual application will use it.

    Code:
    #include <iostream>
    #include <iomanip>
    #include <math.h>
    using namespace std;
    
    int main(int argc, char* argv[])
    {
      // 16 nines
      double d = 0.9999999999999999L;
    
      // Truncate to 15 nines
      cout << std::setprecision(15) << floor(d * 1e15L) / 1e15L << endl;
    
      return 0;
    }
    You're gonna go blind staring into that box all day.

  9. #9
    Join Date
    Jun 2002
    Posts
    224

    Ooopppsss!

    Good morning Chris!

    I misinterpreted your question too. I thought you do not want to rely on math.

    Good luck!
    ZDF

    What is good is twice as good if it's simple.
    "Make it simple" is a complex task.

  10. #10
    Join Date
    Jun 2002
    Location
    Germany
    Posts
    1,557

    Cool streamlined

    zdf,

    Indeed I originally did not want to rely on math or division or anything other than pure streams. However, I really couldn't find the right stream flags for this particular task. I'll either take the solution with floor or read in one extra digit and truncate it by hand.

    I'm not sure if the single-line, pure-stream solution exists.

    Again, thanks.
    Chris.

    You're gonna go blind staring into that box all day.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured