The variable $value contains a floating point number. Floating point numbers are not exact, they are approximations.1
The value of $value is not 1640 but 1639.99999999999977262632. When you use %f to print it, printf() rounds it to 6 decimal places and the rounded value is 1640.000000.
When it is printed with %d, printf() uses only the integer part of $value and it is 1639.
Use round() to get the correct integer value:
printf('%d', round($value, 0));
Or, even better, use number_format() to get the value as string:
echo(number_format($value, 0, '', ''));
Both print 1640.
1 Think of 1/3. It is approximatively 0.3333333333 but one cannot represent it exactly because it has an infinite number of 3 after the decimal dot. In mathematics, 3 * 1/3 = 1 but in real life (and in computers), 3 * 0.333333333 is never 1, no matter how many 3 we put after the decimal dot. The computer programs usually round the value to some number of decimal places and it ends up being displayed as 1 but this doesn't happen always.
When it doesn't happen, another question similar to this one pops up on StackOverflow.