number with no quotation in php - php

the php code is pretty simple :
<?php
$my_bn_num=number_bangla(0123);
function number_bangla($num1){
echo ("<br>num =".$num1);
}
?>
And the ouput is: num=83
But if I call the function with a singly quoted string like this:
$my_bn_num=number_bangla('0123');
the output is: num=0123
What is the detailed difference between 0123 and '0123' here ?

0123 is an octal integer because it starts with 0.
Integers will be printed by echo/print as decimal numbers.
'0123' is a string, so nothing will be converted when it is printed.

0123 is a numeric value whereas '0123' is a string value. Internally PHP stores those types differently.
In order to cast string to integer you can do following:
$num = (int) $num;
In this particular example printing number 0123 results to 83 because 0123 is an octal value. For casting octal strings to octal numbers PHP offers octdec() function:
$num = octdec($num);

0123 is an octal number. In most scripting languages any number represented by a 0 in front of it is treated as if it were an octal number (since you normally don't put 0's in front of numbers.
When you specify it in quotes its treated as a string.
When you are handling integers and want them in a particular format, what you should do is use the intval function.
intval($num,10) would translate the variable $num to a base-10 integer, instead of relying on the PHP casting code to work its black magic.

Related

Convert a string containing a number in scientific notation to a normal string in PHP

I need help converting a string that contains a number in scientific notation to a normal string.
Example strings: "9.1892E+11" to "918919850755"
PHP should understand the scientific notation.
By substracting or adding 0 or something, it will change to a normal notation.
By doing this you might lose precision.
You can cast the string to a float to prevent this.
$number = (float)$number;

Casting zero padded numeric strings to integers

I am padding integers for barcodes with leading zeros so they have same number of characters, for example:
1 -> 00000001
12 -> 00000012
1044 -> 00001044
00000001 is numeric and when casting to an integer it is 1.
Will this work as expected for all integers?
Careful, numbers starting with 0 are treated as base 8 in PHP
>> var_dump(011);
int(9)
however explicit casting string to int seems to be safe
>> var_dump((int)'011');
int(11)
You did not say anything where you're going to be storing these numbers, but in case it will be a database, here's some advice regarding datatype:
Barcode numbers are not (despite the name) numbers. Same goes for fax numbers, social security numbers, etc. You should not store these as numeric data (for example using MySQL's INT or DECIMAL) datatype. Instead use textual datypes (like CHAR or VARCHAR)
Unless you treat it as a string PHP will interpret 00000001 as simply the integer 1. If you want to treat your barcodes as a string, take care to cast them correctly because PHP might interpret them as integers due to type juggling.
Will this work as expected for all ints?
That depends on what you expect. Left-padding with zeros will never change the value. Regardless of the number, you can add any number of zeros to the left of the string and it will always be numeric, and it will always cast to the same integer.
(int)"01" == 1
(int)"0001" == 1
(int)"000000001" == 1
etc.

inconsistency in converting string to integer, when string is hex, prefixed with '0x'

Using PHP 5.3.5. Not sure how this works on other versions.
I'm confused about using strings that hold numbers, e.g., '0x4B0' or '1.2e3'. The way how PHP works with such strings seems inconsistent to me. Is it only me? Or is it a bug? Or undocumented feature? Or am I just missing some magic sentence in docs?
<?php
echo $str = '0x4B0', PHP_EOL;
echo "is_numeric() -> ", var_dump(is_numeric($str)); // bool(true)
echo "*1 -> ", var_dump($str * 1); // int(1200)
echo "(int) -> ", var_dump((int)$str); // int(0)
echo "(float) -> ", var_dump((float)$str); // float(0)
echo PHP_EOL;
echo $str = '1.2e3', PHP_EOL;
echo "is_numeric() -> ", var_dump(is_numeric($str)); // bool(true)
echo "*1 -> ", var_dump($str * 1); // float(1200)
echo "(int) -> ", var_dump((int)$str); // int(1)
echo "(float) -> ", var_dump((float)$str); // float(1200)
echo PHP_EOL;
In both cases, is_numeric() returns true. Also, in both cases, $str * 1 parses string and returns valid number (integer in one case, float in another case).
Casting with (int)$str and (float)$str gives unexpected results.
(int)$str in any case is able to parse only digits, with optional "+" or "-" in front of them.
(float)$str is more advanced and can parse something like ^[+-]?\d*(\.\d*)?(e[+-]?\d*)?, i.e., optional "+" or "-", followed by optional digits, followed by optional decimal point with optional digits, followed by optional exponent which consists of "e" with optional "+" or "-" followed by optional digits. Fails on hex data though.
Related docs:
is_numeric() - states that "Hexadecimal notation (0xFF) is allowed too but only without sign, decimal and exponential part". If function, meant to test if a string holds numeric data, returns true, I expect PHP to be able to convert such string to a number. This seems to work with $str * 1, but not with casting. Why?
Converting to integer - states that "in most cases the cast is not needed, since a value will be automatically converted if an operator, function or control structure requires an integer argument". After such statement, I expect both $s * 10 and (int)$s * 10 expressions to work the same way and to return the same result. Though, as shown in example, those expressions are evaluated differently.
String conversion to numbers - states that "Valid numeric data is an optional sign, followed by one or more digits (optionally containing a decimal point), followed by an optional exponent". "Exponent" is "e" or "E", followed by digits, e.g., 1.2e3 is valid numeric data. Sign ("+" or "-") is not mentioned. It does not mention hexidecimal values. This conflicts with definition of "numeric data" used in is_numeric(). Then, there is suggestion "For more information on this conversion, see the Unix manual page for strtod(3)", and man strtod describes additional numeric values (including HEX notation). So, after reading this, is hexidecimal data supposed to be valid or invalid numeric data?
So...
Is there (or, rather, should there be) any relation between is_numeric() and the way how PHP treats strings when they are used as numbers?
Why do (int)$s, (float)$s and $s * 1 work differently, i.e,. give completely different results, when $s is 0x4B0 or 1.2e3?
Is there any way to convert a string to a number and keep its value, if it is written as 0x4B0 or as 1.2e3? floatval() does not work with HEX at all, intval() needs $base to be set to 16 to work with HEX, typecasting with (int)$str and (float)$str sometimes works, sometimes does not work, so these are not valid options. I'm also not considering $n *= 1;, as it looks more like data manipulation rather than converting. Self-written functions also are not considered in this case, as I'm looking for native solution.
The direct casts (int)$str and (float)$str don't really work differently at all: They both read as many characters from the string as they can interpret as a number of the respective type.
For "0x4B0", the int-conversion reads "0" (OK), then "x" and stops, because it cannot convert "x" into an integer. Likewise for the float-conversion.
For "1.2e3", the int-conversion reads "1" (OK), then "." and stops. The float-conversion recognises the entire string as valid float notation.
The automatic type recognition for an expression like $str * 1 is simply more flexible than the explicit casts. The explicit casts require the integers and floats to be in the format produced by %i and %f in printf, essentially.
Perhaps you can use intval and floatval rather than explicit casts-to-int for more flexibility, though.
Finally, your question "is hexidecimal data supposed to be valid or invalid numeric data?" is awkward. There is no such thing as "hexadecimal data". Hexadecimal is just a number base. What you can do is take a string like "4B0" and use strtoul etc. to parse it as an integer in any number base between 2 and 36.[Sorry, that was BS. There's no strtoul in PHP. But intval has the equivalent functionality, see above.]
intval uses strtol which recognizes oct/hex prefixes when the base parameter is zero, so
var_dump(intval('0xef')); // int(0)
var_dump(intval('0xff', 0)); // int(255)
Is there (or, rather, should there be) any relation between is_numeric() and the way how PHP treats strings when they are used as numbers?
There is no datatype called numeric in PHP, the is_numeric() function is more of a test for something that can be interpreted as number by PHP.
As far as such number interpreting is concerned, adding a + in front of the value will actually make PHP to convert it into a number:
$int = +'0x4B0';
$float = +'1.2e3';
You find this explained in the manual for string, look for the section String conversion to numbers.
As it's triggered by an operator, I don't see any need why there should be a function in PHP that does the same. That would be superfluous.
Internally PHP uses a function called zendi_convert_scalar_to_number for the add operator (assumable +) that will make use of is_numeric_string to obtain the number.
The exact same function is called internally by is_numeric() when used with strings.
So to trigger the native conversion function, I would just use the + operator. This will ensure that you'll get back the numeric pseudo-type (int or float).
Ref: /Zend/zend_operators.c; /ext/standard/type.c

int variable with leading zero?

Why is it that following results in 34?
It doesn't seem to have anything to do with octal numbers.
intval(042);
but a leading 0 does indicate octal in many languages, as is the case here.
It does have to do with octal numbers, 042 is interpreted as the octal number 42 which is 4 * 8 + 2 = 34.
Please be aware that the octal interpretation happens when the number literal is parsed while loading the PHP script. It has nothing to do with intval(), which doesn't do anything here because the value is already integer.
Octal interpretation happens only with number literals, not when casting a string to integer:
intval(042) // == 34
intval('042') // == 42
(int)'042' // == 42
In PHP a number with leading 0 is read as an octal number.
So 042 is read as an octal number.
The intval() function converts it into decimal number, which is 34.
So the browser output is 34.
It's simply how the function is defined. The leading zero is an instruction parse it as an octal number, similarly as to how 0x as a prefix means hex. See the documentation for more information.
Be careful when passing this function a string value with a leading "0". If you give it "042" then, it will treat it as BASE 8 - 9 and convert it to decimal value, which is by default base.
Please go through this

PHP comparison '==' problem

Why is the output 'in'?
<?php
if (1=='1, 3')
{
echo "in";
}
?>
The == operator does type conversion on the two values to try to get them to be the same type. In your example it will convert the second value from a string into an integer, which will be equal to 1. This is then obviously equal to the value you're matching.
If your first value had been a string - ie '1' in quotes, rather than an integer, then the match would have failed because both sides are strings, so it would have done a string comparison, and they're different strings.
If you need an exact match operator that doesn't do type conversion, PHP also offers a tripple-equal operator, ===, which may be what you're looking for instead.
Hope that helps.
Because PHP is doing type conversion, it's turning a string into an integer, and it's methods of doing so work such that it counts all numbers up until a non-numeric value. In your case that's the substring ('1') (because , is the first non-numeric character). If you string started with anything but a number, you'd get 0.
You are comparing a string and an integer. The string must be converted to an integer first, and PHP converts numeric strings to integers. Since the start of that string is '1', it compares the number one, with the number one, these are equal.
What functionality did you intend?
If you're trying to check if 1 is equal to 1 or 3, then I would definitely do it this way:
if (1 == 1 || 1 == 3)
Please refer to the PHP documentation:
http://php.net/manual/en/language.operators.comparison.php
The output should be:
in
From PHP's documentation:
When converting from a string to an
integer, PHP analyzes the string one
character at a time until it finds a
non-digit character. (The number may,
optionally, start with a + or - sign.)
The resulting number is parsed as a
decimal number (base-10). A failure to
parse a valid decimal number returns
the value 0.
I'm guessing you want to know whether a variable is in a range of values.
You can use in_array:
if (in_array(1, array(1, 3, 5, 6)))
echo "in";
if(in_array(1, array(1,3)) {
echo "in";
}

Categories