I know the question is very basic but it seems nothing working for me.
I have a number (either or float or integer) which I want to be formatted upto two decimal point. For this purpose I'm using PHP function number_format but it converts my number to string.
To convert it back to float I am using (float) or floatval(). But these functions just truncates the number after converting it to float from string.
Here is my code
$revenue_sum = array_sum(array_column($val2, 'weighted_revenue')); //23722
$test = number_format($revenue_sum, 2); //"23,722.00"
$test = (float)number_format($revenue_sum, 2); //23.0
$test = floatval(number_format($revenue_sum, 2)); //23.0
I want the $test to be 23722.00 for the $revenue_sum = 23722
If $revenue_sum = 2372.2 the $test should be 2372.20
number_format() function can be used as follows:
echo number_format($revenue_sum, 2,'.',''); // will return 23722.00 for the $revenue_sum = 23722
You are trying to type cast with ',' value, it is truncating the string.
you can try this
<?php echo sprintf("%2.2f", 8900.258); ?>
which will output as
8900.26
If you assign a floating point value to a variable, then it is converted to an internal binary format (usually using IEEE 754). Not all possible values has an internal representation. So while scanning a text, the float is rounded to the nearest possible value. So for example 1.23 is rounded to 1.22999999999999998.
Because of the internal representation, there is no difference between 100 or 1e2 or 100.0 or 100.0000.
And when printing a floating point value without any formatting instruction, PHP guess a good format and rounding some digits. So 1.22999999999999 is displayed as 1.23(may varies on different systems).
In general: As long you are calculating, formatting doesn't matter. It is mostly the best, to ignore the decimal fragments on debugging. But when printing (=converting to text), use functions like format_number() or any of the printf() functions.
To be more pragmatic:
Related
I want to show a float number in php string.
something like:
My float number is: 0.00003485
But when I am using echo I see it like this:
My float number is: 3.485E-5
Also, I know I can use printf("%.10f",$float) code, but I need to use it in lots of places in my string, So I can't use printf.
What code should I use on a string, to show floats as they are? I don't want that shorted number (3.485E-5).
At some condition i am prefer declaration float number as string:
MyFloatNumber = "0.0000000000000000000000003485";
so,
echo MyFlatNumber;
//0.0000000000000000000000003485
I know I can use printf("%.10f",$float) code, but I need to use it in lots of places in my string, So I can't use printf.
I have to respectfully disagree with that:
printf('My float number is: %1$.8f (again: %1$.8f; once more: %1$.8f)', 0.00003485);
Or, if you need it in a string:
$foo = sprintf('My float number is: %1$.8f (again: %1$.8f; once more: %1$.8f)', 0.00003485);
Of course, if you mean it's against project style guidelines or company policy, that's another story.
What code should I use on a string, to show floats as they are?
Really? Floats in PHP are a 64-bit IEEE 754 double precision format bitmap. According to this online converter, number 0.00003485 would be:
0010010001010111110011100001110100101110111001001111
Of course, they aren't actual ones and zeroes but different voltage levels ;-)
You can write a function to handle this in any way you want. Why not?
function fval($f, $precision = 9) {
return number_format($f, $precision);
}
Then any place you need to format, call it out:
$f = 3.485E-5;
echo fval($f); // this will print: 0.000003485
I have a string ($maxDeposit) which is a numeric monetary value. So, for example:
123.00
This string is being passed in to jQuery, it needs to be passed in as a numeric data type. I'm achieving this using the following:
$maxDeposit = floatval($maxDeposit);
This loses the last last decimal place however, so my number looks like:
123.0
I have this method of converting the number to two decimal places:
$maxDeposit = sprintf('%0.2f', round($maxDeposit, 2));
However this also converts the number back to a string. Is there a way I can convert the string to a float but keep the last decimal place? Thanks
No, float is a numeric value, and 123.00 is its representation with 2 decimal places. It is responsibility of view layer to format numbers. In your case it is jQuery, e.g. console.log(maxDeposit.toFixed(2)).
I think, You can use floatval/float and number_format.
$maxDeposit = number_format(floatval($maxDeposit), 2);
or
number_format((float)$maxDeposit, 2, '.', '');
http://php.net/manual/pt_BR/function.number-format.php
How come the result for
intval("19.90"*100)
is
1989
and not 1990 as one would expect (PHP 5.2.14)?
That's because 19.90 is not exactly representable in base 2 and the closest approximation is slightly lower than 19.90.
Namely, this closest approximation is exactly 2^-48 × 0x13E66666666666. You can see its exact value in decimal form here, if you're interested.
This rounding error is propagated when you multiply by 100. intval will force a cast of the float to an integer, and such casts always rounds towards 0, which is why you see 1989. Use round instead.
You can also use bc* function for working with float :
$var = bcmul("19.90", "100");
echo intval($var);
intval converts doubles to integers by truncating the fractional component of the number. When dealing with some values, this can give odd results. Consider the following:
print intval ((0.1 + 0.7) * 10);
This will most likely print out 7, instead of the expected value of 8.
For more information, see the section on floating point numbers in the PHP manual
Why are you using intval on a floating point number? I agree with you that the output is a little off but it has to do with the relative inprecision of floating point numbers.
Why not just use floatval("19.90"*100) which outputs 1990
I believe the php doc at http://de2.php.net/manual/en/function.intval.php is omitting the fact that intval will not deliver "the integer value" but the integer (that is non-fractional) part of the number. It does not round.
What is the PHP command that does something similar to intval(), but for decimals?
Eg. I have string "33.66" and I want to convert it to decimal value before sending it to MSSQL.
How about floatval()?
$f = floatval("33.66");
You can shave a few nanoseconds off of type conversions by using casting instead of a function call. But this is in the realm of micro-optimization, so don't worry about it unless you do millions of these operations per second.
$f = (float) "33.66";
I also recommend learning how to use sscanf() because sometimes it's the most convenient solution.
list($f) = sscanf("33.66", "%f");
If you mean a float:
$var = floatval("33.66")
Or
$var = (float)"33.66";
If you need the exact precision of a decimal, there is no such type in PHP. There is the Arbitrary Precision Mathematics extension, but it will return strings, so it's only usefull for you when performing calculations.
You could try floatval, but floats are potentially lossy.
You could try running the number through sprintf to get it to a more correct format. The format string %.2f would produce a floating-point-formatted number with two decimal places. Excess places get rounded.
I'm not sure if sprintf will convert the value to a float internally for formatting, so the lossy problem might still exist. That being said, if you're only worrying about two decimal places, you shouldn't need to worry about precision loss.
php is a loosely typed language. It doesn't matter if you have
$x = 33.66;
or
$x = "33.66";
sending it to mssql will be the same regardless.
Are you just wanting to make sure it is formatted properly, or is an actual float?
I have a small financial application with PHP as the front end and MySQL as the back end. I have ancient prejudices, and I store money values in MySQL as an integer of cents. My HTML forms allow input of dollar values, like "156.64" and I use PHP to convert that to cents and then I store the cents in the database.
I have a function that both cleans the dollar value from the form, and converts it to cents. I strip leading text, I strip trailing text, I multiply by 100 and convert to an integer. That final step is
$cents = (integer) ($dollars * 100);
This works fine for almost everything, except for a very few values like '156.64' which consistently converts to 15663 cents. Why does it do this?
If I do this:
$cents = (integer) ($dollars * 100 + 0.5);
then it consistently works. Why do I need to add that rounding value?
Also, my prejudices about storing money amounts as integers and not floating point values, is that no longer needed? Will modern float calculations produce nicely rounded and accurate money values adequate for keeping 100% accurate accounting?
If you want precision, you should store your money values using the DECIMAL data type in MySQL.
Your "prejudices" about floats will never be overcome - it's fundamental to the way they work. Without going into too much detail, they store a number based on powers of two and since not all decimal number can be presented this way, it doesn't always work. Your only reliable solution is to store the number as a sequence of digits and the location of the decimal point (as per DECIMAL type mentioned above).
I'm not 100% on the PHP, but is it possible the multiplication is converting the ints to floats and hence introducing exactly the problem you're trying to avoid?
Currency/money values should never be stored in a database (or used in a program) as floats.
Your integer method is fine, as is using a DECIMAL, NUMERIC or MONEY type where available.
Your problem is caused by $dollars being treated as a float and PHP doesn't have a better type to deal with money. Depending on when $dollars is being assigned, it could be being treated as a string or a float, but is certainly converted to a float if it's still a string for the * 100 operation if it looks like a float.
You might be better off parsing the string to an integer "money" value yourself (using a regex) instead of relying on the implicit conversions which PHP is doing.
The code you posted does the multiplication first, forcing a floating point calculation that introduces error, before converting the value to an integer. Instead, you should avoid floating point arithmetic entirely by reversing the order. Convert to integer values first, then perform the arithmetic.
Assuming previous code already validated and formatted the input, try this:
list($bills, $pennies) = explode('.', $dollars);
$cents = 100 * $bills + $pennies;
Your prejudice against floating point values to represent money is well founded because of truncation and because of values being converted from base-10 to base-2 and back again.
Casting does not round() as in round-to-nearest, it truncates at the decimal: (int)3.99 yields 3. (int)-3.99 yields -3.
Since float arithmetic often induces error (and possibly not in the direction you want), use round() if you want reliable rounding.
You should never ever store currency in floating point, because it always get results you don't expect.
Check out php BC Maths, it allow you to store your currency as string, then perform very high precision arithmetic on them.
Instead of using
$cents = (integer) ($dollars * 100);
you may want to try to use:
$cents = bcmul($dollars, 100, 2);
When converting from float to integer, the number will be rounded towards zero (src).
Read the Floating point precision warning.
There's no point in storing money as integer if you enter it through a floating point operation (no pun intended). If you want to convert from string to int and be consistent with your "prejudice" you can simply use string functions.
You can use an arbitrary precision library to divide by 10 (they handle numbers internally as strings), e.g. bcdiv() or gmp_div_q(), but of course, you could have also used it from the beginning for all the math.
Or you can use plain string functions:
<?php
// Quick ugly code not fully tested
$input = '156.64';
$output = NULL;
if( preg_match('/\d+(\.\d+)?/', $input) ){
$tmp = explode('.', $input);
switch( count($tmp) ){
case 1:
$output = $tmp[0];
break;
case 2:
$output = $tmp[0] . substr($tmp[1], 0, 2);
break;
default:
echo "Invalid decimal\n";
}
}else{
echo "Invalid number\n";
}
var_dump($output);
?>