Re: counting the digits in a number, exponential format problem [message #171026 is a reply to message #170998] |
Wed, 15 December 2010 09:13 |
alvaro.NOSPAMTHANX
Messages: 277 Registered: September 2010
Karma:
|
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
--
|
|
|