1

i have a Problem with double precision.

std::stringstream ss;
ss << std::setprecision(std::numeric_limits<double>::digits10) << std::numeric_limits<double>::max();

This prints 1.79769313486232e+308 to the sting, wheras double max is 1.79769313486231XXXXe+308 in reality. So reading this stringstream again results in infinity.

How can i truncate the number instead of rounding it?

kuga
  • 1,483
  • 1
  • 17
  • 38
  • floating point values are always complicated to store as a human readable strings. If this is not mandatory, you should consider storing float (or double) values as binary blob. Or you can convert them to uint64_t (see reinterpret_cast(double*)) in order to avoid any loss of precision, but the stored representation will not be human readable... – johan d Jul 17 '15 at 08:55
  • It must not reread Double max, but it should be something near it. And the string must be human readable since it is put to an configfile which can be edited manually – kuga Jul 17 '15 at 08:59
  • Why not `std::trunc` ? – Shreevardhan Jul 17 '15 at 09:09
  • It truncates towards natural numbers. So i have to add logic to convert my number to `179769313486231.XXXX`, truncate it and convert it back to `1.79769313486231e+308`. But it Looks like i have to do this... :( – kuga Jul 17 '15 at 09:16

1 Answers1

0

The rounding comes from the IEEE-754 floating type standard which is used by many systems. The reason is that you can represent numbers only for a finit precision. And one of the floating point represantation is standardized by the IEEE-754.

If you want to truncate the number after some specific digits, then you can use the std::trunc function which you can find in the math respectively cmath header file.

If you only want to truncate it on the output streams then you can use the setprecision directive using the #include<iomanip> header file.

For tweaking the rounding operations you are able to set some compiler flags. An example for gcc would be the fast-math compiler flag. (for more information look here gcc floating point compiler flags)

EDIT According to my comment here you will find further information for transforming floating types to non-floating-types and then to two's complement. So for further information look here: truncating floats convert to two's complement and further information for rounding-error evaluation

What you could also try is to load your floats to the SSE,AVX, ... (depends on your system).

Community
  • 1
  • 1
mbed_dev
  • 1,450
  • 16
  • 33
  • -1 (if i had enough reputation): I use `setprecision` and it rounds and does not truncate. Of course i could use `trunc` before converting to string, but i want to know if there is an Attribute of stringstream that can be set to do this automatically. – kuga Jul 17 '15 at 09:03
  • @kuga if you want to know whether "there is an attribute of stringstream that can be set to do this automatically" then please say that in your question. mbed_dev cannot read your mind. – Andy Brown Jul 17 '15 at 09:07
  • @kuga As said in the answer, then you have to use the tweaking methods using the compiler flags. Of course does the `stringstream` have a precision setting method like `stringstreamvar.precision(x)` but it still rounds the number. So either you look at the compiler flags, or you transform the floating type to a non-floating-type and analyse your precision in the two's complement form. – mbed_dev Jul 17 '15 at 09:10
  • @Andy: i think it sais that in the headline. but nevermind. – kuga Jul 17 '15 at 09:17
  • @mbed_dev: Thanks for explaination. I cannot change the compiler flags since it might affect the other conversions in that file and honestly, i am not fond of those things. – kuga Jul 17 '15 at 09:20
  • @kuga you still have the non-floating-type represantation (see my edited answer for further information). – mbed_dev Jul 17 '15 at 09:35