преобразование числа из строки в отрицательный int

grigori

( ͡° ͜ʖ ͡°)
Команда форума
привет, не придумаю как сделать, подскажите, пожалуйста

PHP:
$ php -r 'echo ip2long("213.87.240.200");'
-715657016
$ php -r 'echo sprintf("%u", -715657016);'
3579310280
очевидно. получил, записал в базу.

Но
PHP:
$ php -r 'sscanf("3579310280","%u",$x); var_dump($x);'
string(10) "3579310280"
$ php -r 'echo (int)"3579310280";'
2147483647
Как получить (int) -715657016 ?

цель: парсинг логов, построение массива с IP в ключе для поиска запросов с одного ip в интервале времени
 
Последнее редактирование:

Активист

Активист
Команда форума
Код:
var_dump(3579310280 - 0x100000000);
int(-715657016)
Вообще разница тут в платформах, на x64 будет 3579310280 на x86 -715657016, на 64 битной ос приводить к 32 битной можно так
Код:
 if(PHP_INT_SIZE == 8 && $ip >0x7FFFFFFF) {$ip -= 0x100000000 }
На 64 битной ОС можно приводить числа 32 битные к 64 битному размеру var_dump( -715657016 & 0xFFFFFFFF);

вспомнил, у мну маршрутизатор 32 битная ОС
Код:
root@linux-debian-1:~# php -r 'var_dump(PHP_INT_SIZE);';
int(4)
root@linux-debian-1:~# php -r 'var_dump(3579310280 & 0xffffffff);';
int(-715657016)
root@linux-debian-1:~#
[/code[
Тот же код на 64 битной ОС, очивидное повидение - знаковый бит у 64 битного числа другой
Код:
root@keeper:/home/keeper# php -r 'var_dump(PHP_INT_SIZE);';
int(8)
php -r 'var_dump(3579310280 & 0xffffffff);';
int(3579310280)
root@keeper:/home/keeper#
 
Последнее редактирование:

Активист

Активист
Команда форума
в общем прогоняй все числа через битовый и " & 0xffffffff " на той ОС на которой запускаешь, функции long2ip будут работать корректно:

64 битная ОС
Код:
root@keeper:/home/keeper# php -r 'var_dump(long2ip(3579310280 & 0xffffffff));';
string(14) "213.87.240.200"
root@keeper:/home/keeper# php -r 'var_dump(long2ip(-715657016 & 0xffffffff));';
string(14) "213.87.240.200"
root@keeper:/home/keeper#
32 битная ОС
Код:
root@linux-debian-1:~# php -r 'var_dump(long2ip(3579310280 & 0xffffffff));';
string(14) "213.87.240.200"
root@linux-debian-1:~# php -r 'var_dump(long2ip(-715657016 & 0xffffffff));';
string(14) "213.87.240.200"
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
ты предлагаешь в базе сделать int signed вместо unsigned и писать сразу со знаком. вариант, да

прогоняй все числа через битовый и " & 0xffffffff " на той ОС на которой запускаешь
PHP:
$ php -r 'var_dump("3579310280" & 0xffffffff);';
int(2147483647)
на 32х битах нельзя, обрезает,
было бы 64 - вообще бы не задумывался
 
Последнее редактирование:

флоппик

promotor fidei
Команда форума
Партнер клуба
PHP:
C:\www\>php -r "var_dump(unpack('l', pack('L',3579310280)))";
array(1) {
  [1]=>
  int(-715657016)
}
Тоже 32хбитный не нашел, пришлось на винде тестить.
 

Вурдалак

Продвинутый новичок
По идее, как хак, можно intval(doubleval("3579310280")). Только возможности проверить тоже нет :)
 

Вурдалак

Продвинутый новичок
PHP:
C:\www\>php -v
PHP 5.6.3 (cli) (built: Nov 12 2014 17:18:08)
Copyright (c) 1997-2014 The PHP Group
Zend Engine v2.6.0, Copyright (c) 1998-2014 Zend Technologies
    with the ionCube PHP Loader v4.7.2, Copyright (c) 2002-2014, by ionCube Ltd.

C:\www\>php -r "echo PHP_INT_SIZE;"
4
Ааа, у тебя просто числовой литерал «3579310280» как double получается, поэтому никакой разницы с intval(doubleval("3579310280")).

У Гриши строка, если он сделает intval("3579310280"), то получит int 2147483647.
 

Вурдалак

Продвинутый новичок
@Вурдалак я еще короче придумал: =D
PHP:
C:\www\>php -r "echo ("3579310280" | 0b1000);"
-715657016
Эм, а почему оно так работает? Строка должна преобразоваться в int, т.е. в 2147483647.

У меня подозрение, что у тебя из-за отсутствия экранирования кавычек просто получается литерал 3579310280, который double, а «|» форсит int.
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
ну да
$ php -r 'var_dump ("3579310280" | 0b1000);'
int(2147483647)

а так работает
$ php -r 'var_dump ( intval(doubleval("3579310280")));'
int(-715657016)

спасибо
 
Последнее редактирование:

Активист

Активист
Команда форума
Эм...

ну да
$ php -r 'var_dump ("3579310280" | 0b1000);'
int(2147483647)

а так работает
$ php -r 'var_dump ( intval(doubleval("3579310280")));'
int(-715657016)

спасибо
Код:
root@linux-debian-1:~# php -r 'var_dump( ((double)"3579310280") &0xffffffff );';
int(-715657016)
root@linux-debian-1:~# php -v
PHP 5.4.39-0+deb7u2 (cli) (built: Mar 25 2015 09:10:46) 
Copyright (c) 1997-2014 The PHP Group
Zend Engine v2.4.0, Copyright (c) 1998-2014 Zend Technologies
    with XCache v2.0.0, Copyright (c) 2005-2012, by mOo
root@linux-debian-1:~# uname -a
Linux linux-debian-1.local 3.2.0-4-686-pae #1 SMP Debian 3.2.68-1+deb7u1 i686 GNU/Linux
root@linux-debian-1:~#
 

Активист

Активист
Команда форума
Можно вопрос, а зачем вообще приводить их к одному 4-х байтному типу x86? На индекс на конкретной машине как повлияет?
 
Сверху