I got a few values I want to sum up and check agains another number like this:
$a = '15';
$b = '5,50';
$c = '-10';
$to_pay = '10,50';
$formated_total = number_format(($a+$b+($c)), 2, ',', ' ');
$this->assertEquals($to_pay, $formated_total);
the asser part is a selenium function I am using so dont think about that, it's just supposed to check if the 2 values are the same. Now the result I get is:
- Expected
+ Actual
-'10,50'
+'10,00'
Why am I losing the value from the decimals?
You should not use "," as decimal point it's not excel. In PHP you need to use DOT
Change your numbers to:
$a = '15';
$b = '5.50';
$c = '-10';
$to_pay = '10.50';
or even better solution would be treat them as numbers not as strings
Change your numbers to:
$a = 15;
$b = 5.50;
$c = -10;
$to_pay = 10.50;
In that way you would get error if you tried using , instead of .
You can also simplify this line:
$formated_total = number_format(($a+$b+($c)), 2, ',', ' ');
to
$formated_total = number_format($a+$b+$c, 2, ',', ' ');
You may be curious why the result is 10. It's because during casting it to number php parser checks in 5,50 the number at the begining which is 5 and ignores the rest.
From manual:
If the string starts with valid numeric data, this will be the value used. Otherwise, the value will be 0 (zero).
Because comma is not a valid decimal point. You need to "convert" $b and $to_pay values to use dots.
Related
I am trying to receive a result of a math operation with small numbers (maximum 8 decimals), I receive a float result, but in a format that make the other numbers stay with an error:
$a = round($x, 8); //returns 0.0478674, that's correct
$b = round($y,8); //returns 0.04786261, that's correct
$z = $a - $b; //z returns 4.7899999999976E-6, and not 0.00000479 as I was expecting
I tried as well
$w = round($z,8); //but w returns 4.79E-6, and not 0.00000479 as I was expecting
My problem is because the number 4.7899999999976E-6 give an error in other calcs and it's a ugly number to show to the user.
How can I make this number be 0.00000479?
you can use number_format:
$w = number_format($z,8);
number_format should do what you require, from the help: https://www.php.net/manual/en/function.number-format.php
For your specific requirement here:
$w = number_format($z,8);
I'm using bcmod and gmp_mod functions in php for handling large numbers.
This works fine:
// large number must be string
$n = "10000000000000000000001";
$y = 1025;
$c = 1025;
// Both works the same (also tested in python)
$y = gmp_mod( (bcpowmod($y, 2, $n) + $c) , $n);
$y = bcmod ( (bcpowmod($y, 2, $n) + $c) , $n);
But the input $n is not static. So I must use type casting like:
$n = (string)10000000000000000000001;
This doesn't work anymore.
for gmp gives this error:
gmp_mod(): Unable to convert variable to GMP - string is not an integer
And about bc, gives me this error:
bcmod(): Division by zero
The problem is, (string) doesn't convert it to string fine. Any idea?
Edit: I found a solution here, but still the input is string:
$bigint = gmp_init("9999999999999999999");
$bigint_string = gmp_strval($bigint);
var_dump($bigint_string);
If You are taking an input for $n it would give you as a string not as int and if you have type casted as int at any point ... taking care the max size of int, the above given no is converted to 1.0E+22 now what happens when you try to type cast (string)1.0E+22 it becomes "1.0E+22" which is obviously just a string and can not be converted to gmp number.
So You need to convert scientific notation to string which will auto include , hence you also need to replace those commas
$n = 10000000000000000000001;
$n = str_replace(",", "", number_format($n));
I have a weird question here. How can I do this.
So I have a decimal number 1.2; I would like to replace the decimal point with an add sign so that it would be 1+2 and output the value which is 3.
This is what I have tried so far.
replace the dot using str_replace
<?php
$a = 1.2;
$added_decimal = str_replace('.','+',$a);
echo $added_decimal;
The above code outputs 1+2, so it does not compute it.
I also tried converting the decimal to an array like so;
<?php
$a = 1 .'.'. 2; //Concatenated it
explode('.',$a); //entered the delimeter
echo $a[0] + $a[2]; //this outputs 3;
So this one works fine, but then the problem would be when $a was 1.20. This would also output 3 if my code above was use. How would I go about getting 1+ 20 and output 21?
Your second code snippet is almost correct. You just need to store the explode() result in a variable. See this code snippet :
<?php
$a = 1 .'.'. 20; //Concatenated it
$x = explode('.',$a); //entered the delimeter
echo $x[0] + $x[1]; //this outputs 21;
When you do $a[0], you actually access the index of the string not the explode() result.
I am sure this is because of the "g" on the end but this is the scenario and results when I try and work out a ratio percent. I always want to divide the highest of 2 numbers by the lowest.
$item1 = "200.00g";
$item2 = "50.00g";
$calc = round((max($item1,$item2) / min($item1,$item2))*100) . "%";
// result: $calc = "400%"
$item1 = "100.00g";
$item2 = "5.00g";
$calc = round((max($item1,$item2) / min($item1,$item2))*100) . "%";
// result: $calc = "2000%"
PROBLEM RESULT:
$item1 = "8.00g";
$item2 = "14.00g";
$calc = round((max($item1,$item2) / min($item1,$item2))*100) . "%";
// result: $calc = "57%"
// I am expecting (14.00g / 8.00g)*100 = "175%"
It's type casting;
$item1 = "8.00";
$item2 = "14.00";
$calc = round((max($item1,$item2) / min($item1,$item2))*100) . "%";
result will be 175%
When you want to use your strings in mathematical operations, and you know that the unit is placed at the end as it is in your example, you can cast your variables to floats:
$item1_numeric = (float) $item1;
But obviously it is better to have the values and the units separated in your variables / database.
Use: substr($item1, 0, -1) instade of $item1, substr($item2, 0, -1) instade of $item2 when you do round.
You can't compare 2 strings with round().
Edit : If $item1 = "200g", ma solution is ok, but if if $item1 = "200.00g" you need to remove "." before round() with for example pregreplace.
Oh, YAPHPB - and one of my favorite ones. Even though it's written in the Doc:
When [max()] given a string it will be cast as an integer when comparing.
... it's only a partial truth: if at least one of compared values is a number, or a numeric string.
Otherwise all the strings will be compared as strings: first {0} characters of each strings will be compared, then {1}, then {2}... etc.
So basically that's what happens here:
echo max("200.00g", "50.00g"); // 50.00g, as '5' > '2'
echo max("200.00g", 50); // "200.00g", as it gets converted to int (become 200)
And that's even more crazy:
echo max("200.00g", "1000.00"); // "200.00g", as '2' > '1'
echo max("200.00", "1000.00"); // "1000.00", as we tried to help you, no, really!
The latter result can actually be predicted by someone knowing of numeric concept: when both strings are pure numbers, they got converted to numbers when compared. Still, I found this behavior unreliable, to say the least.
The bottom line: if you need to compare numbers, compare numbers, period. Type conversion in PHP can get real messy - and bite you in the bottom real hard when you least expect it. )
I need help converting a string that contains a number in scientific notation to a double.
Example strings:
"1.8281e-009"
"2.3562e-007"
"0.911348"
I was thinking about just breaking the number into the number on the left and the exponent and than just do the math to generate the number; but is there a better/standard way to do this?
PHP is typeless dynamically typed, meaning it has to parse values to determine their types (recent versions of PHP have type declarations).
In your case, you may simply perform a numerical operation to force PHP to consider the values as numbers (and it understands the scientific notation x.yE-z).
Try for instance
foreach (array("1.8281e-009","2.3562e-007","0.911348") as $a)
{
echo "String $a: Number: " . ($a + 1) . "\n";
}
just adding 1 (you could also subtract zero) will make the strings become numbers, with the right amount of decimals.
Result:
String 1.8281e-009: Number: 1.0000000018281
String 2.3562e-007: Number: 1.00000023562
String 0.911348: Number: 1.911348
You might also cast the result using (float)
$real = (float) "3.141592e-007";
$f = (float) "1.8281e-009";
var_dump($f); // float(1.8281E-9)
Following line of code can help you to display bigint value,
$token= sprintf("%.0f",$scienticNotationNum );
refer with this link.
$float = sprintf('%f', $scientific_notation);
$integer = sprintf('%d', $scientific_notation);
if ($float == $integer)
{
// this is a whole number, so remove all decimals
$output = $integer;
}
else
{
// remove trailing zeroes from the decimal portion
$output = rtrim($float,'0');
$output = rtrim($output,'.');
}
I found a post that used number_format to convert the value from a float scientific notation number to a non-scientific notation number:
Example from the post:
$big_integer = 1202400000;
$formatted_int = number_format($big_integer, 0, '.', '');
echo $formatted_int; //outputs 1202400000 as expected
Use number_format() and rtrim() functions together. Eg
//eg $sciNotation = 2.3649E-8
$number = number_format($sciNotation, 10); //Use $dec_point large enough
echo rtrim($number, '0'); //Remove trailing zeros
I created a function, with more functions (pun not intended)
function decimalNotation($num){
$parts = explode('E', $num);
if(count($parts) != 2){
return $num;
}
$exp = abs(end($parts)) + 3;
$decimal = number_format($num, $exp);
$decimal = rtrim($decimal, '0');
return rtrim($decimal, '.');
}
function decimal_notation($float) {
$parts = explode('E', $float);
if(count($parts) === 2){
$exp = abs(end($parts)) + strlen($parts[0]);
$decimal = number_format($float, $exp);
return rtrim($decimal, '.0');
}
else{
return $float;
}
}
work with 0.000077240388
I tried the +1,-1,/1 solution but that was not sufficient without rounding the number afterwards using round($a,4) or similar