note 90754 added to language.types.float
| From: | Bob at osu1 dot php dot net | Date: | Fri, 08 May 2009 05:04:18 +0000 |
| Subject: | note 90754 added to language.types.float | ||
| Groups: | php.notes | ||
| Request: | Send a blank email to php-notes+get-154344@lists.php.net to get a copy of this message | ||
Here is a function to convert an exponential-format float to a decimal-format float; e.g. 1.6e+12 to
1600000000000.
It will help addressing the problem specified by kjohnson above.
I have tested it, but not in any real world situation so any feedback/improvements/bug-reports would
be appreciated.
<?php
function exp_to_dec($float_str)
// formats a floating point number string in decimal notation, supports signed floats, also supports
non-standard formatting e.g. 0.2e+2 for 20
// e.g. '1.6E+6' to '1600000', '-4.566e-12' to
'-0.000000000004566', '+34e+10' to '340000000000'
// Author: Bob
{
// make sure its a standard php float string (i.e. change 0.2e+2 to 20)
// php will automatically format floats decimally if they are within a certain range
$float_str = (string)((float)($float_str));
// if there is an E in the float string
if(($pos = strpos(strtolower($float_str), 'e')) !== false)
{
// get either side of the E, e.g. 1.6E+6 => exp E+6, num 1.6
$exp = substr($float_str, $pos+1);
$num = substr($float_str, 0, $pos);
// strip off num sign, if there is one, and leave it off if its + (not required)
if((($num_sign = $num[0]) === '+') || ($num_sign === '-')) $num = substr($num,
1);
else $num_sign = '';
if($num_sign === '+') $num_sign = '';
// strip off exponential sign ('+' or '-' as in 'E+6') if there is
one, otherwise throw error, e.g. E+6 => '+'
if((($exp_sign = $exp[0]) === '+') || ($exp_sign === '-')) $exp = substr($exp,
1);
else trigger_error("Could not convert exponential notation to decimal notation: invalid float
string '$float_str'", E_USER_ERROR);
// get the number of decimal places to the right of the decimal point (or 0 if there is no dec
point), e.g., 1.6 => 1
$right_dec_places = (($dec_pos = strpos($num, '.')) === false) ? 0 : strlen(substr($num,
$dec_pos+1));
// get the number of decimal places to the left of the decimal point (or the length of the entire
num if there is no dec point), e.g. 1.6 => 1
$left_dec_places = ($dec_pos === false) ? strlen($num) : strlen(substr($num, 0, $dec_pos));
// work out number of zeros from exp, exp sign and dec places, e.g. exp 6, exp sign +, dec places
1 => num zeros 5
if($exp_sign === '+') $num_zeros = $exp - $right_dec_places;
else $num_zeros = $exp - $left_dec_places;
// build a string with $num_zeros zeros, e.g. '0' 5 times => '00000'
$zeros = str_pad('', $num_zeros, '0');
// strip decimal from num, e.g. 1.6 => 16
if($dec_pos !== false) $num = str_replace('.', '', $num);
// if positive exponent, return like 1600000
if($exp_sign === '+') return $num_sign.$num.$zeros;
// if negative exponent, return like 0.0000016
else return $num_sign.'0.'.$zeros.$num;
}
// otherwise, assume already in decimal notation and return
else return $float_str;
}
?>
----
Server IP: 117.104.162.229
Probable Submitter: 58.96.44.86 (proxied: 58.96.44.86)
----
Manual Page -- http://www.php.net/manual/en/language.types.float.php
Edit -- https://master.php.net/note/edit/90754
Del: integrated -- https://master.php.net/note/delete/90754/integrated
Del: useless -- https://master.php.net/note/delete/90754/useless
Del: bad code -- https://master.php.net/note/delete/90754/bad+code
Del: spam -- https://master.php.net/note/delete/90754/spam
Del: non-english -- https://master.php.net/note/delete/90754/non-english
Del: in docs -- https://master.php.net/note/delete/90754/in+docs
Del: other reasons-- https://master.php.net/note/delete/90754
Reject -- https://master.php.net/note/reject/90754
Search -- https://master.php.net/manage/user-notes.php