I have a database storing VIN numbers (stored as VID) for vehicles which are 17 characters in length. I am trying to increment to the next VID to display it on the page where a new vehicle can be added in the database. The VID field in the database is type bigint(17) and has auto_increment set.
$incr_query = "SELECT MAX(VID) FROM Vehicle";
$incr_result = mysql_query($incr_query);
$row = mysql_fetch_assoc($incr_result);
$vid = $row["MAX(VID)"] + 1;
Output:
print var_dump{$row);//array(1) { ["MAX(VID)"]=> string(17) "12345678123456788" }
print gettype($vid); //double
print $vid; //1.2345678123457E+16
print number_format(++$vid, 0, '.', ''); //12345678123456788
print number_format(--$vid, 0, '.', ''); //12345678123456788
print number_format($vid - 5, 0, '.', ''); //12345678123456784
I'm not sure what's going on here. According to the PHP float manual:
"The size of a float is platform-dependent, although a maximum of ~1.8e308 with
a precision of roughly 14 decimal digits is a common value"
EDIT:
So using bcadd, these are the outputs:
$vid = bcadd($vid, '1', 0);
print "\n".$vid; //12345678123456789
print "\n".number_format($vid, 0, '.', ''); //12345678123456788
The VID number might look like a "double" or "integer" or whatever but it isn't. Store it as string. Check out Skeet on Vimeo for an explanation. It starts around 6:10 and ends at, around, 10:00.
A bigint in the DB might do, but a double is a floating point and floating points are not intended to be used as discrete numbers; that's why they're floating points. I would go with string (varchar) all the way, up to the database. Using a bigint would encourage you/other developers to keep treating it as a "number" wich, in fact, it isn't (exactly).
string in your application. If you're going for string/varchar all-the-way as per my earlier suggestion you'll need a bit more (application)logic to increment the number with help from, for example, bcadd from BC Math or gmp_add from GMP - RobIII 2012-04-05 01:46