PHP Retain all decimals when using abs function - php

I'm using the abs function to get the positive value of a negative number as follows:
$totalTax = -4.50 ;
echo abs($totalTax);
which is working well except it is dropping the 0 and returns 4.5 instead of 4.50.
Not sure why it's doing this or what the best method to retain all digits when using the abs function to convert a negative number to a positive? I need the 2 decimals regardless if the cents value is 0 for importing into an accounting system which only accepts 2 decimals and not 1.

It's just because how PHP outputs leading/trailing zeros - trims them. Because there is infinite number of zeros after last non-zero number
e.g. echo 00000.1000000 will output 0.1
You should format your number to keep that leading and trailing zeros.
echo number_format($totalTax, 2, '.', '');
// -> 4.50

You can try with the number_format() function. There is no possibility to retain trailing 0 with using only the abs() function.
Here is code you try:
$totalTax = -4.50 ;
$total_sub = abs($totalTax);
echo number_format($total_sub, 2);

Related

How to get two digit decimal number without change of second digit decimal (1.255 => 1.25)?

I know one function "round()" that it gives me a two-digit decimal number. But the problem is that this will changed the second decimal digit according to the third decimal digit of the number.
For example, if the number is 1.255 and we used function round below code.
echo round(1.255, 2);
And the result will be below.
1.26
But I want result like below.
1.25
Please help me if anyone knows other function that will do this thing.
You could use string functions like substr and strpos()
<?php
$str = strval(1.255);
echo substr($str,0,strpos($str,".") === false ? strlen($str) : strpos($str,".") + 3);
Demo: https://3v4l.org/12E48

PHP lowest common denomination

I am working on a payment gateway and the amount parameter needs to formatted this way:
amount – (digits only) the integer value of the transaction in lowest common denomination (ex. $5.20 is 520)
I have already removed the $ and all values will be rounded to 2 decimal places.
In PHP if i try to cast amount as int ie (int)$amount I am going to loose the .20 in the example though its needed. What could be the best way to go about this?
You can multiply the amount by 100 and then convert it...
$amount = (int)($amount*100);
So 5.20 becomes 520.
If you are not sure about the number of decimal places, you could use regex to strip non-digital values from your string.
echo preg_replace('~\D+~', '', $amount);
\D means any non-numeric character. + means one or more.
If the value needs to be cast as an integer (rather than a string) write(int) just before preg_replace.
Of course, you could use str_replace() and target known characters like: $ and . (and - if it may exist).
After some feedback from the OP...
You can round and format in one step with number_format().
Code: ( Demo: https://3v4l.org/ir54s )
$amounts = array(0.001, 0.005, 5.20, 5.195, 5.204, 5);
foreach ($amounts as $amount) {
echo $amount , "->" , (int)number_format($amount, 2, '', '')."\n";
}
Output:
0.001->0
0.005->1
5.2->520
5.195->520
5.204->520
5->500

Prevent number_format from rounding numbers - add commas and keep the decimal point - PHP

Number format adds the commas I want but removes the decimals.
echo number_format("1000000.25");
This returns 1,000,000
I want it to return 1,000,000.25
I need both the commas and the decimals, without any number rounding. All my values are decimals. They vary in length.
Do I have to use something other than number format?
In case what you meant by they vary in length is related to the decimal part, take a look at this code:
function getLen($var){
$tmp = explode('.', $var);
if(count($tmp)>1){
return strlen($tmp[1]);
}
}
$var = '1000000.255555'; // '1000000.25'; // '1000000';
echo number_format($var, getLen($var));
Some tests
Output for 1000000.255555:
1,000,000.255555
Output for 1000000.25:
1,000,000.25
Output for 1000000:
1,000,000
It counts how many chars there are after the . and uses that as argument in the number_format function;
Otherwise just use a constant number instead of the function call.
And some reference...
From the manual -> number_format():
string number_format ( float $number [, int $decimals = 0 ] )
And you can see in the description that
number
The number being formatted.
decimals
Sets the number of decimal points.
And a bit more:
[...]If two parameters are given, number will be formatted with decimals
decimals with a dot (".") in front, and a comma (",") between every
group of thousands.
$number = '1000000.25';
echo number_format($number, strlen(substr(strrchr($number, "."), 1)));
Explanation:
Number Format takes a second parameter which specifies the number of decimal places required as pointed out in the docs. This Stack overflow answer tells you how to get the number of decimal places of your provided string
The docs for number_format() indicate the second parameter is used to specify decimal:
echo number_format('1000000.25', 2);
Ref: http://php.net/manual/en/function.number-format.php

Always round up on first decimal

I want my variable's first decimal to always be rounded up. For example:
9.66 goes to 9.7
9.55 goes to 9.6
9.51 goes to 9.6
9.00000001 goes to 9.1
How do I do this?
Use round() with an optional precision and round type arguments, e.g.:
round($value, 1, PHP_ROUND_HALF_UP)
The optional second argument to round() is the precision argument and it specifies the number of decimal digits to round to. The third optional argument specifies the rounding mode. See the PHP manual for round for details.
Using round() does not always round up, even when using PHP_ROUND_HALF_UP (e.g. 9.00001 is not rounded to 9.1). You could instead try to use multiplication, ceil() and division:
ceil($value * 10.0) / 10.0
Since these are floating-point values, you might not get exact results.
I made couple tests and suggest the following answer with test cases
<?php
echo '9.66 (expected 9.7) => '.myRound(9.66).PHP_EOL;
echo '9.55 (expected 9.6) => '.myRound(9.55).PHP_EOL;
echo '9.51 (expected 9.6) => '.myRound(9.51).PHP_EOL;
echo '9.00000001 (expected 9.1) => '.myRound(9.00000001).PHP_EOL;
echo '9.9 (expected ??) => '.myRound(9.9).PHP_EOL;
echo '9.91 (expected ??) => '.myRound(9.91).PHP_EOL;
function myRound($value)
{
return ceil($value*10)/10;
}
I'm not a php programmer so will have to answer in "steps". The problem you have is the edge case where you have a number with exactly one decimal. (e.g. 9.5)
Here's how you could do it:
Multiply your number by 10.
If that's an integer, then return the original number (that's the edge case), else continue as follows:
Add 0.5
Round that in the normal way to an integer (i.e. "a.5" rounds up).
Divide the result by 10.
For step (2), sniffing around the php documentation reveals a function bool is_int ( mixed $var ) to test for an integer.
You will need a custom ceil() function, your requirements cannot be satisfied by the default function or by the round.
Use this: online test
You can use this technique. Just explode the given number / string, get the number which is next value / digit of the .. after getting this you need to increment that value and check if the value is greater than 9 or nor, if then divide that and add the carry to the first portion of the main number.
$var = '9.96';
$ar = explode(".", $var);
$nxt = substr($ar[1], 0, 1) + 1;
if($nxt > 9){
$tmp = (string) $nxt;
$num = floatval(($ar[0] + $tmp[0]).".".$tmp[1]);
}
else
$num = floatval($ar[0].".".$nxt);
var_dump($num); // float(10)

Convert strings to numbers without losing decimals

I'm developing a map and I have to save this parameters on Parse database:
lat.: 20.6350 . Long: -103.5334
The problem is when i convert them into numbers, that function converts 20.6350 to 20.635. ¿What can I do in order tu preserve the last zero?
You should specify the sig figs and they will display properly.
$lat = "20.6350";
$lng = "-103.5334";
print number_format($lat, 4); // 4 sig figs
print number_format($lng, 4);
See http://php.net/number_format for additional formatting info
UPDATE
Based on your comments above, seems the string you're pulling varies in length, correct?
Why not just get the amount of sig figs after the decimal then use that as the second argument in number_format()? I'm sure there is a more appropriate way to handle, but this would work I believe.
// Calculate sig figs
$length = strlen($lng) - (stripos($lng, '.') + 1);
number_format($lng, $length);
or in one line
number_format($lng, strlen($lng) - (stripos($lng, '.') + 1));
if you want the numbers with four decimals in your database you could use the Decimal type. Under length you could enter 6,4 representing maximum of 6 digits in total and 4 digits behind the point.
If you want to display the number in PHP you could use the number_format() function
echo number_format($longitude, 4);

Categories