Solved

# Determining Precision of a number

Posted on 2000-04-27
214 Views
I'm tring to determine the precision of a float (ie 123.345 = 3)  The only way I can think of is to convert the float to a string then using strlen.  Are there easier methods?
0
Question by:gmanhart
[X]
###### Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

• Help others & share knowledge
• Earn cash & points
• 6
• 6
• 3
• +1

LVL 12

Expert Comment

ID: 2758311
Actually, the string method seems a perfectly good way of doing it, and I don't see it's all that difficult--just use sprintf() to convert the number to a string, search for the decimal point using strchr(), then work out the length of the string after that point. I don't think you'll get easier than that.
0

LVL 18

Accepted Solution

deighton earned 50 total points
ID: 2758826
#include<math.h>

int decimals(double x)
{
int c;
double d = 1,test;
for(c = 0;1;c++)
{
test = x * d;
if (test == floor(test))
return c;
d *= 10;
}
}

main()
{
printf("\n%i",decimals(3.141592));
}
0

LVL 84

Expert Comment

ID: 2760318
What's the precision of 123.3450000 ?
or do you want FLT_DIG ?
0

Author Comment

ID: 2761660
Adjusted points from 25 to 50
0

Author Comment

ID: 2761661
Excellent solution, especially without even converting the float into a string.  Simple, short and perfect.  Thanks
0

LVL 84

Expert Comment

ID: 2762227
although it's a strange definition of "precision" that increases with round off error.
0

Author Comment

ID: 2762309
Ozo,

Please explain your comment.  Are you talking about problems with the floor function itself?  It would be nice to also consider an option of setting how your precision is to be handled (ie
Precision(Double x, int y) where x would be the number to work on and y would have two options: 0 for 3.12300 = 3 and 1 would be 5 for all decimals after the point)

Now that would allow nice control.  What do you think?
0

Author Comment

ID: 2762313
Ozo,

Also, what is FLT_DIG?
0

LVL 84

Expert Comment

ID: 2762784
FLT_DIG is a macro defined in <float.h> which returns the number of decimal digits such that any floating-point number with FLT_DIG digits can be rounded into a floating-point number with FLT_MANT_DIG radix FLT_RADIX digits without change to the FLT_DIG decimal digits for your implementation.
floor( (FLT_MANT_DIG-1) * log10(FLT_RADIX) ) + 1 if FLT_RADIX is a power of 10, 0 otherwise.
(cf. DBL_DIG)
I'm not sure what you mean by "precision"
Testing when two different round off errors happen to cancel in your floating point processor may or may not be relevent to you.
What would you call the "precision" of an ANSI/IEEE 754-1985 double precision normalized representation of 33141.59? and why?
0

Author Comment

ID: 2764628
Ozo,

I'm creating a Histogram program for a Software Engineering course I'm taking.

I'm need to determine the precision of the numbers the user is entering so that when I bin the numbers I can have +1 decimals more that the user entered to setup the bins.  If the user entered 33141.59, I would consider it a number with 2 decimal places of precision.  A number with trailing zeros to me at this point is not that important since the user as the ablity to override the automatic precision if they don't like the way I trunicate their zeros.  Although I have not test the code completely from deighton, I would only expect it to tell me that 123.123 and 123.12300 have 3 decimal places of precision (even though realisically one has three and the other has 5).  Later I can give the user more options.  Thanks for answering my question and I hope I answered yours

Greg
0

LVL 84

Expert Comment

ID: 2764892
For binning, wouldn't "precision" only have meaning in the context of all the numbers entered?
Whether deighton's code gives you 3 or 5 or some other result for 123.123 may depend on intricate details of your particular floating point processor in a way that may not make sense to your users.
What kind of processor will the code be running on?
If you are using  ANSI/IEEE 754-1985 floating point, 33141.59 would be stored as 33141.589999999997
Try deighton's code with 2.03, 4.03, 8.03, 8.19, or 32.123
0

Author Comment

ID: 2765013
Ozo,

Well now, using deigton's code:

printf("\n%f %i",2.03,decimals(2.03));
printf("\n%f %i",4.03,decimals(4.03));
printf("\n%f %i",8.03,decimals(8.03));
printf("\n%f %i",8.14,decimals(8.14));
printf("\n%f%i",32.123,decimals(32.123));

I got:

2.030000  16
4.030000  2
8.030000  4
8.140000  2
32.123000  4

What is up with that and how can I prevent this from occurring.  I'm using codewarrior on a Macintosh G3 and this is not what I expected.  This will totally mess up my binning!  My routine takes the maximum precision and adds one and then bins based on this.  I find the bin with with the range/# of bins.  Then need to round up to the next precision higher than the data entered.  I need something reliable.

Do you have any ideas on how to prevent this?

Greg
0

LVL 84

Expert Comment

ID: 2765193
You might see better what's going on if you change your print formats to
printf("\n%.20f",
For the kind og "precision" you want you should probably examine the input from your user stings before converting them into float.
(or perhaps what you really want is an approximation to the least common multiple of the numbers from the user)
0

LVL 12

Expert Comment

ID: 2765293
gmanhart: It might help if you used double instead of float, although rounding errors may well still occur.
0

LVL 18

Expert Comment

ID: 2769001
How about reading the value in as a string, counting the digits after the '.' then converting the string to a float.  It could be written to ignore or include trailing zeroes.

I could provide that code!

EMail me at andrew_deighton@hotmail.com if you need to set me working on that, then I'll put the code here, if I can do it/have enough time.

How are you getting the value into the program?  Are you relying on scanf, or do you have your own user written function?
0

LVL 18

Expert Comment

ID: 2769005
ozo,

I see the flaw in my reasoning.
0

LVL 84

Expert Comment

ID: 2770263
pjknibbs, double, or even quad precision, may shift where the errors are noticed, but not eliminate them.
Although rounding errors might be reduced, your sensitivity to rounding errors would be increased.
However, if floats and doubles have different precisions under your implementation, it might work to do the calculations with double and the final test with float.
But that would be sort of a kludge, and non-portable even if it did work, so I would not recommend that approach.
Counting digits in the original string would be a better solution.
0

## Featured Post

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

### Suggested Solutions

An Outlet in Cocoa is a persistent reference to a GUI control; it connects a property (a variable) to a control.  For example, it is common to create an Outlet for the text field GUI control and change the text that appears in this field via that Ouâ€¦
This is a short and sweet, but (hopefully) to the point article. There seems to be some fundamental misunderstanding about the function prototype for the "main" function in C and C++, more specifically what type this function should return. I see soâ€¦
The goal of this video is to provide viewers with basic examples to understand and use nested-loops in the C programming language.
The goal of this video is to provide viewers with basic examples to understand and use while-loops in the C programming language.
###### Suggested Courses
Course of the Month4 days, 1 hour left to enroll