-992233736854775808은 PHPINT_아니 민.
11260 단어 PHPPHP_INT_MIN빈대
현상.
PHP_INT_MAX 및 PHPINT_MIN은 환경에 따라 달라진다. 예를 들어3v4l중PHP_INT_MAX
=9223372036854775807
,PHP_INT_MIN
=-9223372036854775808
이다. var_dump(PHP_INT_MAX);
var_dump(PHP_INT_MIN);
매뉴얼에 通常は PHP_INT_MIN === ~PHP_INT_MAX となる
라고 쓰여 있다.
해보자. . var_dump(PHP_INT_MIN === ~PHP_INT_MAX);
진짜?
대단히 기쁘다.
여기서숫자와 비교하다해보세요. var_dump(PHP_INT_MAX, PHP_INT_MAX === 9223372036854775807);
var_dump(PHP_INT_MIN, PHP_INT_MIN === -9223372036854775808);
어?PHP_INT_MIN === -9223372036854775808
는 가짜다.
사실 PHPINT_MIN뿐만 아니라 수치 간 비교도 잘 모르는 일이 생길 수 있다.-9223372036854775807-1
의 계산 결과가 정확하다-9223372036854775808, -9223372036854775808
와 비교하면 false.
그러나-9223372036854775808
피차간의 비교와PHP_INT_MIN
피차간의 비교는true
이었다.
무슨 일인지 모르겠다.
원인으로 말하자면 사실PHP_INT_MIN
이라기보다는-9223372036854775808
방면이다. var_dump(PHP_INT_MIN);
var_dump(-9223372036854775808);
var_다만 덤프-9223372036854775808
는 왠지float(-9.2233720368548E+18)
로 바뀌었다.
PHP 계산INT_민에게서 빼면 맞다-9223372036854775808
.그런데 그냥 빼면 플랫은 시원하다.
그나저나 이런 현상은 언제부터 일어났을까.
BUG표는 PHP4 시대부터 쭉표였지만 아무도 이 점을 눈치채지 못하고 놀랐다.
경계치의 테스트는2018/08/07에 제시일단인데 (int)
존재라고 쓰여 있기 때문이다.
그리고 bug표는 var입니다.export의 원인인 것 같지만 실제로는 print, echo,sprintef 등에서도 발생할 수 있으니 수치 처리 문제를 고려해 보는 것이 좋다.
원인을 조사하다
여기서부터 아래쪽은 원본 파일을 비스듬히 읽었을 뿐 실제 디버깅한 것이 아니기 때문에 진짜인지 아닌지 장담할 수 없다.
조사에 사용된 버전은 PHP7입니다.2.8.===
의 비교는 zend_operators.h
내감지되지 않음에서 진행되었다.static zend_always_inline int fast_is_identical_function(zval *op1, zval *op2)
{
if (Z_TYPE_P(op1) != Z_TYPE_P(op2)) {
return 0;
} else if (Z_TYPE_P(op1) <= IS_TRUE) {
return 1;
}
return zend_is_identical(op1, op2);
}
・유형에 따라 가짜를 회복합니다.
・ 만약 한 종류가 undefined/null/가짜/진짜라면 진짜로 돌아간다.
• 이외에도 젠드가 있습니다is_identical 결과를 되돌려줍니다.
zend_is_identical fast_is_identical_function 에서 정의합니다.switch (Z_TYPE_P(op1)) {
case IS_LONG:
return (Z_LVAL_P(op1) == Z_LVAL_P(op2));
Z_LVAL_P
는 long 값이 있는 매크로입니다.
비교 부분은 별다른 관계가 없는 것 같다.
그렇다면 도대체 어디가 문제일까? 사실 그 전에 나는 zend_operators.c 대본을 깨끗이 정리할 것이다.
다음은 수치 부분을 제거하는 발췌문입니다.<ST_IN_SCRIPTING>{LNUM} {
// 19桁未満なら
if (yyleng < MAX_LENGTH_OF_LONG - 1) {
// longにする
ZVAL_LONG(zendlval, ZEND_STRTOL(yytext, &end, 0));
// 19桁以上なら
} else {
// longにする
ZVAL_LONG(zendlval, ZEND_STRTOL(yytext, &end, 0));
// オーバーフローしていた
if (errno == ERANGE) {
// 1文字目が0だった
if (yytext[0] == '0') {
// 8進数からdoubleにする
ZVAL_DOUBLE(zendlval, zend_oct_strtod(yytext, (const char **)&end));
} else {
// 10進数からdoubleにする
ZVAL_DOUBLE(zendlval, zend_strtod(yytext, (const char **)&end));
}
}
}
}
LNUM
의 정의는 [0-9]+
로 수치가 여기에 들어간다.-
입장하지 않습니다.
이 함수는 입력한 값ZVAL_LONG
을 매크로로 롱형으로 만들지만 넘치면 더블 형으로 바꿉니다.
여기서부터 자구 해석 부근에 쓰고 싶지만, 최선을 다했으니 계속 써 주십시오.
한 마디로 하면 여기서 자구를 해석할 때-
는 입력하지 않기 때문에 양과 음9223372036854775807
을 막론하고 범위 내에서9223372036854775808
는 넘침으로 판정된 것 같다.
따라서 -9223372036854775808
단어 해석이 끝날 때flat형으로 바뀌었다.-9223372036854775807-1
어휘 해석 시점9223372036854775807
과 1
이 모두 범위 내에 있기 때문에 정상적으로 제거할 수 있다.
실제 응용에서는 (int)
만 입력하면 되기 때문에 처리하는 것도 그리 대단한 일은 아니지만 근치를 위해 자구 해석은 반드시 손에 넣어야 하는 것이 비교적 심각하지 않습니까?
Reference
이 문제에 관하여(-992233736854775808은 PHPINT_아니 민.), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/rana_kualu/items/c0414981ae848852bf48
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
var_dump(PHP_INT_MAX);
var_dump(PHP_INT_MIN);
var_dump(PHP_INT_MIN === ~PHP_INT_MAX);
var_dump(PHP_INT_MAX, PHP_INT_MAX === 9223372036854775807);
var_dump(PHP_INT_MIN, PHP_INT_MIN === -9223372036854775808);
var_dump(PHP_INT_MIN);
var_dump(-9223372036854775808);
여기서부터 아래쪽은 원본 파일을 비스듬히 읽었을 뿐 실제 디버깅한 것이 아니기 때문에 진짜인지 아닌지 장담할 수 없다.
조사에 사용된 버전은 PHP7입니다.2.8.
===
의 비교는 zend_operators.h
내감지되지 않음에서 진행되었다.static zend_always_inline int fast_is_identical_function(zval *op1, zval *op2)
{
if (Z_TYPE_P(op1) != Z_TYPE_P(op2)) {
return 0;
} else if (Z_TYPE_P(op1) <= IS_TRUE) {
return 1;
}
return zend_is_identical(op1, op2);
}
・유형에 따라 가짜를 회복합니다.・ 만약 한 종류가 undefined/null/가짜/진짜라면 진짜로 돌아간다.
• 이외에도 젠드가 있습니다is_identical 결과를 되돌려줍니다.
zend_is_identical fast_is_identical_function 에서 정의합니다.
switch (Z_TYPE_P(op1)) {
case IS_LONG:
return (Z_LVAL_P(op1) == Z_LVAL_P(op2));
Z_LVAL_P
는 long 값이 있는 매크로입니다.비교 부분은 별다른 관계가 없는 것 같다.
그렇다면 도대체 어디가 문제일까? 사실 그 전에 나는 zend_operators.c 대본을 깨끗이 정리할 것이다.
다음은 수치 부분을 제거하는 발췌문입니다.
<ST_IN_SCRIPTING>{LNUM} {
// 19桁未満なら
if (yyleng < MAX_LENGTH_OF_LONG - 1) {
// longにする
ZVAL_LONG(zendlval, ZEND_STRTOL(yytext, &end, 0));
// 19桁以上なら
} else {
// longにする
ZVAL_LONG(zendlval, ZEND_STRTOL(yytext, &end, 0));
// オーバーフローしていた
if (errno == ERANGE) {
// 1文字目が0だった
if (yytext[0] == '0') {
// 8進数からdoubleにする
ZVAL_DOUBLE(zendlval, zend_oct_strtod(yytext, (const char **)&end));
} else {
// 10進数からdoubleにする
ZVAL_DOUBLE(zendlval, zend_strtod(yytext, (const char **)&end));
}
}
}
}
LNUM
의 정의는 [0-9]+
로 수치가 여기에 들어간다.-
입장하지 않습니다.이 함수는 입력한 값
ZVAL_LONG
을 매크로로 롱형으로 만들지만 넘치면 더블 형으로 바꿉니다.여기서부터 자구 해석 부근에 쓰고 싶지만, 최선을 다했으니 계속 써 주십시오.
한 마디로 하면 여기서 자구를 해석할 때
-
는 입력하지 않기 때문에 양과 음9223372036854775807
을 막론하고 범위 내에서9223372036854775808
는 넘침으로 판정된 것 같다.따라서
-9223372036854775808
단어 해석이 끝날 때flat형으로 바뀌었다.-9223372036854775807-1
어휘 해석 시점9223372036854775807
과 1
이 모두 범위 내에 있기 때문에 정상적으로 제거할 수 있다.실제 응용에서는
(int)
만 입력하면 되기 때문에 처리하는 것도 그리 대단한 일은 아니지만 근치를 위해 자구 해석은 반드시 손에 넣어야 하는 것이 비교적 심각하지 않습니까?
Reference
이 문제에 관하여(-992233736854775808은 PHPINT_아니 민.), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/rana_kualu/items/c0414981ae848852bf48텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)