I'm hoping to do some math operations on numbers being represented as strings. So far, I haven't found anything that could do multiplication.
Thanks!
You need of the bcmul() method. You too can take a look on BC Math functions.
Example:
echo bcmul('2.123456', '4.7891011', 6); // 6 is the precision
You mean bcmul?
http://www.php.net/manual/en/function.bcmul.php
bcmul — Multiply two arbitrary precision number
string bcmul ( string $left_operand , string $right_operand [, int $scale ] )
Multiply the left_operand by the right_operand.
Related
Why does this code provide 853 instead of 854?
(int) ((float) ( "8.54") * 100);
How do I convert (string) "8.54" into (integer) 854?
First of all, read Is floating point math broken?
8.54 happens to be one of those numbers which can be written precisely in decimal, but not in binary, so (float)"8.54" will actually create a number very very close to, but slightly under, 8.54.
Multiplying that by 100 will create a number very very close to, but slightly under, 854. And casting to int will find the next smallest integer (e.g. 853.9 becomes 853, not 854).
I can think of two solutions:
After multiplying by 100, round to the nearest whole number, then convert to integer. Unlike 8.54, 854 itself can be represented precisely in floating point, so round(8.54 * 100) will give a number that is exactly 854, rather than slightly under it. So (int)round((float)"8.54" * 100) will give 854 as an integer.
Instead of multiplying by 100, remove the . from the string, and convert to int directly, e.g. (int)str_replace(".", "", "8.54"));
intval(str_replace(".", "", "8.54"))
Try without (int).
Like this => (float) ( "8.54") * 100;
In this case (int) not necessary.
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:
PHP Suggested to use these function for floating point number comparison [here]
bccomp — Compare two arbitrary precision numbers
int bccomp ( string $left_operand , string $right_operand [, int $scale ] )
gmp_cmp — Compare numbers
int gmp_cmp ( resource $a , resource $b )
I used bccomp but I cant still get correct result:
<?php
$n1 = bcdiv(1, 2.36, 4);
$n2 = bcdiv(4237288, 10000000, 4);
echo bccomp( $n1, $n2, 4); // 0! must be 1
echo "<br>\n";
var_dump(bcdiv(1, 2.36, 4)); // string(6) "0.4237"
echo "<br>\n";
var_dump(bcdiv(4237288, 10000000, 4)); // string(6) "0.4237"
?>
So far, I knew that the result of 1/2.36 is equal to (0.4237288135593220338983050847457627118644067796610169491525423728813559322033898305084745762711864406......)
Then, how to I know that the number of decimals is great like this?
The possible solution:
$n1 = bcdiv(1, 2.36, 400);
$n2 = bcdiv(4237288, 10000000, 400);
echo bccomp( $n1, $n2, 400); //1
I think this solution is till not more usable.
Any suggestion?
When you comparing float numbers you MUST choose comparing scale. If 400 is nessary, so it's your scale.
Or... you can try to define your own divide function and compare result on every step of scaling of division. It might be a recursive function.
First, if you want to compare floats, you can use the built-in comparison operators such as <, as mentioned under the heading “Comparing float” on the page you linked to.
Second, if you do not want a direct comparison of the floating-point values (but want some sort of tolerance or partial comparison), you have not specified what comparison you actually want. For the needs of your application, under precisely what circumstances should a comparison return less-than, equal-to, and greater-than?
Third, bccomp is an atrocious way to compare floating-point values:
By default, it attempts to use the “number of digits” in the values to determine the tolerance to compare. However, binary floating-point values do not have a number of decimal digits in the way this code tries to measure them.
Even if they did, the amount of error that could be present in floating-point values after various operations is not a function of the number of decimal digits in the number, so the number of digits is not a good measure of how much tolerance should be accepted.
Once you determine how much error tolerance is acceptable, a digit-by-digit comparison fails to allow for that tolerance. E.g,, if you want to accept as equal two values if they differ by less than .01 but you compare the values 3.4951 and 3.4949 by comparing their two-digit representations “3.50” and “3.49”, they will be reported as unequal even though they differ by only .0002.
Given the following cod:
$number = 1050.55;
var_dump($number - floor($number));
Why does the above code returns the following result?
float(0.54999999999995)
I want a fixed value like 0.55 in this case. Can you help me please?
Floating point operations are not precise and the remainder errors are common.
If you know, what is your desired precission (eg. two digits after the dot), you can use round() function on the result.
In this case this will be:
$number = 1050.55;
var_dump(round($number - floor($number), 2));
For most floats, binary can only approximately represent the correct number. The rule is to perform floor(), ceil() or fmod() last in a series of calculations. At least only do integer math after you use them. If you cast an int to a float, as in your code, then floor() is not going to behave has you expect.
Use printf() when printing floats. Its conversion routines usually do a much better job and give you the answer you expect when truncating floats.
EDIT: Or, to be more exact, printf() works on the decimal character representation of the number when deciding where to truncate so you don't get any weird, unspecified, binary/decimal conversion artifacts.
See this question. While that is about java and you're asking about PHP the math is the same.
I have two numbers in PHP. 81.0000 and 81. While they are equal in reality I cannot get them to be equal in PHP.
I have tried casting both numbers to float and they still won't come thought as equal.
Anyone have any idea how I can have these two numbers be the same?
Check out the awesome WARNING on php.net:
never trust floating number results to the last digit, and never compare floating point numbers for equality.
The very best you can to is type cast to (int), or use PHP rounding functions like round(), floor(), or ceil().
UPDATE
Check out the Arbitrary Precision Math Functions such as the one #Jose Vega pointed out in his answer. They should get you where you need to go.
bccomp — Compare two arbitrary precision numbers
bccomp ( string $left_operand , string $right_operand [, int $scale ] )
<?php
echo bccomp('1', '2') . "\n"; // -1
echo bccomp('1.00001', '1', 3); // 0
echo bccomp('1.00001', '1', 5); // 1
?>