Чудеса какие то творятся
Прислано: seaji
чт, 22/07/2010 - 19:50
Внимание, вопрос к специалистам.
Кто нибудь может объяснить каким образом у меня из выражения:
<?php
$muid = 10863124257902193029;
print sprintf('SELECT uid FROM table WHERE muid = %d', $muid);
?>Вдруг превратилось в:
<?php
SELECT uid FROM table WHERE muid = 2147483647
?>Я из за этого целый час потерял. Сидел и думал, то ли лыжи не едут, то ли я е***нутый.
- seaji's blog
- Для комментирования войдите или зарегистрируйтесь
А число меняется в друпале или уже в БД?
- Для комментирования войдите или зарегистрируйтесь
А что с размером поля?
- Для комментирования войдите или зарегистрируйтесь
INT[(M)] [UNSIGNED] [ZEROFILL] (INTEGER[(M)] [UNSIGNED] [ZEROFILL])
Обычный целый тип. Значения - -2147483648..2147483647 и 0..4294967295 для беззнакового целого.
http://dev.mysql.com/doc/refman/5.0/en/numeric-types.html
- Для комментирования войдите или зарегистрируйтесь
А что с размером поля?
В базе данных это bigint(20) UNSIGNED
Но дело не в этом, до базы даже не доходит.
Замена происходит на момент подстановки числа в выражение.
См. выше, я же делаю проверку через спринтэф.
- Для комментирования войдите или зарегистрируйтесь
Но дело не в этом, до базы даже не доходит.
<?php echo PHP_INT_SIZE; ?>
http://ru2.php.net/manual/en/language.types.integer.php
- Для комментирования войдите или зарегистрируйтесь
PHP_INT_SIZE: 4
И что это значит?
Он мне сконвертил в 10 знаков
- Для комментирования войдите или зарегистрируйтесь
4 - это 4 байта, 32 разряда. Максимальное значение, соответственно, (2^31-1), минимальное - (-2^31). А 10 знаков - это в десятичной системе счисления. Тогда как компутер все считает в двоичной.
- Для комментирования войдите или зарегистрируйтесь
4 - это 4 байта
Почему байта, а не бита?
к тому же 2^32 = 4294967296
толучается что 4294967296 по Юниксу придет конец света?
Чем дальше тем страньше.
date('d-m-Y', 4294967296) показывает 31-12-1969
а сегодня 1279832203
- Для комментирования войдите или зарегистрируйтесь
Почему байта, а не бита?
Потому что байта. 4 байта, 32 бита. Столько занимает в памяти стандартный писишный int. Не обижайся, но вообще-то любой уважающий себя программист должен такие вещи знать.
к тому же 2^32 = 4294967296
Я написал (2^31-1), а не 2^32. Вторая половина (от 0xffffffff до 0x80000000) выделена под отрицательные числа, это же не unsigned int. Был бы беззнаковый - тогда да, максимум бы был (2^32-1).
- Для комментирования войдите или зарегистрируйтесь
Все дело в типах данных php.
<?php
echo PHP_INT_MAX, '<br>'; // 2147483647
$muid = 2147483647;
echo $muid, ' - ',gettype($muid), '<br>'; // целое
$muid = 2147483648;
echo $muid, ' - ',gettype($muid), '<br>'; // вещественное
$muid = 10863124257902193029;
echo $muid, ' - ',gettype($muid), '<br>';
echo sprintf('SELECT uid FROM table WHERE muid = %f', $muid) , '<br>'; // формат не пойдет
echo sprintf('SELECT uid FROM table WHERE muid = %s', number_format($muid, 0 , '', '')) , '<br>'; // из-за точности число не совпадает
?>Для точности при вычислениях с большими числами см. это:
http://php.su/functions/?cat=bc
Чем дальше тем страньше.
date('d-m-Y', 4294967296) показывает 31-12-1969
а сегодня 1279832203
функция date ожидает целое число, а иначе - преобразовывает. Преобразование идет по кругу:
<?php
echo (int)(2147483647 + 1),'<br>';
echo (int)(2147483647 + 2),'<br>';
?>Выведет:
-2147483648
-2147483647
- Для комментирования войдите или зарегистрируйтесь
Ну да, это все хорошо когда знаешь в чем дело.
А я вчера почувствовал себя как тот мужик, который хотел забор поставить.
Измерил длину рулеткой получилось 12 метров.
Заказал 4 секции по 3 метра.
Поставил - не сходится, остается лишних пол метра забора.
Еще раз измерил - 12 метров.
Измерил каждую секцию - 3 метра.
Посчитал секции - 4 штуки.
Столбиком умножил 3 на 4, получилось 12
Ставит забор - не сходиться.
Позвал всех соседей, все считали и умножали.
А в итоге все оказалось просто.
Жена красила потолок и испачкала рулетку и аккуратно вырезала из нее 50 см и склеила.
- Для комментирования войдите или зарегистрируйтесь






Комментарии