Chr() value outside the range (0.255)

Asked

Viewed 103 times

1

I’m studying this function, but I’m having trouble understanding when we pass a value out of range (0.255) to this function.

In the official documentation it presents an algorithm to find the correct value, but I could not get the idea and be able to reproduce.

I have the following example:

echo chr(300);

Which results in: , of heading 44.

But how is it calculated that by passing the value 300 it returns me the corresponding position 44?

Thank you!

1 answer

4


Explain how it happens exactly internally in the PHP script interpreter (in windows or php.exe), PHP is written in , the code is this:

Code:

PHP_FUNCTION(chr)
{
    zend_long c;

    if (ZEND_NUM_ARGS() != 1) {
        WRONG_PARAM_COUNT;
    }

    ZEND_PARSE_PARAMETERS_START_EX(ZEND_PARSE_PARAMS_QUIET, 1, 1)
        Z_PARAM_LONG(c)
    ZEND_PARSE_PARAMETERS_END_EX(c = 0);

    c &= 0xff;
    ZVAL_INTERNED_STR(return_value, ZSTR_CHAR(c));
}

The responsible line is this:

c &= 0xff;

This notation 0x that is in front of the ff means hexadecimal (base 16), its calculation is made so:

  • each f worth 15, then 16 to 1 is 16 even
  • getting 15 * 16
  • 16 to 0 is 1
  • getting 15 * 1
  • sum both

The calculation:

15 * 16^1 + 15 * 16^0 = 255
(15 * 16) + (15 * 1)  = 255

The final value is 255

Important note: with the exception of zero itself, any zero value will result in 1, for example:

  • 30 = 1
  • 100 = 1
  • 220 = 1
  • 20180 = 1

Zero cannot be determined:

  • 00 = undetermined

So why convention programming is considered to be equal to 1 (00 = 1), an example in PHP can thus be tested with the function pow(base, expoente):

var_dump(pow(16, 0));
var_dump(pow(0, 0));

Or in PHP 5.6+:

var_dump(16 ** 0);
var_dump(0 ** 0);

Example https://ideone.com/QAx9Dh


Just to better explain the base 16 formula, if this were it 0xff00 would be so:

15 * 16^3 + 15 * 16^2 = 65280

Operation:

(15 * 256) + (15 * 4096) = 65280
3840       + 61440       = 65280

The value 65280

  • then the rightmost value is always raised to zero
  • the second most right raised to a
  • the third from right to left is raised to two

And so on, as in the second example we had two zeros after the ff (which results in zero in the calculation and therefore disregarded in the formula), then one of them was raised to 2 and the other to three.


Returning the formula, in the result of the execution of the programme (from the function PHP_FUNCTION(chr)) we’ll have this:

c &= 255;

The operator &= amounts to this c = c & 255;, this operator & (or &=) is an operator bitwise called AND (not to confuse with &&, although similar) for binary logic, so in an operation it will compare bit by bit and will return a 1 whenever both when compared are 1, has a response on the website about this:

So 255 equals 011111111 and the amount you put 300 would equal 0100101100, as 255 bits is smaller then a zero is added to your left (even if it was the other way around 255 & 300):

255:       0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1
300:       0 | 1 | 0 | 0 | 1 | 0 | 1 | 1 | 0 | 0
------------------------------------------------
Resultado: 0 | 0 | 0 | 0 | 1 | 0 | 1 | 1 | 0 | 0

Then we’ll have 0000101100 that converted results in 44

Note: to facilitate understanding the operations one can remove the zeros to the left, thus:

255:       0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1
300:       1 | 0 | 0 | 1 | 0 | 1 | 1 | 0 | 0
---------------------------------------------
Resultado: 0 | 0 | 0 | 1 | 0 | 1 | 1 | 0 | 0

The converted value will be the same at the end.


These operations can be done in several programming languages (I don’t know if you have one that doesn’t support), so you can test in Javascript:

var valor = prompt('Insira o numero');
var range = 255;

valor = parseInt(valor);

if (valor) {
    var x = valor & range;
    alert(x);
} else {
    alert('Numero inválido');
}

An example in PHP would be:

<?php

$valor = 44;
$range = 255;

$x = $valor & $range;

var_dump($x);
  • 2

    Dude, I reviewed the PHP repository behind this excerpt... Very good!

  • 1

    Perfect! Thank you very much, now it’s super clear.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.