1

I'm reading data from spreadsheets that contain long numeric ID strings. I'm trying to make my system foolproof by making sure that the data reads correctly even if the column format is incorrectly set as a number.

So the spreadsheet contains the number 32486509223273700000 in scientific notation as 3.2486509223274E+19. Before i store it as a string i need to convert it to the original value. This is where the problems come in.

I can't make PHP convert the scientific notation back to the original number. Using various methods for converting the number back to original, it always seems to have different digits instead of trailing zeros.

$i = 3.2486509223274E+19;
echo $i; //32486509223274000384
echo number_format($i,0,'',''); //32486509223274000384
echo sprintf('%0.0f', $i); //32486509223274000384

Please note that I intend to store the end result as a string.

lucov
  • 21
  • 4
  • http://stackoverflow.com/questions/670662/whats-the-maximum-size-for-an-int-in-php – RST Feb 09 '16 at 10:16
  • The scientific notation is already rounded up. It's impossible to get the original `32486509223273700000` back from that without clairvoyance (which PHP hasn't implemented yet). Even Javascript gives you a *different* number. – deceze Feb 09 '16 at 10:37
  • @deceze Right, I just realized that it's different. – lucov Feb 09 '16 at 10:39

3 Answers3

2

Note that the double floating point format has a precision of about 15.5 decimals. All other displayed decimals are extrapolated. And as always, extrapolation is a dangerous game.

Or in other words, 3.2486509223274E+19 represents an interval, roughly from 3.24865092232739984E+19 to 3.24865092232740024E+19. Any integer in that interval has to count as "correct" extrapolation.

Lutz Lehmann
  • 25,219
  • 2
  • 22
  • 51
  • There is no "extrapolation" -- just conversion. 32486509223274000384 is the exact decimal value of the closest 53 significant bit binary floating-point number to 3.2486509223274e19. Also, be careful using the word "interval", since this is not interval arithmetic. – Rick Regan Feb 13 '16 at 15:33
  • Of course you could also call it a SWAG. However, since it is continuation with null information, it is also extrapolation, in the extended sense. -- I use "interval" in the common mathematical sense. And in a certain sense, floating point arithmetic is -- even if imperfect -- interval arithmetic. – Lutz Lehmann Feb 13 '16 at 16:00
  • Conversion is well-defined. 3.2486509223274E+19 converts to 1.1100001011010111010001000000010010000101101100101011 * 2^64, which is exactly 32486509223274000384. Every digit you get is really there, even if from the point of view of your decimal input some are insignificant. – Rick Regan Feb 13 '16 at 16:50
2

Simplest solution is to convert the big number to a float value:

$i = 3.2486509223274E+19;
echo printf ("%.0f", $i);
// output 3248650922327400038420

This might seem to be a slightly incorrect value but it can't be avoided as @LutzL already pointed out.

maxhb
  • 8,554
  • 9
  • 29
  • 53
0

there is a value in php.ini called precision, its how many digits it will display for a floating point number. In your case set it to at least 21. Better set it to 30

precision=30

Tarik
  • 4,270
  • 38
  • 35