In a array of numbers that have 4 decimals, how can I round them with only 2 decimals? I'm also using a str_replace to replace commas with dots.
foreach($data as $key => $value) {
$vf .= str_replace(",", ".", round($value['vf'])); // gives 1.111, 2.222 etc
$vf .= str_replace(",", ".", round($value['vf'],2)); // does nothing
}
How can I round the values to a number with 2 digits, like 1.11?
You can use number_format.
$n = 12.34567890;
echo number_format($n, 2, '.');
// 12.35
You can even use it to add a thousands separator:
$n = 12345.67890;
echo number_format($n, 2, '.', ',');
// 12,345.68
Or you can use round.
$n = 12.34567890;
echo round($n, 2);
// 12.35
Related
I am having few values
99.00
99.90
99.01
FYI, I am already getting the above 3 values after having number_format($value, 2) applied to them
But now I want to strip the decimals without rounding them off such as
99.00 to 99
99.90 to 99.9
99.01 to 99.01 remains same
How can achieve this? Please devise me a way guys.
I just need a function which checks following:
Whether a given number is decimal i.e having "." and digits after decimal
Whether the last digit is 0, if yes, then get rid of the last digit
Whether both the digits after decimal points are 0, if yes, remove them.
If any of them are not 0, then they should remain there, like in case of 99.09 it should remain intact, in case of 99.90 it should be 99.9.
Awaiting your ideas. Thanks in advance.
By adding 0 to the number, the rightmost zeros are removed:
$num1 = 99.00;
$num2 = 99.90;
$num3 = 99.01;
$num4 = 99.012;
$num5 = 99.0123;
$num1 = number_format(99.00, 2, '.', '') + 0;
$num2 = number_format(99.90, 2, '.', '') + 0;
$num3 = number_format(99.01, 2, '.', '') + 0;
$num4 = number_format(99.012, 2, '.', '') + 0;
$num5 = number_format(99.0123, 2, '.', '') + 0;
echo "$num1\n";
echo "$num2\n";
echo "$num3\n";
echo "$num4\n";
echo "$num5\n";
Output:
99
99.9
99.01
99.01
99.01
Try it here.
With a function:
function round2no0(&$num)
{
$num = number_format($num, 2, '.', '') + 0;
}
usage:
$num1 = 99.00;
$num2 = 99.90;
$num3 = 99.01;
$num4 = 99.012;
$num5 = 99.0123;
round2no0($num1);
round2no0($num2);
round2no0($num3);
round2no0($num4);
round2no0($num5);
echo "$num1\n";
echo "$num2\n";
echo "$num3\n";
echo "$num4\n";
echo "$num5\n";
function round2no0(&$num)
{
$num = number_format($num, 2, '.', '') + 0;
}
Output:
99
99.9
99.01
99.01
99.01
Edit:
Added , '.', '' parameters to number_format to handle also numbers with thousands maintaining the machine-format 12345.12.
Try it here.
you should be able to just wrap it in a floatval()
Try this:
echo round(99.001, 2), PHP_EOL;
echo round(99.901, 2), PHP_EOL;
echo round(99.011, 2), PHP_EOL;
Output:
99
99.9
99.01
If you use a custom notation with number_format, you can use preg_replace to remove the decimal point separator and trailing zeroes after it.
// Default notation
echo preg_replace('/\.?0+$/', '', number_format(9990.00, 2)); // "9,990"
echo preg_replace('/\.?0+$/', '', number_format(9990.90, 2)); // "9,990.9"
echo preg_replace('/\.?0+$/', '', number_format(9990.01, 2)); // "9,990.01"
// French notation
echo preg_replace('/,?0+$/', '', number_format(9990.00, 2, ',', ' ')); // "9 990"
echo preg_replace('/,?0+$/', '', number_format(9990.90, 2, ',', ' ')); // "9 990,9"
echo preg_replace('/,?0+$/', '', number_format(9990.01, 2, ',', ' ')); // "9 990,01"
I'm having some trouble getting the price to show correct on my website. Currently i have a row VerkoopPP40 which is a VARCHAR input. In this row there is a price e.g. 89,5 or just 9. When I try to get these values it does some unexpected things.
**** Update ****
I've just tried this code:
<?php
function formatNumber($number, $format=[], $oldDecimalSeparator=",.·'", $multiplier=1)
{
if ($format) {
$format += ['numOfDecimals' => 0, 'decimalSeparator' => '.', 'thousandSeparator' => '']; # Default format
# Find decimal separator
# The decimal separator is the one that is the last and does not occur more than once
if ($letters = str_replace(' ', '', $number)) { # Replace spaces
if ($letters = preg_replace('/^-/', '', $letters)) { # Remove minus
if ($letters = preg_replace('/[0-9]/', '', $letters)) { # Get all non digits
$lastletter = substr($letters, -1); # Returns last char
if (substr_count($letters, $lastletter) == 1) {
if (strpos($oldDecimalSeparator, $lastletter) !== false)
$oldDecimalSep = $lastletter;
else
return $number;
}
}
}
}
$number = preg_replace('/[^0-9-]/', '', $number); # Remove all non digits except 'minus'
if ($oldDecimalSep)
$number = str_replace($oldDecimalSep, '.', $number); # Format to float
if ($multiplier != 1)
$number = $number * $multiplier;
# Convert float to new format
$number = number_format($number,
$format['numOfDecimals'],
$format['decimalSeparator'],
$format['thousandSeparator']
);
}
return $number;
}
This returns: 9,00 and 895,00 so the comma is in a different place right now. It's something I guess... Anyone got an idea to move the comma and remove a 0.
**** End Update ****
And echo-ed it like this:
<td><p>vanaf " . formatNumber($number, [
'numOfDecimals' => 2,
'decimalSeparator' => ',',
'thousandSeparator' => ' '
], ',.') . " p.p. <small>Excl btw</small></p></td>
If I just echo the VerkoopPP40 row it returns: €89,5 or €9.
So I googled around some and found this:
$var = $row["VerkoopPP40"];
$var = ltrim($var, '0');
$foo = $var;
$prijzen = number_format($foo, 2, ',', '');
This turns the . into a ,. But also returns €9,00 for the row that has 9 in it. But the strange thing is the row that has 89.5 in it now just returns €89,00. So somewhere in the code it rounds the numbers down.
Does anyone know how to get the price to show just €9,00 and €89,50 respectively.
I tried the following codes as well:
SELECT ROUND(VerkoopPP40,2) AS RoundedPrice
As database query. That didn't work.
$prijzen = CAST($prijzen as decimal(2,2));
Also didn't work. Any more ideas?
Don't know if this will help you, but found in the comments of the PHP doc : "To prevent the rounding that occurs when next digit after last significant decimal is 5 (mentioned by several people)..." read more
$num1 = "89,5";
$num2 = str_replace(',', '.', $num1);
$price = number_format($num2, 2, '.', '');
echo"[ $price ]";
you should use number_format but in the right way let me explain it to you
you tried this with 89.5
$prijzen = number_format($foo, 2, ',', '');
but this is written for 89,5 not for 89.5
//this will work for you
$var = $row["VerkoopPP40"];
echo 'raw output from database is :'.$var;
$var = $var / 10;
echo 'after this step the number is :'.$var;
$var = number_format($var, 2, '.', '');
echo 'after this step the number is :'.$var;
number_format(the input number, decimal places, 'the divider between whole numbers and decimals', '')
I've tried to write a function that will take an array of different amounts and align the decimal places, by adding the appropriate amount of to each number with a lesser length than the number with longest length.
It seems pretty long though, and I wonder if anyone has some insight on how I could make is shorter and more efficient.
$arr = array(12, 34.233, .23, 44, 24334, 234);
function align_decimal ($arr) {
$long = 0;
$len = 0;
foreach ( $arr as &$i ){
//change array elements to string
(string)$i;
//if there is no decimal, add '.00'
//if there is a decimal, add '00'
//ensures that there are always at least two zeros after the decimal
if ( strrpos( $i, "." ) === false ) {
$i .= ".00";
} else {
$i .= "00";
}
//find the decimal
$dec = strrpos( $i, "." );
//ensure there are only two decimals
//$dec+3 is the decimal plus two characters
$i = substr_replace($i, "", $dec+3);
//if $i is longer than $long, set $long to $i
if ( strlen($i) >= strlen($long) ) {
$long = $i;
}
}
//locate the decimal in the longest string
$long_dec = strrpos( $long, "." );
foreach ( $arr as &$i ) {
//difference between $i and $long position of the decimal
$z = ( $long_dec - strrpos( $i, "." ) );
$c = 0;
while ( $c <= $z ) {
//add a for each number of characters
//between the two decimal locations
$i = " " . $i;
$c++;
}
}
return $arr;
}
it works okkaaay... just seems really verbose. I'm sure there are a million ways to make it much shorter and more professional. Thanks for any ideas!
Code:
$array = array(12, 34.233, .23, 44, 24334, 234);;
foreach($array as $value) $formatted[] = number_format($value, 2, '.', '');
$length = max(array_map('strlen', $formatted));
foreach($formatted as $value)
{
echo str_repeat(" ",$length-strlen($value)).$value."<br>";
}
Output:
12.00<br>
34.23<br>
0.23<br>
44.00<br>
24334.00<br>
234.00<br>
Rendered by browser:
12.00
34.23
0.23
44.00
24334.00
234.00
Is using a space a requirement for the display? If you don't mind having "30" coming out as "30.000" you could use the number_format to do most of the work for you, after you figured out the max number of decimal places to use.
$item = "40";
$len = 10;
$temp = number_format($item,$len);
echo $temp;
Another would be to use sprintf to format:
$item = "40";
$len = 10;
$temp = sprintf("%-{$len}s", $item);
$temp = str_replace(' ', ' ',$temp);
echo $temp;
Have you considered using HTML elements alongside CSS alignment to do this for you?
For instance:
<div style="display:inline-block; text-align:right;">$10.00<br />$1234.56<div>
This would ease the issue of using spaces to manually adjust the alignment. Since you're aligning to the right and there are two decimal places, the decimals will line up as you wish. You could also do this using a <table> and in both scenarios, you're able to simply retrieve the full value through JS if need be.
Lastly, using spaces assumes you're using a fixed-width font which may not necessarily be the case. CSS alignment allows you to handle this much more eloquently.
I have this array:
$numbers = array(1, 2, 3);
I can grab a random value from it like so:
$numbers[array_rand($numbers)];
But I need to come up with different random variations of these values. For example
1
13
123
3
32
12
3
12
13
231
etc...
As you can see a number can't repeat more than once in each set, so we can't have sets like:
113
232
33
etc...
How can this be done?
This solution lets you handle with any size of array...same operation..
<?php
$numbers = array(1, 2, 3);
$count=count($numbers);
$result="";
$iterations=rand(1,$count);
for($i=0;$i<$iterations;$i++)
{
$selected=$numbers[array_rand($numbers)];
$numbers=remove_item_by_value($numbers,$selected);
$result=$result.$selected;
}
function remove_item_by_value($array, $val) {
foreach($array as $key => $value) {
if ($value == $val)
unset($array[$key]);
}
return $array;
}
echo $result;
?>
Now it will return you even random sized string:).
Define the array, get a random length, shuffle the array, slice the array:
$numbers = array(1, 2, 3);
$length = rand(1, count($numbers));
shuffle($numbers);
$result = array_slice($numbers, -$length);
Demo
One possible solution is:
$number1 = array(1, 2, 3);
$number2 = array(1, 2, 3);
$number3 = array(1, 2, 3);
$loop = 10;
for($i=0;$i<$loop;$i++) {
$bool1 = mt_rand(0, 1);
$bool2 = mt_rand(0, 1);
$randomNumber = $number1[array_rand($number1)];
if($bool1)
$randomNumber .= $number2[array_rand($number2)];
if($bool2)
$randomNumber .= $number3[array_rand($number3)];
echo $randomNumber;
}
This both randomly decides to choose between 1-3 digits and can use the numbers 1-3 as many times as possible. Just change $loop to the amount of times you want to run the generator.
I also just realised you could simplify this further:
$numbers = array(1, 1, 1, 2, 2, 2, 3, 3, 3);
$limit = mt_rand(1, 3);
$keys = array_rand($numbers, $limit);
$number = "";
if($limit == 1)
$number .= $numbers[$keys];
else {
foreach ($keys as $value) {
$number .= $numbers[$value];
}
}
Insert each number the maximum amount of times into the array you want it to appear in any number (maximum number of digits you want to generate). And randomly generate a number between 1-3 with mt_rand() to use as your array_rand() limit.
Well, define "random" (what are the chances of getting a 1-digit long string, or a 2-digit long, or a 3-digit long?), but here's one method:
$len = rand( 1, count( $numbers ) );
$result = '';
shuffle( $numbers );
for( $i = 0; $i < $len; ++$i ) {
$result .= $numbers[ $i ];
}
Note that this changes the original array. Make a copy of it if it shouldn't be changed.
I hold decimals in a database using DECIMAL(10,5)
I would like to format these numbers according to a few rules:
A zero decimal should display as 0
Show a long decimal (no trailing zero's) with all of it's numbers
When possible, I would like to only show up to 2 decimal places (when there are trailing zeros)
Here are some examples:
The left side corresponds to how the number is stored in database.
The right number is how I would like to display the number in my application.
0.00000 => 0
0.51231 => 0.51231
0.12000 => 0.12
0.40000 => 0.40
0.67800 => 0.678
12.10000 => 12.10
This will work for you:
function format($x){
if(!(int)substr_replace($x, '', $dpos = strpos($x, '.'), 1))
return 0;
else
return str_pad((rtrim($x, '0')), $dpos + 3, '0');
}
Example
I would utilize the number_format function in php to actually do the formatting after you determine the amount of decimal places to the number has.
Source:
http://php.net/manual/en/function.number-format.php
Example Usage:
$number = 1234.56;
// english notation (default)
$english_format_number = number_format($number);
// 1,235
// French notation
$nombre_format_francais = number_format($number, 2, ',', ' ');
// 1 234,56
$number = 1234.5678;
// english notation without thousands separator
$english_format_number = number_format($number, 2, '.', '');
// 1234.57
Well here's one way (I haven't tested it yet so there may be minor errors):
$pattern = '/([0-9]+)\\.{0,1}([0-9]*?)0*$/';
$subject = 12.10000;
$matches = array();
$result = preg_match ($pattern, $subject, $matches);
$number = $matches[1];
if ($matches[2] != 0) {
$number .= '.'.$matches[2];
if ($matches[2] < 10) {
$number .= '0';
}
}
echo $number;
And here's another way (probably a little faster):
$x = 1.000;
$result = (int)$x;
$trimmed = rtrim($x, 0);
if ($trimmed[strlen($trimmed) - 1] != '.') {
if ($trimmed[strlen($trimmed) - 2] == '.') {
$result = $trimmed.'0';
} else {
$result = $trimmed;
}
}
echo $result;
I haven't used it myself, but theres the NumberFormatter class: http://php.net/manual/class.numberformatter.php as part of the Internationalization Functions for this stuff. Using that is a little more involved i think though.
I know this is an old question, but the following quick function I wrote for my own project might help someone looking for this.
function number_format_least_dp($number, $decimal_point = '.', $thousand_seperator = ','){
if (floatval($number) == (int)$number){
$number = number_format($number, 0, $decimal_point, $thousand_seperator);
} else {
$number = rtrim($number, '.0');
$number = number_format($number, strlen(substr(strrchr($number, '.'), 1)), $decimal_point, $thousand_seperator);
}
return $number;
}