How to detect a double's significant digits

M

mrstephengross

Hi all... How can I find out the number of significant digits (to the
right of the decimal place, that is) in a double? At least, I *think*
that's what I'm asking for. For instance:

0.103 --> 3
0.0103 --> 4
0.00103 --> 5
0.000103 --> 6
0.0000103 --> 7

Thanks in advance!
--Steve ([email protected])
 
J

James Stroud

Significant digits are an accounting concept. As such, it is up to the
accountant to keep track of these as only she knows the precision of her
measurements.

Koan for the day:

What are the significant digits of 0.1?

Hint:
James



Hi all... How can I find out the number of significant digits (to the
right of the decimal place, that is) in a double? At least, I *think*
that's what I'm asking for. For instance:

0.103 --> 3
0.0103 --> 4
0.00103 --> 5
0.000103 --> 6
0.0000103 --> 7

Thanks in advance!
--Steve ([email protected])

--
James Stroud, Ph.D.
UCLA-DOE Institute for Genomics and Proteomics
Box 951570
Los Angeles, CA 90095

http://www.jamesstroud.com/
 
M

mrstephengross

So how can I get the kind of information I want then?

For example:

0.103 --> 3
0.0103 --> 4
0.00103 --> 5
0.000103 --> 6
0.0000103 --> 7

Any ideas?
--Steve
 
M

mrstephengross

Ok, that won't work. First of all, str() is not a function. If I want
to convert the float into a string, the conversion function will have
to use some kind of numeric precision, which will screw things up.
Consider this:

float f = 1.004;
ostringstream s;
s << f;
cout << s.str();

The above code may produce "1.004", or "1.0040", or "1.00400",
depending on the stream's precision setting. I need a way to detect the
number of digits to the right of decimal point *prior* to doing any
kind of string conversion.

--Steve
 
S

Steven Bethard

mrstephengross said:
So how can I get the kind of information I want then?

For example:

0.103 --> 3
0.0103 --> 4
0.00103 --> 5
0.000103 --> 6
0.0000103 --> 7

Beware that this is probably only relevant if you have your numbers as
strings, not as floats:

py> 0.103
0.10299999999999999

But, assuming you have your numbers as strings, I would suggest looking
at str.split() and len(). I'd give you an example, but this sounds
kinda like a homework assignment.

STeVe
 
S

Steven Bethard

mrstephengross said:
First of all, str() is not a function.

Yes it is.
float f = 1.004;
ostringstream s;
s << f;
cout << s.str();

This doesn't look like Python to me. Are you sure you're on the right
newsgroup?

STeVe
 
M

mrstephengross

But, assuming you have your numbers as strings, I would suggest
looking
at str.split() and len().

Well, the numbers are in fact stored as numbers, so string processing
won't work.
I'd give you an example, but this sounds kinda like a homework
assignment.

The task may sound like it comes from class, but I can assure you that
I am indeed a professional developer. I'm doing some rather intricate
text processing / rendering stuff these days, and C++ is unfortunately
none too handy for that sort of thing. Unfortunately, I have to use it
for the task.

Thanks,
--Steve
 
S

Steven Bethard

mrstephengross said:
Well, the numbers are in fact stored as numbers, so string processing
won't work.

What kind of numbers? Python floats?

STeVe
 
S

Steven Bethard

mrstephengross said:
looking
at str.split() and len().

Well, the numbers are in fact stored as numbers, so string processing
won't work.

How about:

py> def digits(f):
.... return len(str(f).split('.')[1].rstrip('0'))
....
py> for f in [0.103, 0.1030, 0.0103, 0.010300]:
.... print f, digits(f)
....
0.103 3
0.103 3
0.0103 4
0.0103 4

I believe the rstrip is unnecessary because I think str() will never
produce additional following zeros, but you can guarantee it by calling
rstrip if you want.

Note that, for example, 0.103 and 0.1030 are identical as far as Python
is concerned, so I hope you're not hoping to show a difference between
these two...

STeVe
 
C

Charles Krug

Hi all... How can I find out the number of significant digits (to the
right of the decimal place, that is) in a double? At least, I *think*
that's what I'm asking for. For instance:

0.103 --> 3
0.0103 --> 4
0.00103 --> 5
0.000103 --> 6
0.0000103 --> 7

Thanks in advance!
--Steve ([email protected])

I would say that each of these examples has three signficant figures.
Each of them can be expressed as:

1.03e+n

For any integer n.

The fact that you've only shown the cases where n \in {-1, -2, -3, -4,
-5 . . } doesn't change the generality of the answer.
 
G

Grant Edwards

looking
at str.split() and len().

Well, the numbers are in fact stored as numbers,

Then your question is in fact meaningless. The related
question that can be answered is "where is the least
significant '1' bit in the IEEE representation". If that's
useful information, the struct module will help you find it.
so string processing won't work.

That's the only way to answer the question you asked.
 
M

mrstephengross

This doesn't look like Python to me. Are you sure you're on the right
newsgroup?

Er, ok, I'm an idiot. This was all supposed to be on comp.lang.c++, but
obviously I posted on the wrong one. Sorry for all the hassle. In
python, this stuff is a heck of a lot easier.

--Steve
 
P

Peter Otten

mrstephengross said:
This was all supposed to be on comp.lang.c++, but

You may still want to read the following thread on Python-Dev:
http://mail.python.org/pipermail/python-dev/2004-March/043703.html

A link mentioned by Andrew Koenig may be helpful:
http://www.netlib.org/fp/

"""
file g_fmt.c
by David Gay
for ANSI C or C++ source for function g_fmt(char *, double):
, with help from dtoa, g_fmt(buf, x) sets buf to the shortest
, decimal string that correctly rounds to x and returns buf.
"""

Peter
 
F

Fredrik Lundh

mrstephengross said:
looking
at str.split() and len().

Well, the numbers are in fact stored as numbers, so string processing
won't work.

if they're not strings, your question is meaningless. as others have
pointed out, the exact internal representation for 0.103 is more like
0.10299999999999999433786257441170164383947849273681640625
which has a lot more than 3 digits...
assignment.

The task may sound like it comes from class, but I can assure you that
I am indeed a professional developer.

well professional or not, you clearly need to refresh your floating point
skills. I suggest reading the following documents before proceeding:

http://docs.python.org/tut/node16.html
http://www.lahey.com/float.htm

</F>
 
J

Jeremy Bowers

I would say that each of these examples has three signficant figures. Each
of them can be expressed as:

1.03e+n

For any integer n.

You beat me to it.

Step one for mrstephengross is to *rigorously* define what he means by
"significant digits", then go from there. Since I think he mentioned
something about predicting how much space it will take to print out, my
suggestion is to run through whatever printing routines there are and get
a string out, the measure the string, as anything else will likely be
wrong. If that's not possible with the formatting library, you've already
lost; you'll have to completely correctly re-implement the formatting
library, and not only is that a major PITA, you almost never get it
bug-for-bug right...
 
E

Erik Max Francis

Jeremy said:
Step one for mrstephengross is to *rigorously* define what he means by
"significant digits", then go from there. Since I think he mentioned
something about predicting how much space it will take to print out, my
suggestion is to run through whatever printing routines there are and get
a string out, the measure the string, as anything else will likely be
wrong. If that's not possible with the formatting library, you've already
lost; you'll have to completely correctly re-implement the formatting
library, and not only is that a major PITA, you almost never get it
bug-for-bug right...

Especially since all of his examples have the same number of significant
digits (3), as the term is usually meant. Zeroes to the right are
significant, not zeroes to the left.
 
G

Grant Edwards

Since I think he mentioned something about predicting how much
space it will take to print out, my suggestion is to run
through whatever printing routines there are and get a string
out,

A step which will require him to tell the printing routine how
many digits he wants printed.
 
G

Grant Edwards

Especially since all of his examples have the same number of
significant digits (3), as the term is usually meant. Zeroes
to the right are significant, not zeroes to the left.

And only the person who performed the measurement knows how
many of the zeros to the right are significant.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top