Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > number of digits in a number

Reply
Thread Tools

number of digits in a number

 
 
bejiz
Guest
Posts: n/a
 
      09-26-2007
Hi,
Do you know a way to tell to the compiler that if
there are numbers of 1 digit ( 2, 6, 8,...), I want spaces like this:
" ".
But if I have numbers of 3 digits, I want spaces
like this: " ".
I don't know how to get the numbers of digits in
a number (integer or float).
Thanks.

 
Reply With Quote
 
 
 
 
Victor Bazarov
Guest
Posts: n/a
 
      09-26-2007
bejiz wrote:
> Hi,
> Do you know a way to tell to the compiler that if
> there are numbers of 1 digit ( 2, 6, 8,...), I want spaces like this:
> " ".
> But if I have numbers of 3 digits, I want spaces
> like this: " ".
> I don't know how to get the numbers of digits in
> a number (integer or float).


Number of digits in 'x' (assuming 'x' is unsigned) :

int ndigits = x > 0 ? int(log10(x)) + 1 : 1;

As to preceding number of spaces, see 'setw' stream manipulator.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask


 
Reply With Quote
 
 
 
 
Mark P
Guest
Posts: n/a
 
      09-26-2007
Victor Bazarov wrote:
> bejiz wrote:
>> Hi,
>> Do you know a way to tell to the compiler that if
>> there are numbers of 1 digit ( 2, 6, 8,...), I want spaces like this:
>> " ".
>> But if I have numbers of 3 digits, I want spaces
>> like this: " ".
>> I don't know how to get the numbers of digits in
>> a number (integer or float).

>
> Number of digits in 'x' (assuming 'x' is unsigned) :
>
> int ndigits = x > 0 ? int(log10(x)) + 1 : 1;
>
> As to preceding number of spaces, see 'setw' stream manipulator.
>
> V


Maybe the standard guarantees otherwise, but this seems potentially
susceptible to numerical inaccuracies. What happens if log10( 100)
returns 1.99999999987?
 
Reply With Quote
 
Victor Bazarov
Guest
Posts: n/a
 
      09-27-2007
Mark P wrote:
> Victor Bazarov wrote:
>> bejiz wrote:
>>> Hi,
>>> Do you know a way to tell to the compiler that
>>> if there are numbers of 1 digit ( 2, 6, 8,...), I want spaces like
>>> this: " ".
>>> But if I have numbers of 3 digits, I want spaces
>>> like this: " ".
>>> I don't know how to get the numbers of digits in
>>> a number (integer or float).

>>
>> Number of digits in 'x' (assuming 'x' is unsigned) :
>>
>> int ndigits = x > 0 ? int(log10(x)) + 1 : 1;
>>
>> As to preceding number of spaces, see 'setw' stream manipulator.
>>
>> V

>
> Maybe the standard guarantees otherwise, but this seems potentially
> susceptible to numerical inaccuracies. What happens if log10( 100)
> returns 1.99999999987?


Right. I should have added 0.5:

int ndigits = x > 0 ? int(log10(x + 0.5)) + 1 : 1;

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask


 
Reply With Quote
 
Mark P
Guest
Posts: n/a
 
      09-27-2007
Victor Bazarov wrote:
> Mark P wrote:
>> Victor Bazarov wrote:
>>> bejiz wrote:
>>>> Hi,
>>>> Do you know a way to tell to the compiler that
>>>> if there are numbers of 1 digit ( 2, 6, 8,...), I want spaces like
>>>> this: " ".
>>>> But if I have numbers of 3 digits, I want spaces
>>>> like this: " ".
>>>> I don't know how to get the numbers of digits in
>>>> a number (integer or float).
>>> Number of digits in 'x' (assuming 'x' is unsigned) :
>>>
>>> int ndigits = x > 0 ? int(log10(x)) + 1 : 1;
>>>
>>> As to preceding number of spaces, see 'setw' stream manipulator.
>>>
>>> V

>> Maybe the standard guarantees otherwise, but this seems potentially
>> susceptible to numerical inaccuracies. What happens if log10( 100)
>> returns 1.99999999987?

>
> Right. I should have added 0.5:
>
> int ndigits = x > 0 ? int(log10(x + 0.5)) + 1 : 1;
>
> V


That works, and also spares you the indignity of the ternary operator.
 
Reply With Quote
 
robertwessel2@yahoo.com
Guest
Posts: n/a
 
      09-27-2007
On Sep 26, 7:33 pm, "Victor Bazarov" <(E-Mail Removed)> wrote:
> Right. I should have added 0.5:
>
> int ndigits = x > 0 ? int(log10(x + 0.5)) + 1 : 1;



Now it won't work for 99.7, 999.7, 9999.7, etc. It's also not clear
that this does what you want for numbers less than 1.

I suggest you give this up, you will not be able to make this work
reliably, since the result of log10() is almost never exact, and you'd
have to prove that the result is correct around all the powers of 10.
While you might be able to verify that for any given implementation of
C++, you can't make the case in general.

While using the log() operator is likely to be overly expensive in any
case, you *could* use that to pick an approximation (IOW log10(x)),
and then test if that needs to be adjusted up or down one, perhaps
with a table lookup. Something like:


double powers10[] = {1., 10., 100., 1000., 10000., 100000.,
1000000....};

nd = log10(x); //needs range check

if (x < powers10[nd]) nd--;
else if (x >=powers10[nd+1) nd++;

 
Reply With Quote
 
James Kanze
Guest
Posts: n/a
 
      09-27-2007
On Sep 27, 7:00 am, "(E-Mail Removed)"
<(E-Mail Removed)> wrote:
> On Sep 26, 7:33 pm, "Victor Bazarov" <(E-Mail Removed)> wrote:


> > Right. I should have added 0.5:


> > int ndigits = x > 0 ? int(log10(x + 0.5)) + 1 : 1;


> Now it won't work for 99.7, 999.7, 9999.7, etc. It's also not clear
> that this does what you want for numbers less than 1.


It's not clear at all what he wants to begin with; Victor's
guess is as good as anything else. But if he wants to know how
many digits are present, the most obvious solution is:

std:strinstream s ;
// add whatever format flags are wanted...
s << value ;
return s.str().size() ;

It probably won't be as fast as the solution with log10, but it
does guarantee that the number you get corresponds exactly to
the number of characters ostream will generate.

> I suggest you give this up, you will not be able to make this
> work reliably, since the result of log10() is almost never
> exact, and you'd have to prove that the result is correct
> around all the powers of 10. While you might be able to
> verify that for any given implementation of C++, you can't
> make the case in general.


You could certainly do it for IEEE, at least for numbers in a
"normal" range. (As for the extremes... what should
log10(1e300) return? You're not really passing it 1e300 to
begin with.)

--
James Kanze (GABI Software) email:(E-Mail Removed)
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

 
Reply With Quote
 
robertwessel2@yahoo.com
Guest
Posts: n/a
 
      09-27-2007
On Sep 27, 5:09 am, James Kanze <(E-Mail Removed)> wrote:
> You could certainly do it for IEEE, at least for numbers in a
> "normal" range. (As for the extremes... what should
> log10(1e300) return? You're not really passing it 1e300 to
> begin with.)



No, you actually can't. There isn't actually a formal accuracy
standard for the complex transcendental functions, and the accepted
"One ULP*" rule (which, IIRC, is suggested by the IEEE standard too))
leaves enough slack that you can certainly *not* guarantee that all
implementations will produce identical results. Contract that with
the basic arithmetic operations, where all operations have an exact
result in IEEE-754 terms (and mind you that many compilers, even on
reasonably IEEE compliant hardware, do *not* generate code that
produces IEEE compliant results, even for basic operations. Consider
the default operand widening performed/allowed by most x87 code
generators, so your problem is even worse (and an inappropriately
lengthened intermediate result may be what's actually passed to the
log function).


*Except when that's too hard and it's the "almost always one ULP, two
in a few cases we can't fix" rule.

 
Reply With Quote
 
Victor Bazarov
Guest
Posts: n/a
 
      09-27-2007
http://www.velocityreviews.com/forums/(E-Mail Removed) wrote:
> On Sep 26, 7:33 pm, "Victor Bazarov" <(E-Mail Removed)> wrote:
>> Right. I should have added 0.5:
>>
>> int ndigits = x > 0 ? int(log10(x + 0.5)) + 1 : 1;

>
>
> Now it won't work for 99.7, 999.7, 9999.7, etc. It's also not clear
> that this does what you want for numbers less than 1.


But there is no way to tell how many digits those numbers have! The
original solution was proposed for the *unsigned* 'x', IOW the one
that does NOT have a fractional part.

> I suggest you give this up, [..]


I suggest you reread the original post and think before you shoot next
time.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask


 
Reply With Quote
 
bejiz
Guest
Posts: n/a
 
      09-27-2007
Thanks for your answers. I wanted to know the number of digits so that
it would be possible to line up the columns of a matrix and choose an
appropriate size for the spaces. I now think I'll use cout.width() for
the spaces and the booleans with log10 for guessing the size. I think
it is possible finding the number of digits of a float by multiplying
it by a huge power of 10 and then removing the zeros dividing by 10
until the modulo is different from zero and counting the number of
digits in the final number.

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Re: Using %x to format number to hex and number of digits Tim Chase Python 2 11-06-2010 01:22 AM
Re: Using %x to format number to hex and number of digits Chris Rebert Python 1 11-05-2010 07:05 PM
extract digits from a number ? mark C++ 1 06-14-2004 12:32 AM
Number of digits of float value Marc Schellens C++ 4 04-21-2004 01:24 PM
Outlook Express - minimum number of digits for Account name John Computer Support 4 12-15-2003 08:13 PM



Advertisments