round number in php - php

Hello how do I round the following to two decimal places .
echo
"<div class='quote-results-result'>ex VAT £" .
((($_POST['qtylitres'] * $price ['Price']) + $fuelmargin['margin']) / 1.2) .
"</div>"
I need to round the price bit of a php novice.

Use number_format function like this:
$number = 1234.56789
$new_number = number_format($number, 2, '.', '');
echo $new_number;
Output: 1234.57

round($VARIABLE_NAME,2); //This rounds off the variable to 2 decimal places

Use round function from php manuals
echo round(3.4); // 3
echo round(3.5); // 4
echo round(3.6); // 4
echo round(3.6, 0); // 4
echo round(1.95583, 2); // 1.96
echo round(1241757, -3); // 1242000
echo round(5.045, 2); // 5.05
echo round(5.055, 2); // 5.06

function roundoff($number,$format)
{
if($number != '') {
$newNumber=$this->exp_to_dec($number);
$num = explode('.',$newNumber);
//pr($num);
if(isset($num[1]) && $num[1] != 0) {
$dec = substr($num[1],0,$format);
} else {
$dec = '00';
}
} else {
$num[0] = 0;
$dec = '00';
}
return $num[0].'.'.$dec;
}
function exp_to_dec($float_str)
// formats a floating point number string in decimal notation, supports signed floats, also supports non-standard formatting e.g. 0.2e+2 for 20
{
// make sure its a standard php float string (i.e. change 0.2e+2 to 20)
// php will automatically format floats decimally if they are within a certain range
$float_str = ( string ) (( float ) ($float_str));
// if there is an E in the float string
if (($pos = strpos ( strtolower ( $float_str ), 'e' )) !== false) {
// get either side of the E, e.g. 1.6E+6 => exp E+6, num 1.6
$exp = substr ( $float_str, $pos + 1 );
$num = substr ( $float_str, 0, $pos );
// strip off num sign, if there is one, and leave it off if its + (not required)
if ((($num_sign = $num [0]) === '+') || ($num_sign === '-'))
$num = substr ( $num, 1 );
else
$num_sign = '';
if ($num_sign === '+')
$num_sign = '';
// strip off exponential sign ('+' or '-' as in 'E+6') if there is one, otherwise throw error, e.g. E+6 => '+'
if ((($exp_sign = $exp [0]) === '+') || ($exp_sign === '-'))
$exp = substr ( $exp, 1 );
else
trigger_error ( "Could not convert exponential notation to decimal notation: invalid float string '$float_str'", E_USER_ERROR );
// get the number of decimal places to the right of the decimal point (or 0 if there is no dec point), e.g., 1.6 => 1
$right_dec_places = (($dec_pos = strpos ( $num, '.' )) === false) ? 0 : strlen ( substr ( $num, $dec_pos + 1 ) );
// get the number of decimal places to the left of the decimal point (or the length of the entire num if there is no dec point), e.g. 1.6 => 1
$left_dec_places = ($dec_pos === false) ? strlen ( $num ) : strlen ( substr ( $num, 0, $dec_pos ) );
// work out number of zeros from exp, exp sign and dec places, e.g. exp 6, exp sign +, dec places 1 => num zeros 5
if ($exp_sign === '+')
$num_zeros = $exp - $right_dec_places;
else
$num_zeros = $exp - $left_dec_places;
// build a string with $num_zeros zeros, e.g. '0' 5 times => '00000'
$zeros = str_pad ( '', $num_zeros, '0' );
// strip decimal from num, e.g. 1.6 => 16
if ($dec_pos !== false)
$num = str_replace ( '.', '', $num );
// if positive exponent, return like 1600000
if ($exp_sign === '+')
return $num_sign . $num . $zeros;
// if negative exponent, return like 0.0000016
else
return $num_sign . '0.' . $zeros . $num;
} // otherwise, assume already in decimal notation and return
else
return $float_str;
}

Related

number_format without decimal argument

I would like to use the number_format() function without to specify the number of decimals. (If 2 decimals, display 2, if 5, display 5)
Is that possible?
Thanks a lot
You can calculate the number of decimals before you use numberformat and use that in the function.
$number = 50001/4;
If(strpos($number, ".") !== false){
// Is float
$decimals = strlen($number) - (strpos($number, ".")+1);
}Else{
// Is integer == no decimals
$decimals =0;
}
Echo number_format($number, $decimals, ',', ' ');
https://3v4l.org/DULp4
If this is really what you want, this may work even if this is totally useless
function numberOfDecimals($value)
{
if ((int)$value == $value)
{
return 0;
}
else if (! is_numeric($value))
{
// throw new Exception('numberOfDecimals: ' . $value . ' is not a number!');
return false;
}
return strlen($value) - strrpos($value, '.') - 1;
}
$number = 1.23456;
print number_format($number,numberOfDecimals($number));
credits : PHP: get number of decimal digits

Make number format?

Make format of number:
For example:
if number = 204433
output = 204K
if number = 84243
output = 84'243
if number = 8000
output = 8000
if number = 400
output = 400
How to formatted number to that's format?
The number_format command can do what you are looking for.
string number_format ( float $number , int $decimals = 0 , string $dec_point = "." , string $thousands_sep = "," )
You wrote:
if number = 84243
output = 84'243
Example:
$in = 84243;
$out = number_format ( $in, 0, ".", "'");
// $out = "84'243"
I think you can try this
if(strlen($number) > 5) {
echo substr($number,0,2).'K';
} elseif(strlen($number)) {
echo numberformat($number,2,'.',"'"); // for example
} else {
echo $number;
}

PHP - Check for positive / negative numeric strings

I'd like to know what is the best way to check whether a numeric string is positive or negative. I am using this answer on S.O but I am not able to determine whether a number with decimals is + or -
For example :
function check_numb($Degree){
if ( (int)$Degree == $Degree && (int)$Degree > 0 ) {
return 'Positive';
} else {
return 'Negative';
}
}
print check_numb("+2"); // returns Positive
print check_numb("+2.0"); // returns Positive
print check_numb("+2.1"); // returns Negative ??
print check_numb("+0.1"); // returns Negative ??
print check_numb("-0.1"); // returns Negative
It seems when a decimal is added it returns false. How do you properly check for positive strings > +0.XX and negative < -0.XX which 2 decimals..
Thanks!
Considering the given input, why not :
$number = '+2,33122';
$isPositive = $number[0] === '+' ? 'Positive' : 'Negative';
// Positive
$number = '-0,2';
$isPositive = $number[0] === '+' ? 'Positive' : 'Negative';
// Negative
Here is a more generic code, working even if the sign is removed from your input :
function checkPositive ($number) {
if (!is_numeric(substr($number, 0, 1))) {
$sign = substr($number, 0, 1);
return $sign == '+';
}
return $number > 0;
}
$number = '+2,33122';
var_dump(checkPositive($number));
// true
$number = '-2,33122';
var_dump(checkPositive($number));
// false
$number = '2,22';
var_dump(checkPositive($number));
// true
Your problem is because: (int)"+2.1" == 2 and 2 != "+2.1". For ALL numbers, if it is < 0 it is negative and if it is > 0 it is positive. If it is == 0, then it is obviously 0 which is unsigned.
function check_numb($Degree){
if ( $Degree > 0 ) {
return 'Positive';
} elseif( $Degree < 0 ) {
return 'Negative';
}
}

Break down number into thousands,hundreds,etc

I'm currently putting together a cheque printing solution for my company. When printing the cheque you need to print the number of millions,hundred thousands,ten thousands,thousands, hundreds,tens and units (pounds/dollars/euros etc ) from the amount being paid.
In the case of 111232.23 the following is correctly output from the code I have written below. I cant help feeling that there is a more efficient or reliable method of doing this? Does anyone know of a library/class math technique that does this?
float(111232.23)
Array
(
[100000] => 1
[10000] => 1
[1000] => 1
[100] => 2
[10] => 3
[1] => 2
)
<?php
$amounts = array(111232.23,4334.25,123.24,3.99);
function cheque_format($amount)
{
var_dump($amount);
#no need for millions
$levels = array(100000,10000,1000,100,10,1);
do{
$current_level = current($levels);
$modulo = $amount % $current_level;
$results[$current_level] = $div = number_format(floor($amount) / $current_level,0);
if($div)
{
$amount -= $current_level * $div;
}
}while($modulo && next($levels));
print_r($results);
}
foreach($amounts as $amount)
{
cheque_format($amount);
}
?>
I think you just re-wrote the number_format function that PHP has. My suggestion is to use the PHP function rather than to re-write it.
<?php
$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
?>
I'm not sure exactly what the PHP script would be for this, but if you have 10000, 1000, 100, 10, 1 as the things you need the amounts of. How many 10,000's in amount $dollar?
floor($dollar/10000)
how many thousands?
floor(($dollar%10000)/1000)
etc.
This is not the answer for the question, but the following also break down the decimals.
function cheque_format($amount, $decimals = true, $decimal_seperator = '.')
{
var_dump($amount);
$levels = array(100000, 10000, 1000, 100, 10, 5, 1);
$decimal_levels = array(50, 20, 10, 5, 1);
preg_match('/(?:\\' . $decimal_seperator . '(\d+))?(?:[eE]([+-]?\d+))?$/', (string)$amount, $match);
$d = isset($match[1]) ? $match[1] : 0;
foreach ( $levels as $level )
{
$level = (float)$level;
$results[(string)$level] = $div = (int)(floor($amount) / $level);
if ($div) $amount -= $level * $div;
}
if ( $decimals ) {
$amount = $d;
foreach ( $decimal_levels as $level )
{
$level = (float)$level;
$results[$level < 10 ? '0.0'.(string)$level : '0.'.(string)$level] = $div = (int)(floor($amount) / $level);
if ($div) $amount -= $level * $div;
}
}
print_r($results);
}

How to make number_format() not to round numbers up

I have this number:
$double = '21.188624';
After using number_format($double, 2, ',', ' ') I get:
21,19
But what I want is:
21,18
Any ideea how can I make this work?
Thank you.
number_format will always do that, your only solution is to feed it something different:
$number = intval(($number*100))/100;
Or:
$number = floor(($number*100))/100;
I know that this an old question, but it still actual :) .
How about this function?
function numberFormatPrecision($number, $precision = 2, $separator = '.')
{
$numberParts = explode($separator, $number);
$response = $numberParts[0];
if (count($numberParts)>1 && $precision > 0) {
$response .= $separator;
$response .= substr($numberParts[1], 0, $precision);
}
return $response;
}
Usage:
// numbers test
numberFormatPrecision(19, 2, '.'); // expected 19 return 19
numberFormatPrecision(19.1, 2, '.'); //expected 19.1 return 19.1
numberFormatPrecision(19.123456, 2, '.'); //expected 19.12 return 19.12
numberFormatPrecision(19.123456, 0, '.'); //expected 19 return 19
// negative numbers test
numberFormatPrecision(-19, 2, '.'); // expected -19 return -19
numberFormatPrecision(-19.1, 2, '.'); //expected -19.1 return -19.1
numberFormatPrecision(-19.123456, 2, '.'); //expected -19.12 return -19.12
numberFormatPrecision(-19.123456, 0, '.'); //expected -19 return -19
// precision test
numberFormatPrecision(-19.123456, 4, '.'); //expected -19.1234 return -19.1234
// separator test
numberFormatPrecision('-19,123456', 3, ','); //expected -19,123 return -19,123 -- comma separator
Function (only precision):
function numberPrecision($number, $decimals = 0)
{
$negation = ($number < 0) ? (-1) : 1;
$coefficient = 10 ** $decimals;
return $negation * floor((string)(abs($number) * $coefficient)) / $coefficient;
}
Examples:
numberPrecision(2557.9999, 2); // returns 2557.99
numberPrecision(2557.9999, 10); // returns 2557.9999
numberPrecision(2557.9999, 0); // returns 2557
numberPrecision(2557.9999, -2); // returns 2500
numberPrecision(2557.9999, -10); // returns 0
numberPrecision(-2557.9999, 2); // returns -2557.99
numberPrecision(-2557.9999, 10); // returns -2557.9999
numberPrecision(-2557.9999, 0); // returns -2557
numberPrecision(-2557.9999, -2); // returns -2500
numberPrecision(-2557.9999, -10); // returns 0
Function (full functionality):
function numberFormat($number, $decimals = 0, $decPoint = '.' , $thousandsSep = ',')
{
$negation = ($number < 0) ? (-1) : 1;
$coefficient = 10 ** $decimals;
$number = $negation * floor((string)(abs($number) * $coefficient)) / $coefficient;
return number_format($number, $decimals, $decPoint, $thousandsSep);
}
Examples:
numberFormat(2557.9999, 2, ',', ' '); // returns 2 557,99
numberFormat(2557.9999, 10, ',', ' '); // returns 2 557,9999000000
numberFormat(2557.9999, 0, ',', ' '); // returns 2 557
numberFormat(2557.9999, -2, ',', ' '); // returns 2 500
numberFormat(2557.9999, -10, ',', ' '); // returns 0
numberFormat(-2557.9999, 2, ',', ' '); // returns -2 557,99
numberFormat(-2557.9999, 10, ',', ' '); // returns -2 557,9999000000
numberFormat(-2557.9999, 0, ',', ' '); // returns -2 557
numberFormat(-2557.9999, -2, ',', ' '); // returns -2 500
numberFormat(-2557.9999, -10, ',', ' '); // returns 0
floor($double*100)/100
I use this function:
function cutNum($num, $precision = 2) {
return floor($num) . substr(str_replace(floor($num), '', $num), 0, $precision + 1);
}
Usage examples:
cutNum(5) //returns 5
cutNum(5.6789) //returns 5.67 (default precision is two decimals)
cutNum(5.6789, 3) //returns 5.678
cutNum(5.6789, 10) //returns 5.6789
cutNum(5.6789, 0) //returns 5. (!don't use with zero as second argument: use floor instead!)
Explanation: here you have the same function, just more verbose to help understanding its behaviour:
function cutNum($num, $precision = 2) {
$integerPart = floor($num);
$decimalPart = str_replace($integerPart, '', $num);
$trimmedDecimal = substr($decimalPart, 0, $precision + 1);
return $integerPart . $trimmedDecimal;
}
Use the PHP native function bcdiv.
function numberFormat($number, $decimals = 2, $sep = ".", $k = ","){
$number = bcdiv($number, 1, $decimals); // Truncate decimals without rounding
return number_format($number, $decimals, $sep, $k); // Format the number
}
See this answer for more details.
**Number without round**
$double = '21.188624';
echo intval($double).'.'.substr(end(explode('.',$double)),0,2);
**Output** 21.18
In case you don't care for what comes behind the decimal point, you can cast the float as an int to avoid rounding:
$float = 2.8;
echo (int) $float; // outputs '2'
$double = '21.188624';
$teX = explode('.', $double);
if(isset($teX[1])){
$de = substr($teX[1], 0, 2);
$final = $teX[0].'.'.$de;
$final = (float) $final;
}else{
$final = $double;
}
final will be 21.18
In case you need 2 fixed decimal places, you can try this!
#Dima's solution is working for me, but it prints "19.90" as "19.9" so I made some changes as follows:
<?php
function numberPrecision($number, $decimals = 0)
{
$negation = ($number < 0) ? (-1) : 1;
$coefficient = 10 ** $decimals;
$result = $negation * floor((string)(abs($number) * $coefficient)) / $coefficient;
$arr = explode(".", $result);
$num = $arr[0];
if(empty($arr[1]))
$num .= ".00";
else if(strlen($arr[1]) == 1)
$num .= "." . $arr[1] . "0";
else
$num .= ".". $arr[1];
return $num;
}
echo numberPrecision(19.90,2); // 19.90
So, what I did is, I just break the result into two parts with explode function. and convert the result into a string with concatenation!
public function numberFormatPrecision( $number, $separator = '.', $format = 2 ){
$response = '';
$brokenNumber = explode( $separator, $number );
$response = $brokenNumber[0] . $separator;
$brokenBackNumber = str_split($brokenNumber[1]);
if( $format < count($brokenBackNumber) ){
for( $i = 1; $i <= $format; $i++ )
$response .= $brokenBackNumber[$i];
}
return $response;
}
$finalCommishParts = explode('.',$commission);
$commisshSuffix = (isset($finalCommishParts[1])?substr($finalCommishParts[1],0,2):'00');
$finalCommish = $finalCommishParts[0].'.'.$commisshSuffix;
The faster way as exploding(building arrays) is to do it with string commands like this:
$number = ABC.EDFG;
$precision = substr($number, strpos($number, '.'), 3); // 3 because . plus 2 precision
$new_number = substr($number, 0, strpos($number, '.')).$precision;
The result ist ABC.ED in this case because of 2 precision
If you want more precision just change the 3 to 4 or X to have X-1 precision
Cheers
Javascript Version
function numberFormat($number, $decimals = 0, $decPoint = '.' , $thousandsSep = ',')
{
return number_format((Math.floor($number * 100) / 100).toFixed($decimals), $decimals, $decPoint, $thousandsSep );
}
// https://locutus.io/php/strings/number_format/
function number_format(number, decimals, decPoint, thousandsSep) {
if(decimals === 'undefined') decimals = 2;
number = (number + '').replace(/[^0-9+\-Ee.]/g, '')
const n = !isFinite(+number) ? 0 : +number
const prec = !isFinite(+decimals) ? 0 : Math.abs(decimals)
const sep = (typeof thousandsSep === 'undefined') ? ',' : thousandsSep
const dec = (typeof decPoint === 'undefined') ? '.' : decPoint
let s = ''
const toFixedFix = function (n, prec) {
if (('' + n).indexOf('e') === -1) {
return +(Math.round(n + 'e+' + prec) + 'e-' + prec)
} else {
const arr = ('' + n).split('e')
let sig = ''
if (+arr[1] + prec > 0) {
sig = '+'
}
return (+(Math.round(+arr[0] + 'e' + sig + (+arr[1] + prec)) + 'e-' + prec)).toFixed(prec)
}
}
// #todo: for IE parseFloat(0.55).toFixed(0) = 0;
s = (prec ? toFixedFix(n, prec).toString() : '' + Math.round(n)).split('.')
if (s[0].length > 3) {
s[0] = s[0].replace(/\B(?=(?:\d{3})+(?!\d))/g, sep)
}
if ((s[1] || '').length < prec) {
s[1] = s[1] || ''
s[1] += new Array(prec - s[1].length + 1).join('0')
}
return s.join(dec)
}
$number = 2.278;
echo new_number_format($number,1);
//result: 2.2
function new_number_format($number,$decimal)
{
//explode the number with the delimiter of dot(.) and get the whole number in index 0 and the decimal in index 1
$num = explode('.',$number);
//if the decimal is equal to zero
//take note that we can't split the zero value only and it will return Undefined offset if we split the zero only
//for example: rating_format(2.0,1); the result will be 2. the zero is gone because of the Undefined offset
//the solution of this problem is this condition below
if($num[1] == 0)
{
$final_decimal = '';
$i=0;
//loop the decimal so that we can display depend on how many decimal that you want to display
while($i<$decimal){
$final_decimal .= 0;
$i++;
}
}
//if the decimal is not zero
else
{
$dec = str_split($num[1]); //split the decimal and get the value using the array index
$i=0;
$final_decimal = '';
//loop the decimal so that we can display depend on how many decimal that you want to display
while($i<$decimal){
$final_decimal .= $dec[$i];
$i++;
}
}
$new_number= $num[0].'.'.$final_decimal;//combine the result with final decimal
return $new_number; //return the final output
}
thanks for your help Dima!!! My function
private function number_format(float $num, int $decimals = 0, ?string $decimal_separator = ',', ?string $thousands_separator = '.'){
/**
* Formatea un numero como number_format sin redondear hacia arriba, trunca el resultado
* #access private
* #param string num - Numero de va a ser formateado
* #param int decimals - Posiciones Decimales
* #param string|null $decimal_separator — [opcional]
* #param string|null $thousands_separator — [opcional]
* #return string — Version de numero formateado.
*/
$negation = ($num < 0) ? (-1) : 1;
$coefficient = 10 ** $decimals;
$number = $negation * floor((string)(abs($num) * $coefficient)) / $coefficient;
return number_format($number, $decimals, $decimal_separator, $thousands_separator);
}
for use it
echo $this->number_format(24996.46783, 3, ',', '.'); //24.996,467
use this function:
function number_format_unlimited_precision($number,$decimal = '.')
{
$broken_number = explode($decimal,$number);
return number_format($broken_number[0]).$decimal.$broken_number[1]);
}
In Case you have small float values you can use number_format function this way.
$number = 21.23;
echo number_format($number, 2, '.', ',') ); // 21.23
In case you have you have long decimal number then also it will format number this way
$number = 201541.23;
echo number_format($number, 2, '.', ',') ); // 201,541.23

Categories