Why does "echo strcmp('60', '100');" in php output 5? - php

PHP's documentation on this function is a bit sparse and I have read that this function compares ASCII values so...
echo strcmp('hello', 'hello');
//outputs 0 as expected - strings are equal.
echo '<hr />';
echo strcmp('Hello', 'hello');
//outputs -32, a negative number is expected as
//uppercase H has a lower ASCII value than lowercase h.
echo '<hr />';
echo strcmp('60', '100');
//outputs 5.
The last example is confusing me. I don't understand why it is outputting a positive number.
ASCII Value of 0 = 48
ASCII Value of 1 = 49
ASCII Value of 6 = 54
Total ASCII value of '60' = (54 + 48) = 102
Total ASCII value of '100' = (49 + 48 + 48) = 145
The strcmp() functions is saying that '60' is "greater" than '100' even though it seems that the ASCII value and string length of '100' is greater than '60'
Can anyone explain why?
Thanks

strcmp() returns the difference of the first non-matching character between the strings.
6 - 1 is 5.
When you look at it, you are probably not seeing the characters or digits—just the numbers

Because strcmp() stops at the first difference it finds. Hence the difference between the ASCII value of '1' and the ASCII value of '6'

6 is 5 "larger" than 1. This is lexical comparison. The first character is different, that's where the comparison stops.

Related

Why only hex recognized but not octal and byte if the left hand operand is a number in an expression

First expression:
displays 123 octal, is not recognized, if recognized it should be 83
Second Expression:
displays 291, here hex recognized, if not recognized it should be 123
Third Expression:
Displays 0
$y = 0+"0123";
echo $y;
echo '<br>';
$x = 0+"0x123";
echo $x;
echo '<br>';
$x = 0+"0b10101";
echo $x; // This displays 0
output:
123
291
0
See the documentation at http://php.net/manual/en/language.types.string.php#language.types.string.conversion
The value is given by the initial portion of the string. If the string
starts with valid numeric data, this will be the value used.
Otherwise, the value will be 0 (zero). Valid numeric data is an
optional sign, followed by one or more digits (optionally containing a
decimal point), followed by an optional exponent. The exponent is an
'e' or 'E' followed by one or more digits.
There is no mention of non-decimal support.
PHP casting of strings to numbers is limited (and probably with good reason). If you want to use different base numbers you need to specify them as numbers e.g.
$y = 0123;
echo $y; // 83
$x = 0x123;
echo $x; // 291
$x = 0b10101;
echo $x; // 21
Notice that they are not quoted.
If you want to explicitly convert strings you need to do the following:
echo octdec("0123"); // 83
echo hexdec("0x123"); // 291
echo bindec("0b10101"); // 21
The prefixes (e.g. 0 or 0x or 0b) are allowed but optional when using these functions.
Note: PHP used to support implicit casting of hex strings as numbers but as of 7.0 it does not

Weird output, when number starts with 0

1. script:
$num = "00445790";
echo $num;
returns:
00445790
2. script
$num = 00445790;
echo $num;
returns:
2351
Can somebody explain why I get 2351 on the second script?
Integers that start with zero are consider octal. Because octal integers only use numbers from 0 to 8 everything from the 9 on are ignored.
So 00445790 becomes 004457 which is 2351 in decimal.

PHP rand explanation using an array?

I have very little programming experience but I am going over a php book and this block of code is confusing me.
If rand generates a random integer, how does this program use ABCDEFG in the array.
Can you please explain the program thank you. I know what the result is, I am just not sure how it get it.
<?php
$array = '123456789ABCDEFG';
$s = '';
for ($i=1; $i < 50; $i++) {
$s.= $array[rand(0,strlen($array)-1)]; //explain please
}
echo $s;
?>
It's using the array index so $array[11] would equal 'C'. rand() takes a range - in your example that's from 0 to strlen($array)-1 which is the length of the string, minus 1 since it's a 0 based index.
Break it down into parts:
strlen($array) - returns the length of the string in $array, which would be 17
strlen($array) - 1 => 16
rand(0, 16) - generate a random number between 0 and 16
$array[$random_number] - get the $random_number'th element of the array
Its just taking the length of the array with strlen($array). It doesn't matter what is in the string just the length. Then its generating a random number between 0 and the length of the string minus one.
Then it takes whatever character is in that position in the array (so $array[5] would be '6', $array[12] would be 'C', etc) and appending that to string $s. It then has a for loop to repeat it 50 times.
What you end up with is a random string that is 50 characters long and contains the numbers 1-9 and letters A-G.

Unexpected bitwise operation result [duplicate]

This question already has answers here:
What's the function of the ~ bitwise operator (Tilde) [duplicate]
(3 answers)
Closed 9 years ago.
Consider:
php > $a = 12; // 1100
php > echo ~$a;
-13
I would expect the inverse of 1100 to be either 0011 (direct) or 11110011 (an entire byte). That would give a result to either 3 or 243. Whence cometh -13?
Again, for good measure, another unexpected result of the same type and explanation:
php > $b = 6; // 0110
php > echo ~$b;
-7
Why -7?
Look at this code:
<?php
$val = 6;
print "$val = ".decbin($val);
print "\n";
$val = ~$val;
print "$val = ".decbin($val);
It prints
6 = 110
-7 = 11111111111111111111111111111001
At first you have 110. As my php uses 32 bits, after inverting all the bits, we get this huge number. As the 1-st bit is 1, php interprets it as a negative value, stored, using two's-complement representation. To find out, the modulus of the negative value, stored in this notation, we
invert the digits:
110
add one to the result:
111
which gives us 7
So, the value is -7
http://www.cs.cornell.edu/~tomf/notes/cps104/twoscomp.html
Why -7?
6 is 00000000000000000000000000000110, so ~6 is ~00000000000000000000000000000110, and that's equal to 11111111111111111111111111111001. Because a signed datatype is used, the first bit indicates whether the number is positive or negative (positive = 0 and negative = 1). Because it is Two's complement, you should convert the binary number to decimal using this way:
Invert the binary number. You get 00000000000000000000000000000110
Convert 00000000000000000000000000000110 (a positive binary number) to a decimal number. You get 6
Add 6 up with one: you get 7
Make it negative: you get -7

PHP - Length of a number containing 0's to the left

I'm trying to validate a number by it's length. This number has to have 4 digits so it passes the validation. The problem is when this number has 0's to it's left, like 0035.
Right now I'm at this:
echo (strlen ((string) 0025 ));
Which gives a total of 2, but I want this to count the 0's to it's left, so it gives me a total of 4.
Clearly the cast of the integer to string is not working, how can i do this?
You can't do that way, a left zero means the number is octal and not decimal, you can use sprintf() to do that.
Example:
echo strlen(sprintf("%04d", 25));
Live Test:
http://codepad.viper-7.com/VQr7Xz
Comment Answer:
I don't want to add the 0s to the number, i want to detect if the
number has 0s. If the number received is 25, it's not a valid number.
If it is 0025 it is valid. What i want is to validate only numbers
with 4 digits. – Cláudio Ribeiro
Cláudio, numbers have infinite left zeros, although a user has explicitly type 2 or 3 left zeros there are more hidden left zeros, it's a math basic, this is why it's impossible to know how many left zeros the user has typed if you receive an integer variable. If the variable has a constant size and you want to know how many left zeros it has you can do this:
<?php
$int = 25;
echo 4 - strlen($int);
Live test: http://codepad.viper-7.com/fT2jSn
But if you the variable has variable length it must be a string type instead of a numeric type.
An example where the variable received is a string:
<?php
$strs = array("0025","000035","01","2");
foreach($strs as $str)
{
preg_match("/^0+/", $str, $matches);
echo strlen(#$matches[0]);
echo "<br>";
}
Live Test: http://codepad.viper-7.com/BTRTgR
That should work:
$str = "0025";
if( is_numeric($str) && strlen($str) == 4)
{
echo "pass";
}
If it's a number, not a string, the number doesn't have digits. It has a value. You can format that value into a string with 4 digits which is left padded with 0s. But to validate whether a number has 4 digits is nonsense, since the number value has no formatting. The value only becomes "4 digits" when you format it as base 10 number. Until then the value is a value which can be expressed in a multitude of bases and has a different number of "digits" in all of them.
You either want to format the number to a 0-padded 4 digit string, or you want to check whether the value is between 0 and 9999 (or 1000 and 9999 if it has to be exactly "4 digits").
if (0 <= $num && $num <= 9999) {
$numStr = sprintf('%04d', $num);
} else {
trigger_error('Number out of range');
}

Categories