FUDforum
Fast Uncompromising Discussions. FUDforum will get your users talking.

Home » Imported messages » comp.lang.php » counting the digits in a number, exponential format problem
Show: Today's Messages :: Polls :: Message Navigator
Switch to threaded view of this topic Create a new topic Submit Reply
counting the digits in a number, exponential format problem [message #170979] Mon, 13 December 2010 18:46 Go to next message
mhandersen is currently offline  mhandersen
Messages: 5
Registered: December 2010
Karma: 0
Junior Member
Hi,

I was wondering if anyone had a good way of counting the digits in a
given (general) number.

Obviously this is trivial for certain numbers. For example, the number
of digits in 523 (or any other natural number) can be found either by:

ceil(log10(523)) or strlen(523)… and I am sure there are other ways.

Once you start dealing with floats it gets a little more complicated,
but there are solutions. For example, the number of digits in 3.3 can
be found with:

$value = 3.3;
if ((int)$value == $value)
{
return strlen($value);
} else {
return strlen($value)-1; //the -1 removes the count for the ‘.’
}

In general the above equation SHOULD work for any float or double, but
it does not. My problem arises when PHP uses exponential formatting
and for some reason there is a break down at E-5. For example:

$value = 3.3E-4;
if ((int)$value == $value)
{
return strlen($value);
} else {
return strlen($value)-1;
}

returns the value 6, which is correct. (There are 6 digits in
0.00033). However, if we try:

$value = 3.3E-5;
if ((int)$value == $value)
{
return strlen($value);
} else {
return strlen($value)-1;
}

it returns 5. The reason it does this is because at E-5 it appears
that PHP stops using the full decimal value and leaves it in the
exponential format. Thus strlen no longer makes sense because it does
strlen(3.3E-5) (and treats not only the ‘.’ but also the ‘E’ and ‘-‘
as characters and includes them in the length calculation) instead of
converting the number to a value and performing strlen(0.000033). Even
if I alter the function to cast the value [return strlen((float)
$value)-1;] it still returns 5.

There is some difference in PHP between numbers which are E-4 and
numbers which are E-5. The numbers I care about go out to E-8.

If anyone knows why PHP does this, how to force PHP to not use
exponential formatting, or how to count digits in an exponentially
formatted float less than E-4 I would appreciate the help.

P.S. I have tried ini_set("precision", "12"); and the like, but that
does not help. My interest is not in adjusting PHP’s precision, only
how it treats the numbers.
Re: counting the digits in a number, exponential format problem [message #170985 is a reply to message #170979] Mon, 13 December 2010 19:28 Go to previous messageGo to next message
Jerry Stuckle is currently offline  Jerry Stuckle
Messages: 2598
Registered: September 2010
Karma: 0
Senior Member
On 12/13/2010 1:46 PM, -matt wrote:
> Hi,
>
> I was wondering if anyone had a good way of counting the digits in a
> given (general) number.
>
> Obviously this is trivial for certain numbers. For example, the number
> of digits in 523 (or any other natural number) can be found either by:
>
> ceil(log10(523)) or strlen(523)… and I am sure there are other ways.
>
> Once you start dealing with floats it gets a little more complicated,
> but there are solutions. For example, the number of digits in 3.3 can
> be found with:
>
> $value = 3.3;
> if ((int)$value == $value)
> {
> return strlen($value);
> } else {
> return strlen($value)-1; //the -1 removes the count for the ‘.’
> }
>
> In general the above equation SHOULD work for any float or double, but
> it does not. My problem arises when PHP uses exponential formatting
> and for some reason there is a break down at E-5. For example:
>
> $value = 3.3E-4;
> if ((int)$value == $value)
> {
> return strlen($value);
> } else {
> return strlen($value)-1;
> }
>
> returns the value 6, which is correct. (There are 6 digits in
> 0.00033). However, if we try:
>
> $value = 3.3E-5;
> if ((int)$value == $value)
> {
> return strlen($value);
> } else {
> return strlen($value)-1;
> }
>
> it returns 5. The reason it does this is because at E-5 it appears
> that PHP stops using the full decimal value and leaves it in the
> exponential format. Thus strlen no longer makes sense because it does
> strlen(3.3E-5) (and treats not only the ‘.’ but also the ‘E’ and ‘-‘
> as characters and includes them in the length calculation) instead of
> converting the number to a value and performing strlen(0.000033). Even
> if I alter the function to cast the value [return strlen((float)
> $value)-1;] it still returns 5.
>
> There is some difference in PHP between numbers which are E-4 and
> numbers which are E-5. The numbers I care about go out to E-8.
>
> If anyone knows why PHP does this, how to force PHP to not use
> exponential formatting, or how to count digits in an exponentially
> formatted float less than E-4 I would appreciate the help.
>
> P.S. I have tried ini_set("precision", "12"); and the like, but that
> does not help. My interest is not in adjusting PHP’s precision, only
> how it treats the numbers.

strlen() works on strings, not values (hence the name). And floating
point numbers are almost never exact values - i.e. 0.00033 is actually
0.00032999999999999999819588758498412062181159853935242 (plus or minus,
depending on your precision).

This is not PHP - this is how floating point numbers work in most
computers and languages (the exception being those which support BCD
formats).

As for formatting - there are any number of ways to format the data, i.e.

$s = sprintf("$12.10f");
echo strlen($s) . "->$s\n";

Prints

12->0.0000033000

Of course, you can also strip trailing zeros, if you wish.

--
==================
Remove the "x" from my email address
Jerry Stuckle
JDS Computer Training Corp.
jstucklex(at)attglobal(dot)net
==================
Re: counting the digits in a number, exponential format problem [message #170993 is a reply to message #170979] Tue, 14 December 2010 08:37 Go to previous messageGo to next message
alvaro.NOSPAMTHANX is currently offline  alvaro.NOSPAMTHANX
Messages: 277
Registered: September 2010
Karma: 0
Senior Member
El 13/12/2010 19:46, -matt escribió/wrote:
> I was wondering if anyone had a good way of counting the digits in a
> given (general) number.
>
> Obviously this is trivial for certain numbers. For example, the number
> of digits in 523 (or any other natural number) can be found either by:
>
> ceil(log10(523)) or strlen(523)… and I am sure there are other ways.
>
> Once you start dealing with floats it gets a little more complicated,
> but there are solutions. For example, the number of digits in 3.3 can
> be found with:
>
> $value = 3.3;
> if ((int)$value == $value)
> {
> return strlen($value);
> } else {
> return strlen($value)-1; //the -1 removes the count for the ‘.’
> }
>
> In general the above equation SHOULD work for any float or double, but
> it does not. My problem arises when PHP uses exponential formatting
> and for some reason there is a break down at E-5. For example:
>
> $value = 3.3E-4;
> if ((int)$value == $value)
> {
> return strlen($value);
> } else {
> return strlen($value)-1;
> }
>
> returns the value 6, which is correct. (There are 6 digits in
> 0.00033). However, if we try:
>
> $value = 3.3E-5;
> if ((int)$value == $value)
> {
> return strlen($value);
> } else {
> return strlen($value)-1;
> }
>
> it returns 5. The reason it does this is because at E-5 it appears
> that PHP stops using the full decimal value and leaves it in the
> exponential format. Thus strlen no longer makes sense because it does
> strlen(3.3E-5) (and treats not only the ‘.’ but also the ‘E’ and ‘-‘
> as characters and includes them in the length calculation) instead of
> converting the number to a value and performing strlen(0.000033). Even
> if I alter the function to cast the value [return strlen((float)
> $value)-1;] it still returns 5.
>
> There is some difference in PHP between numbers which are E-4 and
> numbers which are E-5. The numbers I care about go out to E-8.
>
> If anyone knows why PHP does this, how to force PHP to not use
> exponential formatting, or how to count digits in an exponentially
> formatted float less than E-4 I would appreciate the help.
>
> P.S. I have tried ini_set("precision", "12"); and the like, but that
> does not help. My interest is not in adjusting PHP’s precision, only
> how it treats the numbers.

I'm not sure the whole subject really makes sense. First of all, the
number of digits depends on the base (obviously). Second, a number with
a fixed number of digits in base 10 may not have a representation in
base 2 (e.g. 1.01). Third, there'll be lots of cases where you actually
have infinite digits and you just cut at certain threshold (1/3 = 1.333).

If you absolutely need to do it, I see no other method that handling
numbers as strings rather than floats and pick a maximum number of
decimals when necessary. Compare:

<?php
var_dump( pow(101, 40) );
var_dump( bcpow('101', '40') );
?>

float(1.4888637335882E+80)
string(81)
" 148886373358822087497126463801738296202951256788286744534662595050969228887 804001 "

<?
var_dump(2/3);
var_dump( bcdiv('2', '3', 2) );
var_dump( bcdiv('2', '3', 10) );
var_dump( bcdiv('2', '3', 20) );
?>

float(0.66666666666667)
string(4) "0.66"
string(12) "0.6666666666"
string(22) "0.66666666666666666666"

<?php
var_dump( 10000000000000+0.5 );
var_dump( bcadd('10000000000000', '0.5', 1) );
?>

float(10000000000000)
string(16) "10000000000000.5"


Whatever, it may help to know the exact reason why you need to count
digits in the first place. Perhaps there's a better solution :-?


--
-- http://alvaro.es - Álvaro G. Vicario - Burgos, Spain
-- Mi sitio sobre programación web: http://borrame.com
-- Mi web de humor satinado: http://www.demogracia.com
--
Re: counting the digits in a number, exponential format problem [message #170998 is a reply to message #170993] Tue, 14 December 2010 15:27 Go to previous messageGo to next message
mhandersen is currently offline  mhandersen
Messages: 5
Registered: December 2010
Karma: 0
Junior Member
maybe i did not word my question well enough... let me try again.

first of all, this is not a question about machine precision. i am
well aware of the limitations of floating point values and that some
(many) numbers are not actually able to be exactly represented by a
computer. for the sake of argument lets forget that, because i do not
think my question relates to it at all.

at its core, my question really wants to know why there is an
inconsistency in PHP shown by the following example:

strlen(3E-1) = strlen(0.3) = 3
strlen(3E-2) = strlen(0.03) = 4
strlen(3E-3) = strlen(0.003) = 5
strlen(3E-4) = strlen(0.0003) = 6

but then for some reason

strlen(3E-5) = strlen((float)3E-5) = strlen(0.00003) = 6
strlen(3E-6) = strlen((float)3E-5) = strlen(0.000003) = 6

don't get hung up on the numbers. this has happened for any number i
have chosen in the jump between E-4 and E-5. there just seems to be
some inconsistency in how PHP internally represents the variables. and
i would like to know if anyone know what it is, why it is, and/or how
to avoid it?

also, in response to Jerry, PHP is a weakly typed language which means
it doesn't require (nor support for that matter) explicit type
declaration of variables. so saying that strlen only works on strings
doesn't make sense. in PHP a variable is a variable is a variable.
there is no difference.

in response to Alvaro, the reason i would like to count the digits is
because i do not know how wide each number is in a set of numbers and
for each number i need to set a width for a placeholder for the
number. i do not want to force a certain number of digits to always be
outputted so it is constant width, so i would like to adjust my
placeholder width based on the number width.
Re: counting the digits in a number, exponential format problem [message #170999 is a reply to message #170998] Tue, 14 December 2010 16:51 Go to previous messageGo to next message
The Natural Philosoph is currently offline  The Natural Philosoph
Messages: 993
Registered: September 2010
Karma: 0
Senior Member
-matt wrote:
> maybe i did not word my question well enough... let me try again.
>
> first of all, this is not a question about machine precision. i am
> well aware of the limitations of floating point values and that some
> (many) numbers are not actually able to be exactly represented by a
> computer. for the sake of argument lets forget that, because i do not
> think my question relates to it at all.
>
> at its core, my question really wants to know why there is an
> inconsistency in PHP shown by the following example:
>
> strlen(3E-1) = strlen(0.3) = 3
> strlen(3E-2) = strlen(0.03) = 4
> strlen(3E-3) = strlen(0.003) = 5
> strlen(3E-4) = strlen(0.0003) = 6
>
> but then for some reason
>
> strlen(3E-5) = strlen((float)3E-5) = strlen(0.00003) = 6
> strlen(3E-6) = strlen((float)3E-5) = strlen(0.000003) = 6
>
> don't get hung up on the numbers. this has happened for any number i
> have chosen in the jump between E-4 and E-5. there just seems to be
> some inconsistency in how PHP internally represents the variables. and
> i would like to know if anyone know what it is, why it is, and/or how
> to avoid it?
>
> also, in response to Jerry, PHP is a weakly typed language which means
> it doesn't require (nor support for that matter) explicit type
> declaration of variables. so saying that strlen only works on strings
> doesn't make sense. in PHP a variable is a variable is a variable.
> there is no difference.

well

(a) thats jerry but
(b) internally it does know the difference, The fact that it seamlessly
converts between at its own whim is typical of the noddy approach of
modern languages and software, that likes to make what its designers
consider is the right decision on your behalf, because you are too
stoopid to tell it exactly what to do.

In Jerry's case, this is a fully justified assumption.

>
> in response to Alvaro, the reason i would like to count the digits is
> because i do not know how wide each number is in a set of numbers and
> for each number i need to set a width for a placeholder for the
> number. i do not want to force a certain number of digits to always be
> outputted so it is constant width, so i would like to adjust my
> placeholder width based on the number width.

well try something like strlen(sprintf("0.03%f",$mynum)) then..unless
you really want to force it, the language will have at some point a
decision whether to output in decimal or exponential format.
Re: counting the digits in a number, exponential format problem [message #171000 is a reply to message #170998] Tue, 14 December 2010 17:30 Go to previous messageGo to next message
Jerry Stuckle is currently offline  Jerry Stuckle
Messages: 2598
Registered: September 2010
Karma: 0
Senior Member
On 12/14/2010 10:27 AM, -matt wrote:
> maybe i did not word my question well enough... let me try again.
>
> first of all, this is not a question about machine precision. i am
> well aware of the limitations of floating point values and that some
> (many) numbers are not actually able to be exactly represented by a
> computer. for the sake of argument lets forget that, because i do not
> think my question relates to it at all.
>
> at its core, my question really wants to know why there is an
> inconsistency in PHP shown by the following example:
>
> strlen(3E-1) = strlen(0.3) = 3
> strlen(3E-2) = strlen(0.03) = 4
> strlen(3E-3) = strlen(0.003) = 5
> strlen(3E-4) = strlen(0.0003) = 6
>
> but then for some reason
>
> strlen(3E-5) = strlen((float)3E-5) = strlen(0.00003) = 6
> strlen(3E-6) = strlen((float)3E-5) = strlen(0.000003) = 6
>
> don't get hung up on the numbers. this has happened for any number i
> have chosen in the jump between E-4 and E-5. there just seems to be
> some inconsistency in how PHP internally represents the variables. and
> i would like to know if anyone know what it is, why it is, and/or how
> to avoid it?
>
> also, in response to Jerry, PHP is a weakly typed language which means
> it doesn't require (nor support for that matter) explicit type
> declaration of variables. so saying that strlen only works on strings
> doesn't make sense. in PHP a variable is a variable is a variable.
> there is no difference.
>

Untrue. There are differences between various types; it's just that PHP
converts between them under the covers. And sometimes this causes
problems, i.e. 0 == false, but 0 !== false.

If you give strlen() a numeric value, PHP has to convert this to a
string before taking the length. The result may or may not be what you
want.

For more information on types, see
http://www.php.net/manual/en/language.types.php.

For more information on type juggling, see
http://www.php.net/manual/en/language.types.type-juggling.php

--
==================
Remove the "x" from my email address
Jerry Stuckle
JDS Computer Training Corp.
jstucklex(at)attglobal(dot)net
==================
Re: counting the digits in a number, exponential format problem [message #171001 is a reply to message #171000] Tue, 14 December 2010 18:50 Go to previous messageGo to next message
mhandersen is currently offline  mhandersen
Messages: 5
Registered: December 2010
Karma: 0
Junior Member
certainly at some level PHP must know the difference between a string
and a float, but you can't a define a variable yourself as such. all i
was saying is that strlen() takes a variable, type of that variable
cannot be declared. i understand that strlen is intended for use with
'strings' but it also works for floats up to E-4 after which it breaks
down... all i am wondering is why???

i tried the strlen(sprintf("0.03%f",$mynum)) suggestion (and several
iterations of it) but no luck. i am not sure where PHP makes the
decision on whether or not to convert to a decimal but that doesn't
appear to help.

@Jerry: i totally agree with you that PHP must convert a numeric value
passed to strlen() to a string at some point. what i do not understand
though is why it makes a difference whether the numeric is 1E-4 or
1E-5. it is like that single order of magnitude drastically changes
the logic/conversion process of the numeric to a string and causes the
answer to not, as you say, 'be what i want'.

it is just not consistent at all. imho a function like strlen() should
pick one way of handling a type of input and do it consistently, not
vary its approach depending on the size of a value passed to it...
especially when it is a weakly typed language.

it appears as though PHP might use something similar to the Linux
function strtod(3) to do its string to float conversions. however, the
man page:
http://linux.die.net/man/3/strtod
does not shed any light on my problem.
Re: counting the digits in a number, exponential format problem [message #171003 is a reply to message #171001] Tue, 14 December 2010 19:51 Go to previous messageGo to next message
ED is currently offline  ED
Messages: 1
Registered: December 2010
Karma: 0
Junior Member
"-matt" <mhandersen(at)gmail(dot)com> wrote in message
news:2592bddb-447c-4fd3-afae-da8bb35cfa0c(at)r29g2000yqj(dot)googlegroups(dot)com...
> certainly at some level PHP must know the difference between a string
> and a float, but you can't a define a variable yourself as such. all i
> was saying is that strlen() takes a variable, type of that variable
> cannot be declared. i understand that strlen is intended for use with
> 'strings' but it also works for floats up to E-4 after which it breaks
> down... all i am wondering is why???
>
> i tried the strlen(sprintf("0.03%f",$mynum)) suggestion (and several
> iterations of it) but no luck. i am not sure where PHP makes the
> decision on whether or not to convert to a decimal but that doesn't
> appear to help.
>
> @Jerry: i totally agree with you that PHP must convert a numeric value
> passed to strlen() to a string at some point. what i do not understand
> though is why it makes a difference whether the numeric is 1E-4 or
> 1E-5. it is like that single order of magnitude drastically changes
> the logic/conversion process of the numeric to a string and causes the
> answer to not, as you say, 'be what i want'.
>
> it is just not consistent at all. imho a function like strlen() should
> pick one way of handling a type of input and do it consistently, not
> vary its approach depending on the size of a value passed to it...
> especially when it is a weakly typed language.
>
> it appears as though PHP might use something similar to the Linux
> function strtod(3) to do its string to float conversions. however, the
> man page:
> http://linux.die.net/man/3/strtod
> does not shed any light on my problem.

hi Matt,

The strval function should shed some light here in seeing how php interally
represets the string value of the floats, eg:

echo strval(3E-1); // '0.3'
echo strval(3E-2); // '0.03'
echo strval(3E-3); // '0.003'
echo strval(3E-4); // '0.0003'
echo strval(3E-5); // '3.0E-5'
echo strval(3E-6); // '3.0E-6'

ie after 4 decimal places php will represent the string value of the float
in exponential format.

also see -
http://www.php.net/manual/en/language.types.string.php#language.types.strin g.casting
"An integer or float is converted to a string representing the number
textually (including the exponent part for floats). Floating point numbers
can be converted using exponential notation (4.1E+6)."

Cheers
ED
Re: counting the digits in a number, exponential format problem [message #171007 is a reply to message #171003] Tue, 14 December 2010 21:50 Go to previous messageGo to next message
mhandersen is currently offline  mhandersen
Messages: 5
Registered: December 2010
Karma: 0
Junior Member
@ED: thanks for the reply. at least that helps me understand whats
going on.

i guess what i really want now then is a way to turn off exponential
formatting. i don't like that:

echo floatval(3E-5); // '3.0E-5'
echo strval(3E-5); // '3.0E-5'
echo floatval(0.00003); // '3.0E-5'
echo strval(0.00003); // '3.0E-5'

the strval() output is understandable (now). i could even deal with
the output of floatval(3E-5), but why does it feel the need to convert
to exponential formatting with floatval(0.00003)? 3.0E-5 is much more
'sting like' than 0.00003 is to me, so why would you convert it to the
string form if preforming a numeric operation on the value?

i know that i can can display it however i want with something like
printf("%f",3E-5); but that doesn't help me "count digits" as my
original question asked...


thanks everyone for your input.
Re: counting the digits in a number, exponential format problem [message #171026 is a reply to message #170998] Wed, 15 December 2010 09:13 Go to previous messageGo to next message
alvaro.NOSPAMTHANX is currently offline  alvaro.NOSPAMTHANX
Messages: 277
Registered: September 2010
Karma: 0
Senior Member
El 14/12/2010 16:27, -matt escribió/wrote:
> maybe i did not word my question well enough... let me try again.

Most points have already been answered but I'll provide my own
explanation anyway ;-)

>
> first of all, this is not a question about machine precision. i am
> well aware of the limitations of floating point values and that some
> (many) numbers are not actually able to be exactly represented by a
> computer. for the sake of argument lets forget that, because i do not
> think my question relates to it at all.
>
> at its core, my question really wants to know why there is an
> inconsistency in PHP shown by the following example:
>
> strlen(3E-1) = strlen(0.3) = 3
> strlen(3E-2) = strlen(0.03) = 4
> strlen(3E-3) = strlen(0.003) = 5
> strlen(3E-4) = strlen(0.0003) = 6
>
> but then for some reason
>
> strlen(3E-5) = strlen((float)3E-5) = strlen(0.00003) = 6
> strlen(3E-6) = strlen((float)3E-5) = strlen(0.000003) = 6
>
> don't get hung up on the numbers. this has happened for any number i
> have chosen in the jump between E-4 and E-5. there just seems to be
> some inconsistency in how PHP internally represents the variables. and
> i would like to know if anyone know what it is, why it is, and/or how
> to avoid it?

Let's have a look at the function definition <http://php.net/strlen>:

Description
int strlen ( string $string )

Returns the length of the given string.

As the manual states, this function works on strings.


> also, in response to Jerry, PHP is a weakly typed language which means
> it doesn't require (nor support for that matter) explicit type
> declaration of variables. so saying that strlen only works on strings
> doesn't make sense. in PHP a variable is a variable is a variable.
> there is no difference.

As almost all langs out there, PHP *has* data types. Otherwise, how
could do simple math with variables? You can see it yourself if you
inspect stuff with var_dump() which is, by the way, the recommended way
to see the actual contents of variables:

<?php var_dump(0, 0.1, '0', TRUE, FALSE); ?>

int(0)
float(0.1)
string(1) "0"
bool(true)
bool(false)

PHP is, however, *loosely typed*. That means that a variable can hold
any data type, unlike other langs where you must declare a type and are
forced to use it. E.g., you cannot do this in C:

int i = 7;
i = 3.14; /* Error */

.... but you can in PHP:

$i = 7; // int(7)
$i = 3.14; //float(3.14)

It also means that PHP always performs transparent type casting when
necessary, no matter how stupid it may seem:

$i = pow(10, "Bunnies") / TRUE; // int(1)

And this is the precise reason why you can actually do this:

strlen(33);

C, Java or other strongly typed languages would never allow you to pass
a number to a function that expects a string. Your code would not even
compile. PHP allows you to strlen(33) and it's not because strlen() can
calculate the length of a number (it cannot); it's because it casts the
argument to string before applying its string abilities.

The casting is performed with precise rules that are documented:

http://es.php.net/manual/en/language.types.type-juggling.php
http://es.php.net/manual/en/language.types.string.php#language.types.string .casting

It happens that rules are not always intuitive:

$i = (string)TRUE; // string(1) "1"
$i = (string)FALSE; // string(0) ""

.... which can lead to surprising (yet expected) results:

$i = strlen(TRUE); // int(1)
$i = strlen(FALSE); // int(0)

.... and also explains why plain echo statements are not a good debugging
tool:

echo 4<3; // Prints nothing
var_dump(4<3); // Prints bool(false)


> in response to Alvaro, the reason i would like to count the digits is
> because i do not know how wide each number is in a set of numbers and
> for each number i need to set a width for a placeholder for the
> number. i do not want to force a certain number of digits to always be
> outputted so it is constant width, so i would like to adjust my
> placeholder width based on the number width.

Alright, you don't really want to know the length of a numeric variable.
You know to want the length of its string representation. That's easy to
calculate but clearly depends of how you want to display the number:

1000
1,000
1,000.00
0001000
....

You just need to pick a string representation, generate such string and
strlen() it:

$display = number_format(20000/3, 2, '.', ','); // 6,666.67
$length = strlen($display); // 8

If you just strlen() a float variable you're telling PHP: please format
the number to your liking and tell me how room it takes. It won't lie
because that's exactly the number of characters it'll use to echo it.



--
-- http://alvaro.es - Álvaro G. Vicario - Burgos, Spain
-- Mi sitio sobre programación web: http://borrame.com
-- Mi web de humor satinado: http://www.demogracia.com
--
Re: counting the digits in a number, exponential format problem [message #171031 is a reply to message #171026] Wed, 15 December 2010 15:53 Go to previous messageGo to next message
mhandersen is currently offline  mhandersen
Messages: 5
Registered: December 2010
Karma: 0
Junior Member
@Alvaro: thanks for your reply. i am by no means a PHP expert
(obviously) so this is all good information.

> Alright, you don't really want to know the length of a numeric variable.
> You know to want the length of its string representation. That's easy to
> calculate but clearly depends of how you want to display the number:

exactly!!! the only problem is that i have no control of how the
number comes to me, nor how it is displayed later. however, it is
always displayed using full decimal form with the least number of
digits and no commas. for example: 1234 not 1,234.0, etc. the problem
i was having is how PHP changes its conversion process to strings for
float from E-4 to E-5. that is what has been really throwing me off.
however, i think i have a working solution now for my original
problem. below is my function if anyone cares to see my solution:

function numberOfDigits($value)
{
if(!is_numeric($value))
{
return 0;
}
if((int)$value == $value)
{
return strlen((int)$value);
}
for($i=1; $i<=10; $i+=1)
{
$temp = $value * pow(10,$i);
if((int)$temp == $temp)
{
if((int)$value == 0)
{
return $i + 1;
}
else
{
return strlen($temp);
}
}
}
return strlen((int)$value) + 10;
}

echo numberOfDigits(1); // '1'
echo numberOfDigits(123.456); // '6'
echo numberOfDigits(1.0); // '1'
echo numberOfDigits(0.33); // '3'
echo numberOfDigits(0.033); // '4'
echo numberOfDigits(0.0033); // '5'
echo numberOfDigits(0.00033); // '6'
echo numberOfDigits(3.3E-5); // '7'
echo numberOfDigits(3.3E-6); // '8'
echo numberOfDigits(3.3E-7); // '9'

i use a for loop which only goes to $i=10 because i really only care
about numbers down to E-9ish. clearly you could change that to a while
loop or something and make the function more general.

thanks again everyone for all the help and information.
Re: counting the digits in a number, exponential format problem [message #171032 is a reply to message #171031] Wed, 15 December 2010 16:15 Go to previous messageGo to next message
Jerry Stuckle is currently offline  Jerry Stuckle
Messages: 2598
Registered: September 2010
Karma: 0
Senior Member
On 12/15/2010 10:53 AM, -matt wrote:
> @Alvaro: thanks for your reply. i am by no means a PHP expert
> (obviously) so this is all good information.
>
>> Alright, you don't really want to know the length of a numeric variable.
>> You know to want the length of its string representation. That's easy to
>> calculate but clearly depends of how you want to display the number:
>
> exactly!!! the only problem is that i have no control of how the
> number comes to me, nor how it is displayed later. however, it is
> always displayed using full decimal form with the least number of
> digits and no commas. for example: 1234 not 1,234.0, etc. the problem
> i was having is how PHP changes its conversion process to strings for
> float from E-4 to E-5. that is what has been really throwing me off.
> however, i think i have a working solution now for my original
> problem. below is my function if anyone cares to see my solution:
>
> function numberOfDigits($value)
> {
> if(!is_numeric($value))
> {
> return 0;
> }
> if((int)$value == $value)
> {
> return strlen((int)$value);
> }
> for($i=1; $i<=10; $i+=1)
> {
> $temp = $value * pow(10,$i);
> if((int)$temp == $temp)
> {
> if((int)$value == 0)
> {
> return $i + 1;
> }
> else
> {
> return strlen($temp);
> }
> }
> }
> return strlen((int)$value) + 10;
> }
>
> echo numberOfDigits(1); // '1'
> echo numberOfDigits(123.456); // '6'
> echo numberOfDigits(1.0); // '1'
> echo numberOfDigits(0.33); // '3'
> echo numberOfDigits(0.033); // '4'
> echo numberOfDigits(0.0033); // '5'
> echo numberOfDigits(0.00033); // '6'
> echo numberOfDigits(3.3E-5); // '7'
> echo numberOfDigits(3.3E-6); // '8'
> echo numberOfDigits(3.3E-7); // '9'
>
> i use a for loop which only goes to $i=10 because i really only care
> about numbers down to E-9ish. clearly you could change that to a while
> loop or something and make the function more general.
>
> thanks again everyone for all the help and information.

But you DO have control. Just format the number yourself, instead of
using the default PHP formatting.

The defaults are there to make life easier. However, they don't work in
all circumstances. When that happens, there are (almost, anyway) always
ways to do the job yourself.

--
==================
Remove the "x" from my email address
Jerry Stuckle
JDS Computer Training Corp.
jstucklex(at)attglobal(dot)net
==================
Re: counting the digits in a number, exponential format problem [message #176341 is a reply to message #171001] Fri, 23 December 2011 19:00 Go to previous messageGo to next message
gordonb.hojoy is currently offline  gordonb.hojoy
Messages: 1
Registered: December 2011
Karma: 0
Junior Member
> @Jerry: i totally agree with you that PHP must convert a numeric value
> passed to strlen() to a string at some point. what i do not understand
> though is why it makes a difference whether the numeric is 1E-4 or
> 1E-5. it is like that single order of magnitude drastically changes
> the logic/conversion process of the numeric to a string and causes the
> answer to not, as you say, 'be what i want'.

Read the description of the (C language, but also applies to PHP)
*printf format conversion %g. "The argument is printed in style f
or in style e, whichever gives full precision in minimum space".
Guess where it switches?

I assume that in PHP, strlen($x), where $x is a floating-point
number, is equivalent to strlen(sprintf("%g", $x)), and experimentation
seems to bear this out.

I suggest that you explicitly convert the number into a string using
the format that you want (e.g. %f, not %g, or else use a format
explicitly specifying precision) and apply strlen() to that. Do
not apply strlen() to floating-point numbers.


> it is just not consistent at all. imho a function like strlen() should
> pick one way of handling a type of input and do it consistently, not
> vary its approach depending on the size of a value passed to it...
> especially when it is a weakly typed language.

I suspect that strlen() does not get to pick anything. It's done before
strlen() gets its hands on it.

> it appears as though PHP might use something similar to the Linux
> function strtod(3) to do its string to float conversions. however, the

You are concerned with float to string conversions, not the other
way around.

> man page:
> http://linux.die.net/man/3/strtod
> does not shed any light on my problem.
Re: counting the digits in a number, exponential format problem [message #176342 is a reply to message #176341] Sat, 24 December 2011 03:31 Go to previous message
Denis McMahon is currently offline  Denis McMahon
Messages: 634
Registered: September 2010
Karma: 0
Senior Member
On Fri, 23 Dec 2011 13:00:44 -0600, Gordon Burditt wrote:

>> @Jerry: i totally agree with you that PHP must convert a numeric value
>> passed to strlen() to a string at some point. what i do not understand
>> though is why it makes a difference whether the numeric is 1E-4 or
>> 1E-5. it is like that single order of magnitude drastically changes the
>> logic/conversion process of the numeric to a string and causes the
>> answer to not, as you say, 'be what i want'.
>
> Read the description of the (C language, but also applies to PHP)
> *printf format conversion %g. "The argument is printed in style f or in
> style e, whichever gives full precision in minimum space". Guess where
> it switches?

For the specific case given by the OP, it could switch over at 1.0E-3 /
1.0E-4 instead of 1.0E-4 / 1.0E-5, given that both representations give
the same number of characters.

0.001 = 1.0E-3 <- fixed format shorter
0.0001 = 1.0E-4 <- both same length
0.00001 = 1.0E-5 <- exp format shorter

In the more general case, it won't always switch over at the E-4 / E-5
boundary either, it seems from writing down various decimal fractions in
both formats that E-3 is more commonly the point where both forms take
the same space. Where the exponent is -2 or higher (in the sense that 0
is higher than -1 is higher than -2) then the number will probably be
displayed in fixed format, and where the exponent is -5 or lower (in the
same sense as above) then the number will probably be displayed in
exponential format, but if the exponent is 3 or 4, then it depends on the
number of significant digits. In the latter case, behaviour might change
in future if the underlying c function changes slightly, even though such
a change might not result in the described operation of that function
being any different to the currently described and observed operation.

I guess that when the exponent travels away from 0 in a positive
direction the effect doesn't occur, because if the digits to the left of
the fixed format decimal point are significant, adding an exponent will
always increase the space taken by the space used by the exponential
representation:

1234567890.0123456789
1.2345678900123456789E9

Rgds

Denis McMahon
  Switch to threaded view of this topic Create a new topic Submit Reply
Previous Topic: width measurements?
Next Topic: cheap, discount nike air max shoes, paypal payment, free shipping
Goto Forum:
  

-=] Back to Top [=-
[ Syndicate this forum (XML) ] [ RSS ]

Current Time: Sat Nov 30 07:50:40 GMT 2024

Total time taken to generate the page: 0.02851 seconds