note 92885 added to language.types.float
| From: | francois dot barbier at gmail dot com | Date: | Thu, 13 Aug 2009 03:49:29 +0000 |
| Subject: | note 92885 added to language.types.float | ||
| Groups: | php.notes | ||
| Request: | Send a blank email to php-notes+get-159427@lists.php.net to get a copy of this message | ||
As "m dot lebkowski+php at gmail dot com" (http://www.php.net/language.types.float#81416)
noted 9 comments below :
When PHP converts a float to a string, the decimal separator used depends on the current locale
conventions.
However, to declare a floating point number, one must always use a full stop otherwhise the code
would be locale dependent (imagine the nightmare):
<?php
$float = 1.5; // float(1.5)
$float = 1,5; // Parse error: syntax error, unexpected ','
$float = (float) '1.5'; // float(1.5)
$float = (float) '1,5'; // float(1)
?>
Now, if you have a string containing a localized number, you can convert it back to a floating point
number using the following function:
<?php
/**
* Convert a localized number string into a floating point number
*
* @param string $sNumber The localized number string to convert.
* @return float The converted number.
*/
function str2num($sNumber)
{
$aConventions = localeConv();
$sNumber = trim((string) $sNumber);
$bIsNegative = (0 === $aConventions['n_sign_posn'] && '(' ===
$sNumber{0} && ')' === $sNumber{strlen($sNumber) - 1});
$sCharacters = $aConventions['decimal_point'].
$aConventions['mon_decimal_point'].
$aConventions['negative_sign'];
$sNumber = preg_replace('/[^'.preg_quote($sCharacters).'\d]+/', '',
trim((string) $sNumber));
$iLength = strlen($sNumber);
if (strlen($aConventions['decimal_point']))
{
$sNumber = str_replace($aConventions['decimal_point'], '.', $sNumber);
}
if (strlen($aConventions['mon_decimal_point']))
{
$sNumber = str_replace($aConventions['mon_decimal_point'], '.', $sNumber);
}
$sNegativeSign = $aConventions['negative_sign'];
if (strlen($sNegativeSign) && 0 !== $aConventions['n_sign_posn'])
{
$bIsNegative = ($sNegativeSign === $sNumber{0} || $sNegativeSign === $sNumber{$iLength - 1});
if ($bIsNegative)
{
$sNumber = str_replace($aConventions['negative_sign'], '', $sNumber);
}
}
$fNumber = (float) $sNumber;
if ($bIsNegative)
{
$fNumber = -$fNumber;
}
return $fNumber;
}
?>
Example:
<?php
setLocale(LC_ALL, 'fr_BE.UTF-8'); // decimal separator is now a comma
$float = -123456.789;
$string = (string) $float;
var_dump($float); // float(-123456,789)
var_dump($string); // string(11) "-123456,789"
var_dump((float) $string); // float(-123456)
var_dump(str2num($string)); // float(-123456,789)
?>
It also works with strings returned by the number_format() function:
<?php
setLocale(LC_ALL, 'fr_BE.UTF-8'); // decimal separator is now a comma
$conv = localeconv();
$float = -123456.789;
$string = $conv['int_curr_symbol'].number_format($float, $conv['frac_digits'],
$conv['decimal_point'], $conv['thousands_sep']);
var_dump($float); // float(-123456,789)
var_dump($string); // string(15) "EUR -123.456,79"
var_dump((float) $string); // float(0)
var_dump(str2num($string)); // float(-123456,79)
?>
----
Server IP: 64.71.164.2
Probable Submitter: 87.65.121.159
----
Manual Page -- http://www.php.net/manual/en/language.types.float.php
Edit -- https://master.php.net/note/edit/92885
Del: integrated -- https://master.php.net/note/delete/92885/integrated
Del: useless -- https://master.php.net/note/delete/92885/useless
Del: bad code -- https://master.php.net/note/delete/92885/bad+code
Del: spam -- https://master.php.net/note/delete/92885/spam
Del: non-english -- https://master.php.net/note/delete/92885/non-english
Del: in docs -- https://master.php.net/note/delete/92885/in+docs
Del: other reasons-- https://master.php.net/note/delete/92885
Reject -- https://master.php.net/note/reject/92885
Search -- https://master.php.net/manage/user-notes.php