Share PHP Gotcha: Bigint with sprintf()

December 3rd, 2008 by Erik

PHP LogoToday I am working on modification of an FB application to permit installation on “pages” in addition to profiles. Facebook has switched (several months ago) to using 64bit integer values for id’s site wide. In the code I use sprintf to create stored procedure calls and couldn’t figure out why the values the the database weren’t matching up with my expectations… the following code would output 536035818 instead of the much larger 30600806890 value I expected. Clearly this is a 32bit vs 64bit.

$big_int = 30600806890;
$format = "%d";
$new_string = sprintf($format, $big_int);
print $new_string;

Since updating to a fully 64 bit platform and so on really isn’t an option, I needed a work around. I composed a quick test for my value and ran it. The test as you can see, it provides output for each of the valid substitution types in sprintf.

$big_int = 30600806890;
$type = array("%b","%c","%d","%e","%u","%f","%F","%o","%s","%x","%X");
for($i=0;$i<count($type);$i++){
        print $type[$i] . ": " . sprintf($type[$i], $big_int) . "\n";
}

This results with the list below. Obviously floating point numbers and strings are the only way to handle these bigint values. A simple drop in value is of course to swap %s for %d as needed, but you lose some type catching which may cause security issues. Instead, I recommend using %0.0f which will suppress the decimal portion – keeping the int an int – while keeping the numeric type checking intact.

%b: 11111111100110100000111101010
%c: ?
%d: 536035818
%e: 3.06008e+10
%u: 536035818
%f: 30600806890.000000
%F: 30600806890.000000
%o: 3774640752
%s: 30600806890
%x: 1ff341ea
%X: 1FF341EA

You should follow me on Twitter.

Tags: , , , , ,

Not ready to comment, but still found it valuable?

2 Responses to “PHP Gotcha: Bigint with sprintf()”

  1. Erik Erik Says:

    I’ve since learned that this is actually because PHP silently converts integer values to floats behind the scenes for you. See my latest troubles and work around here:

    http://af-design.com/blog/2009/10/28/php-64-bit-integer-modulus-almost/

  2. Long Facebook User IDs | Ryan Rampersad Long Facebook User IDs | Ryan Rampersad Says:

    [...] had to update my ID columns in my database to use BIGINT so that they could store 20 digits. Other people have been impacted by this because they actually coded Facebook applications. Share and [...]

Leave a Reply

© 1998-2008 AF-Design, All rights reserved.