PHP
downloads | documentation | faq | getting help | mailing lists | reporting bugs | php.net sites | links | conferences | my php.net

search for in the

부동소수점> <논리값
Last updated: Sun, 25 Nov 2007

view this page in

정수

integer는 거대한 집합 Z = {..., -2, -1, 0, 1, 2, ...}이다.

Arbitrary length integer / GMP, 부동 소수점수, Arbitrary precision / BCMath를 참고

문법

정수는 10진수(10-based), 16진수(16-based), 8진수(8-based) 표기법으로 표현 될수 있다. 선택적으로 부호 (- 나 +)를 사용할수 있다.

8진수 표기법을 사용하면, 0 (zero)를 숫자의 앞에 붙여야 하며, 16진수 표기하려면 0x을 숫자 앞에 붙이도록 한다.

Example#1 정수 리터럴

<?php
$a 
1234# decimal number
$a = -123# a negative number
$a 0123# octal number (equivalent to 83 decimal)
$a 0x1A# hexadecimal number (equivalent to 26 decimal)
?>
공식적으로 가능한 정수 리터럴의 구조는 다음과 같다:
decimal     : [1-9][0-9]*
            | 0

hexadecimal : 0[xX][0-9a-fA-F]+

octal       : 0[0-7]+

integer     : [+-]?decimal
            | [+-]?hexadecimal
            | [+-]?octal
약 20억을 최대값(부호가 있는 32비트)으로 사용할수 있을지라도, 정수의 크기는 플랫폼에 따라 달라지게 된다. PHP는 부호없는(unsigned) 정수 를 지원하지 않는다.

정수 오버플로우

정수타입의 범위를 넘는 수를 사용하려면 그 값은 대신 float타입으로 해석될 것이다. 또한, 결과값이 integer타입의 범위를 초과하게 되는 작업을 수행되면, 그 값은 대신 float으로 돌려줄것이다.

<?php
$large_number 
=  2147483647;
var_dump($large_number);
// output: int(2147483647)

$large_number =  2147483648;
var_dump($large_number);
// output: float(2147483648)

// this goes also for hexadecimal specified integers:
var_dump0x80000000 );
// output: float(2147483648)

$million 1000000;
$large_number =  50000 $million;
var_dump($large_number);
// output: float(50000000000)
?>
Warning

불운하게도, PHP는 버그로 인해 음수와 연계될때 정확하게 동작하지 않을수 있다. 예를 들면 -50000 * $million를 수행하면, 결과는 -429496728이 될것이다. 두 피연산자가 모두 양수이면 아무 문제가 없다.

이 문제는 PHP 4.1.0에서 해결되었다.

PHP에는 정수 나누기 연산자가 없다. 1/2float 0.5가 된다. 반올림하기 위해 정수로 값을 캐스트하거나, round() 함수를 쓸수 있다.

<?php
var_dump
(25/7);         // float(3.5714285714286) 
var_dump((int) (25/7)); // int(3)
var_dump(round(25/7));  // float(4) 
?>

정수로 변환하기

명시적으로 integer로 변환하려면 (int)(integer) 캐스트를 사용한다. 하지만, 대부분의 경우 이런 캐스트를 사용할 필요가 없다. 왜냐하면 연산자 나 함수 또는 제어 구조가 integer 인수를 요구한다면 자동으로 변환되기 때문이다. 또한 intval()함수로 정수값으로 변환할수 있다.

See also type-juggling.

논리값에서

FALSE0 (zero), 그리고 TRUE1 (one).

부동소수점수에서

float에서 integer로 변환할때, 그 수는 0으로 깍일것이다.

float이 integer범위를 초과하면 (주로 +/- 2.15e+9 = 2^31), 결과는 정의되지않는다. 왜냐하면 float은 정확한 정수값을 돌려주기에 충분한 정밀도를 갖지 않기 때문이다. 이 경우에는 warning이나 notice조차도 나타나지 않는다!

Warning

알려지지 않은 소수를 integer로 캐스트하지 말것, 왜냐하면 이렇게 하는경우에 종종 기대하지 않는 결과를 유도할수 있기 때문이다.

<?php
echo (int) ( (0.1+0.7) * 10 ); // echoes 7!
?>
자세한 정보는 부동-정밀도에 관한 경고를 참고.

문자열로부터

문자열을 숫자로 변환하기를 참고

다른 타입으로부터

Caution

정수로의 변환은 다른 타입에 대해 정의되지 않는다. 현재까지는 값이 논리값으로 변환될때와 동일하게 동작한다. 하지만, 경고 없이 변할수 있기 때문에 이 동작에 연관짓지 말것



부동소수점> <논리값
Last updated: Sun, 25 Nov 2007
 
add a note add a note User Contributed Notes
정수
eric
11-Jun-2008 01:50
In response to the comment by me at troyswanson dot net:

-2147483648 falls into the range of 32 bit signed integers yet php treats it as a float.  However, -2147483647-1 is treated as an integer.

The following code demonstrates:
<?php
    var_dump
(-2147483648); //float(-2147483648)
   
var_dump(-2147483647 - 1); //int(-2147483648)
?>

This is probably very similar to the MS C bug which also treats -2147483648 as an UNSIGNED because it thinks it's out of the range of a signed int.

The problem is that the parser does not view "-x" as a single token, but rather as two, "-" and "x".  Since "x" is out of the range of an INT, it is promoted to float, even though in this unique case, "-x" is in the range of an int.

The best cure is probably to replace "-2147483648" with "0x80000000", as that is the hexadecimal equivalent of the same number.

Hope that helps explain what's going on

Peace

 - Eric / fez
winterheat
10-Jun-2008 03:25
PHP_INT_SIZE seems to be 8 when it is 64 bit integers... so 8 means the number of bytes, or number of 8-bits.
Elliott Brueggeman
06-Feb-2008 07:52
Don't forget about the integer minimum value. From my experimentation, the lowest valid integer is (PHP_INT_MAX * -1)-1. All values smaller than this fail the is_int() test, even though the may appear to act normally during mathematic operations. More info on this: http://www.ebrueggeman.com/blog/php/integers-and-floating-numbers/
bart at NOvankuikSPAM dot nl
09-Jan-2008 01:06
When handling very large numbers in PHP, you'll notice they get cut off at hexadecimal 7FFFF FFFF. Sometimes, you don't need to use these numbers in an actual calculation in PHP (i.e. just editing and displaying), and just need to save them in a database.

In that case, you can let MySQL handle the conversion from and to hexadecimal notation. In the example below, engineers need to save hexadecimal addresses up to FFFF FFFF. To update such a value in MySQL, use the following query, where 'addr' is a column with type unsigned integer(10).

<?php

        $query
= "
        UPDATE hardware_register
        SET    name = ?,
               type = ?,
               addr = conv(?, 16, 10)
        WHERE  id = ?
        "
;

?>

And selecting:
<?php
    $query
= "
    SELECT name, type, conv(addr, 10, 16)
    FROM   hardware_register
    WHERE  id = ?
    "
;

?>

Note that you'll have to treat the resulting addr column as a string everywhere in PHP. You can't do conversions like:

<?php
    $addr_decimal
= sprintf("%X", $addr_column);
?>

because that'll result in $addr_decimal having the cut-off, maximum int value.
autotelic at NOOOOSPAM dot hotmail dot com
29-Nov-2007 10:36
A note about converting IP addresses for storage in database.  For MySQL, this is unnecessary as it has built in support via the INET functions.  Also, there is no need to use BIGINT.  UNSIGNED INT is, at 4 bytes, the perfect size for holding an IP (column must be defined as UNSIGNED).  This can basically halve the storage size, as BIGINT is an 8 byte data type.

INET_ATON() converts a dotted IP string to INT:
INSERT table(ip) VALUES(INET_ATON('127.0.0.1'));

INET_NTOA() converts an INT to dotted IP string:
SELECT INET_NTOA(ip) FROM table
returns '127.0.0.1'

Details:
http://dev.mysql.com/doc/refman/5.1/en/miscellaneous-functions.html
darkshire
16-Nov-2007 04:56
d_n at NOSPAM dot Loryx dot com
13-Aug-2007 05:33
Here are some tricks to convert from a "dotted" IP address to a LONG int, and backwards. This is very useful because accessing an IP addy in a database table is very much faster if it's stored as a BIGINT rather than in characters.

IP to BIGINT:
<?php
  $ipArr   
= explode('.',$_SERVER['REMOTE_ADDR']);
 
$ip       = $ipArr[0] * 0x1000000
           
+ $ipArr[1] * 0x10000
           
+ $ipArr[2] * 0x100
           
+ $ipArr[3]
            ;
?>

This can be written in a bit more efficient way:
<?php
  $ipArr   
= explode('.',$_SERVER['REMOTE_ADDR']);
 
$ip       = $ipArr[0]<<24
           
+ $ipArr[1]<<16
           
+ $ipArr[2] <<8
           
+ $ipArr[3]
            ;
?>

shift is more cheaper.
Paul
04-Sep-2007 11:46
"always round it downwards"

It seems to truncate, or round toward zero, rather than downward. If the float is negative, it is rounded up.
d_n at NOSPAM dot Loryx dot com
13-Aug-2007 05:33
Here are some tricks to convert from a "dotted" IP address to a LONG int, and backwards. This is very useful because accessing an IP addy in a database table is very much faster if it's stored as a BIGINT rather than in characters.

IP to BIGINT:
<?php
  $ipArr   
= explode('.',$_SERVER['REMOTE_ADDR']);
 
$ip       = $ipArr[0] * 0x1000000
           
+ $ipArr[1] * 0x10000
           
+ $ipArr[2] * 0x100
           
+ $ipArr[3]
            ;
?>

IP as BIGINT read from db back to dotted form:

Keep in mind, PHP integer operators are INTEGER -- not long. Also, since there is no integer divide in PHP, we save a couple of S-L-O-W floor (<division>)'s by doing bitshifts. We must use floor(/) for $ipArr[0] because though $ipVal is stored as a long value, $ipVal >> 24 will operate on a truncated, integer value of $ipVal! $ipVint is, however, a nice integer, so
we can enjoy the bitshifts.

<?php
        $ipVal
= $row['client_IP'];
       
$ipArr = array(0 =>
                   
floor$ipVal               / 0x1000000) );
       
$ipVint   = $ipVal-($ipArr[0]*0x1000000); // for clarity
       
$ipArr[1] = ($ipVint & 0xFF0000)  >> 16;
       
$ipArr[2] = ($ipVint & 0xFF00  )  >> 8;
       
$ipArr[3] =  $ipVint & 0xFF;
       
$ipDotted = implode('.', $ipArr);
?>
me at troyswanson dot net
12-Jun-2007 03:11
This note applies to machines that are using a 32 bit integer size.  I imagine the same results occur in 64 bit machines as well (with the number 2^63-1).

-2147483648 falls into the range of 32 bit signed integers (0b10000000000000000000000000000000), yet php treats it as a float.  However, -2147483647-1 is treated as an integer.

The following code demonstrates:
<?php
    var_dump
(-2147483648); //float(-2147483648)
   
var_dump(-2147483647 - 1); //int(-2147483648)
?>

Regards
Jacek
10-Mar-2007 04:51
On 64 bits machines max integer value is 0x7fffffffffffffff (9 223 372 036 854 775 807).
09-Mar-2007 07:26
To force the correct usage of 32-bit unsigned integer in some functions, just add '+0'  just before processing them.

for example
echo(dechex("2724838310"));
will print '7FFFFFFF'
but it should print 'A269BBA6'

When adding '+0' php will handle the 32bit unsigned integer
correctly
echo(dechex("2724838310"+0));
will print 'A269BBA6'
popefelix at gmail dot com
21-Dec-2006 06:50
Be careful when using integer conversion to test something to see if it evaluates to a positive integer or not.  You might get unexpected behaviour.

To wit:
<?php
error_reporting
(E_ALL);
require_once
'Date.php';

$date = new Date();
print
"\$date is an instance of " . get_class($date) . "\n";
$date += 0;
print
"\$date is now $date\n";
var_dump($date);

$foo = new foo();
print
"\$foo is an instance of " . get_class($foo) . "\n";
$foo += 0;
print
"\$foo is now $foo\n";
var_dump($foo);

class
foo {
    var
$bar = 0;
    var
$baz = "la lal la";
    var
$bak;

    function
foo() {
       
$bak = 3.14159;
    }
}
?>

After the integer conversion, you might expect both $foo and $date to evaluate to 0.  However, this is not the case:

$date is an instance of Date

Notice: Object of class Date could not be converted to int in /home/kpeters/work/sketches/ObjectSketch.php on line 7
$date is now 1
int(1)
$foo is an instance of foo

Notice: Object of class foo could not be converted to int in /home/kpeters/work/sketches/ObjectSketch.php on line 13
$foo is now 1
int(1)

This is because the objects are first converted to boolean before being converted to int.
rustamabd@gmail-you-know-what
12-Dec-2006 01:42
Be careful with using the modulo operation on big numbers, it will cast a float argument to an int and may return wrong results. For example:
<?php
    $i
= 6887129852;
    echo
"i=$i\n";
    echo
"i%36=".($i%36)."\n";
    echo
"alternative i%36=".($i-floor($i/36)*36)."\n";
?>
Will output:
i=6.88713E+009
i%36=-24
alternative i%36=20
jmw254 at cornell dot edu
25-Aug-2006 10:14
Try this one instead:

function iplongtostring($ip)
{
    $ip=floatval($ip); // otherwise it is capped at 127.255.255.255

    $a=($ip>>24)&255;
    $b=($ip>>16)&255;
    $c=($ip>>8)&255;
    $d=$ip&255;

    return "$a.$b.$c.$d";
}
rickard_cedergren at yahoo dot com
27-Jan-2005 01:15
When doing large subtractions on 32 bit unsigned integers the result sometimes end up negative. My example script converts a IPv4 address represented as a 32 bit unsigned integer to a dotted quad (similar to ip2long()), and adds a "fix" to the operation.

   /**************************
    * int_oct($ip)
    * Convert INTeger rep of IP to octal (dotted quad)
    */
   function int_oct($ip) {

      /* Set variable to float */
      settype($ip, float);

      /* FIX for silly PHP integer syndrome */
      $fix = 0;
      if($ip > 2147483647) $fix = 16777216;

      if(is_numeric($ip)) {
         return(sprintf("%u.%u.%u.%u",
                $ip / 16777216,
                (($ip % 16777216) + $fix) / 65536,
                (($ip % 65536) + $fix / 256) / 256,
                ($ip % 256) + $fix / 256 / 256
                )
     );
      }
      else {
         return('');
      }
   }
23-Dec-2003 10:18
Sometimes you need to parse an unsigned
32 bit integer. Here's a function I 've used:
                                                                               
    function parse_unsigned_int($string) {
        $x = (float)$string;
        if ($x > (float)2147483647)
            $x -= (float)"4294967296";
        return (int)$x;
    }

부동소수점> <논리값
Last updated: Sun, 25 Nov 2007
 
 
show source | credits | stats | sitemap | contact | advertising | mirror sites