Decimal value truncation in C ++

What is the easiest way to trim a C ++ float variable that has a value of 0.6000002 to a value of 0.6000 and store it back in a variable?

+7
c ++ decimal truncate
Nov 20 '08 at 0:48
source share
9 answers

At first it is important to know that floating-point numbers are approximated. See the link provided by @Greg Hewgill to see why this problem is not completely solvable.

But here are a few solutions to the problem that are likely to satisfy your needs:

Probably the best method, but less effective:

 char sz[64]; double lf = 0.600000002; sprintf(sz, "%.4lf\n", lf); //sz contains 0.6000 double lf2 = atof(sz); //lf == 0.600000002; //lf2 == 0.6000 printf("%.4lf", lf2); //print 0.6000 

A more efficient way, but probably less accurate:

 double lf = 0.600000002; int iSigned = lf > 0? 1: -1; unsigned int uiTemp = (lf*pow(10, 4)) * iSigned; //Note I'm using unsigned int so that I can increase the precision of the truncate lf = (((double)uiTemp)/pow(10,4) * iSigned); 
+5
Nov 20 '08 at 0:49
source share
— -

A good reference to why this is happening can be found in What Every Computer Scientist Should Know About David Goldberg's Floating-Point Arithmetic .

+12
Nov 20 '08 at 0:57
source share

Really, that is impossible. This is not a limitation in C ++, but only how the floating point works. For many values, there are no exact representations, so you cannot just crop a few digits.

You can crop while printing using printf format strings.

If you really need to be able to store only a limited number of digits, I suggest that you use a fixed-precision data type instead.

+6
Nov 20 '08 at 0:53
source share

I think the question to ask here is: Why do you need to trim it?

If this is to compare values, perhaps you should consider using the epsilon test. (with an additional tolerance value, in your case, since it seems much larger than the generally accepted epsilon).

If you just want to print it as 0.6000, use the methods that others have suggested.

+3
Nov 20 '08 at 2:07
source share
 roundf(myfloat * powf(10, numDigits)) / powf(10, numDigits); 

For example, in your case, you truncate three digits (numDigits). You should use:

 roundf(0.6000002 * 1000) / 1000 // And thus: roundf(600.0002) / 1000 600 / 1000 0.6 

(You would probably save the powf result somewhere because you use it twice.)

Because floats are usually stored on computers, there are likely to be inaccuracies. This is what you use to use floats.

+1
Nov 23 '08 at 2:13
source share

Use this:

 floor(0.6000002*10000)/10000 
+1
07 Feb '10 at 4:21
source share

Here is a function that uses advice in other answers and an example of its use:

 #include <iostream> #include <cmath> static void Truncate(double& d, unsigned int numberOfDecimalsToKeep); int main(int, char*[]) { double a = 1.23456789; unsigned int numDigits = 3; std::cout << a << std::endl; Truncate(a,3); std::cout << a << std::endl; return 0; } void Truncate(double& d, unsigned int numberOfDecimalsToKeep) { d = roundf(d * powf(10, numberOfDecimalsToKeep)) / powf(10, numberOfDecimalsToKeep); } 
0
Mar 14 '13 at 16:33
source share

Like the other answers, BUT you must not forget that the circle, gender and trunc differ by definition. See an example of determining and deriving the following:

http://www.cplusplus.com/reference/cmath/trunc/

In this case, we need to perform the trick with an accuracy of 4 decimal places and get rid of non-essential decimal places:

 trunc(valueToTrunc*10000)/10000 

or

 value = (double)((int)(valueToTrunc*10000))/(double)10000 
0
Jan 20 '16 at 18:58
source share

For C ++ 11, you can use std::round defined in the <cmath> header:

 auto trunc_value = std::round(value_to_trunc * 10000) / 10000; 
0
Apr 28 '17 at 19:04 on
source share



All Articles