No Truncate function in PHP - Options? - php

I have an algorithm that performs the following calculations:
( ( 0.50 * 0 ) + 7 ) / 10 = 0.70
( ( 0.70 * 10 ) + 9 ) / 20 = 0.80
( ( 0.80 * 20 ) + 7 ) / 30 = 0.7666666667 -> I want this value to truncate to 0.76
So that it may feed into the rest of the calculation as:
4a. ( ( 0.76 * 30 ) + 8 ) / 40 = 0.77
And not to feed in when rounded up two decimal places as 0.77:
4b. ( ( 0.77 * 30 ) + 8 ) / 40 = 0.77
****The following seem to have failed and instead force a round up to 0.77:****
The PHP sptrinf() function: PHP dropping decimals without rounding up
The PHP number_format() function: PHP: show a number to 2 decimal places
The PHP floor() function: Truncate float numbers with PHP
Is there another way?
Is it at all possible to achieve what I want (truncate to two decimal places) with PHP?
Please assist. Many thanks.
UPDATE - SOLVED
Ok, it is working now thanks to dkamins and zneak. I used the floor() approach (I assume I wasn't doing something right in the past). However, now the following happens:
e.g.
(0.86 * 30) + 9 ) / 40 = 0.87 (it should), yet after TRUNC it = 0.86
How is it truncating 0.87 to 0.86? It makes no sense. Is there a way to get it to truncate only if there are more than 2 decimal places?
SOLVED:
$numDecPlace = strlen(substr(strrchr($newRel, "."), 1));
echo '<p>Test: Number of decimal places=' .$numDecPlace. '</p>';
if($numDecPlace > 2) {
$newRel = floor($newRel * 100) / 100; // Truncate to 2dp.
echo '<p>Test: New relationship truncated is $newRel=' .$newRel. '</p>';
}

All the answers given here round the number.
This function worked for me and i hope for you too.
function truncate($number, $decimals)
{
$point_index = strrpos($number, '.');
return substr($number, 0, $point_index + $decimals+ 1);
}
Where $number is the number to truncate and$decimals is the number of decimals you want.
Example: truncate(-38.59540719940386 , 6); returns -38.595407
If you want, check substr's documentation!

You can use PHP's floor function along with some decimal shifting like so:
floor(0.7666666667 * 100) / 100;

how about round()
<?php
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
?>

To do this accurately for both +ve and -ve numbers you need use:
- the php floor() function for +ve numbers
- the php ceil() function for -ve numbers
function truncate_float($number, $decimals) {
$power = pow(10, $decimals);
if($number > 0){
return floor($number * $power) / $power;
} else {
return ceil($number * $power) / $power;
}
}
the reason for this is that floor() always rounds the number down, not towards zero.
ie floor() effectively rounds -ve numbers towards a larger absolute value
eg floor(1.5) = 1 while floor(-1.5) = 2
Therefore for the truncate method using multiply by power, round, then divide by power:
- floor() only works for positive numbers
- ceil() only works for negative numbers
To test this, copy the following code into the editor of http://phpfiddle.org/lite (or similar):
<div>Php Truncate Function</div>
<br>
<?php
function truncate_float($number, $places) {
$power = pow(10, $places);
if($number > 0){
return floor($number * $power) / $power;
} else {
return ceil($number * $power) / $power;
}
}
// demo
$lat = 52.4884;
$lng = -1.88651;
$lat_tr = truncate_float($lat, 3);
$lng_tr = truncate_float($lng, 3);
echo 'lat = ' . $lat . '<br>';
echo 'lat truncated = ' . $lat_tr . '<br>';
echo 'lat = ' . $lng . '<br>';
echo 'lat truncated = ' . $lng_tr . '<br><br>';
// demo of floor() on negatives
echo 'floor (1.5) = ' . floor(1.5) . '<br>';
echo 'floor (-1.5) = ' . floor(-1.5) . '<br>';
?>

I used would use the round() function as mentioned by Kartikey. You can find more information here at PHP.Net
float round ( float $val [, int $precision = 0 [, int $mode = PHP_ROUND_HALF_UP ]] )
Fissh

Related

How i can round this number 5.53 always like this: 5.55 in PHP? [duplicate]

I would like to solve rounding mechanism by using php4,5.2 and below (not 5.3)
Currently I am doing 0.05 rounding, something like this page:
http://www.bnm.gov.my/index.php?ch=209&pg=657&ac=568
before rounding | after rounding
89.90 | 89.90
89.91 | 89.90
89.92 | 89.90
89.93 | 89.95
89.94 | 89.95
89.95 | 89.95
89.96 | 89.95
89.97 | 89.95
89.98 | 90.00
89.99 | 90.00
I try to use string to split it out and manually do adding, but not really a good solution, hoping here can find someone to solve it.
use this function
function rndfunc($x){
return round($x * 2, 1) / 2;
}
Conceptually, the procedure can be done as:
Divide by 0.05
or multiply by (1 / 0.05)
Round to nearest integer
Multiply by 0.05
You basically want to map values to a grid. The grid is defined as a multiple of .05. In general, you need to find the multiplicands your value lies between.
What isn't in the table are the negative numbers. You need to decide on whether to round away from zero (symmetrical) or always in the same direction (i.e. positive).
code:
$step = .05;
$multiplicand = floor( $value / $step );
$rest = $value % $step ;
if( $rest > $step/2 ) $multiplicand++; // round up if needed
$roundedvalue = $step*$multiplicand;
Multiply by two, then round, then divide by two.
Hint:-
$input1 = 24.05;
$things = abs($input * 20 ); // 481 ".05"s
$tenpcnt = abs($things / 10); // 48 ".05"s
$ouput = $tenpcnt / 20;
echo $ouput; // 2.40
function round5Sen ($value) {
return number_format(round($value*20,0)/20,2,'.','');
}
echo round5Sen(155.13);
echo "\n";
echo round5Sen(155.12);
echo "\n";
echo round5Sen(155.0);
echo "\n";
echo round5Sen(155.18);
echo "\n";
I'm sure there are more elegant solutions, but this appears to suit the task:
<?php
// setup test
$start_num = 89.90;
$iterations = 10;
// loop through test numbers
for ($i = 0; $i < $iterations; $i++) {
nickleRound($start_num + (0.01 * $i));
echo "\n\n";
}
//
function nickleRound($num) {
$p = 0.05;
echo "\n" . 'p= ' . $p;
$num = round($num, 2);
echo "\n" . 'num= ' . $num;
$r = ($num / $p);
echo "\n" . 'r= ' . $r;
$r2 = ceil($r) - $r;
echo "\n" . 'r2= ' . $r2;
$a = round($num, 1);
if (($r2 > 0) && ($r2 < 0.5)) {
$a = $a + 0.05;
}
echo "\n" . 'a= ' . $a;
}
Expanding a little on #xtofl to allow for more precise steps (not technically required for this question)
$step = 0.0005;
$multiplicand = floor($value / $step);
$rest = fmod($value, $step);
$value = $step * $multiplicand;
if ($rest > $step / 2) {
$value += $step;
}
//Round to nearest 0.05
echo round ($number * 20, 0) / 20;
//Round Up to nearest 0.05
echo ceil ($number * 20) / 20;
//Round Down to nearest 0.05
echo floor ($number * 20) / 20;
Thank you #mauris for the solution to solve my problem on Malaysia GST rounding mechanism. It also works in SQL.
DECLARE #tempTable AS TABLE(Number Decimal(20,4));
INSERT INTO #tempTable VALUES (89.90),(89.91),(89.92),(89.93),(89.94),(89.95),(89.96),(89.97),(89.98),(89.99)
SELECT Number, round(Number * 2, 1) / 2 AS 'Rounded' FROM #tempTable
PHP has the function round() for the PHP 4, PHP 5, PHP 7, PHP 8
https://www.php.net/manual/en/function.round.php

Round to 0.5 up and down and if 0 after dot docimal

Hey I have following Problems,
I get ratings and have the average of then but bow I want following:
1,2222222222222 = 1
1,2666666666666 = 1,5
2,3635345435435 = 2.5
2,567435 345345 = 2.5
3.5709 = 3
29,3003453450 = 29
I want all numbers to their most neir .5 but when they have a no decimal then should NOT be displayed 3.0 or 4.0, Just the number without decimals.
at the moment i have this code:
function roundRating($rating) {
return floor($rating * 2) / 2;
}
can someone help me?
greets
Here is a suggestion. See comments for step by step explanation.
<?php
$float = 1.753242342;
// Modulo operator (%) does not return float remainder. Use fmod().
$remainder = fmod($float, 1);
/* Apply rounding logic here.
* It isn't entirely clear to me what your intended behavior is.
* Should 0.75 round up to 1 or down to 0.5?
* I will leave this to you to figure out.
*/
$roundedRemainder = ($remainder >= 0.25)?0.5:0;
$int = $float - $remainder;
$result = $int + $roundedRemainder;
// If remainder is zero, cast to int to remove remainder.
if (fmod($result, 1) == 0)
$result = (int)$result;
echo "Int: " . $int . "<br>";
echo "Remainder: " . $remainder . "<br>";
echo "Rounded remainder: " . $roundedRemainder . "<br>";
echo "Result: " . $result . "<br>";
Outputs:
Int: 1
Remainder: 0.753242342
Rounded remainder: 0.5
Result: 1.5

Round up decimal number for specific decimal places in PHP

I want to round up my variable if it's decimal larger than .3 and if it's lower or equal it will round down, for example if i have 1.34 it will round up to 2, if i have 1.29 it will round down to 1, and if i have 1.3 it will round down to 1. I don't know how to do this precisely, right now i'm using the round basic function like this:
$weight = $weight/1000;
if($weight < 1) $weight = 1;
else $weight = round($weight, 0, PHP_ROUND_HALF_DOWN);
If you manipulate the numbers a bit, you can figure out if the decimals are .3 or higher. You achieve this by flooring the value, and subtract that from the original value. Check if the result of that, multiplied by 10, is greater than 3. If it is, you've got something above x.3.
$number = 1.31;
$int = floor($number);
$float = $number-$int;
if ($float*10 > 3.1)
$result = ceil($number);
else
$result = $int;
echo $result; // 2
Live demo
I made you a little hack, here's the code
$weight = 5088;
$weight = $weight/1000;
if($weight < 1) {
$weight = 1;
} else {
// I get the last number (I treat the $weight as a string here)
$last_number = substr($weight, -1, 1);
// Then I get the precision (floating numbers)
$precision = strlen(substr(strrchr($weight, "."), 1));
// Then I convert it to a string so I can use some helpful string functions
$weight_str = (string) $weight;
// If the last number is less then 3
if ($last_number > 3)
// I change it to 9 I could just change it to 5 and it would work
// because round will round up if then number is 5 or greater
$weight_str[strlen($weight_str) -1] = 9;
}
}
// Then the round will round up if it's 9 or round down if it's 3 or less
$weight = round($weight_str, $precision);
echo $weight;
Maybe something like this function?
function roundImproved($value, $decimalBreakPart = 0.3) {
$whole = floor($value);
$decimal = $value - $whole;
$decimalPartLen = strlen($decimal) - 2;
return (number_format($decimal, $decimalPartLen) <= number_format($decimalBreakPart, $decimalPartLen) ? $whole : ceil($value));
}
Proof:
http://sandbox.onlinephpfunctions.com/code/d75858f175dd819de069a8a05611ac9e7053f07a
You can specify "break part" if you want.

PHP - Get length of digits in a number

I would like to ask how I can get the length of digits in an Integer. For example:
$num = 245354;
$numlength = mb_strlen($num);
$numlength should be 6 in this example. Somehow I can't manage it to work?
Thanks
EDIT: The example code above --^ and its respective method mb_strlen(); works just fine.
Maybe:
$num = 245354;
$numlength = strlen((string)$num);
Accepted answer won't work with the big numbers. The better way to calculate the length of any number is to invoke floor(log10($num) + 1) with a check for 0.
$num = 12357;
echo $num !== 0 ? floor(log10($num) + 1) : 1; // prints 5
It has multiple advantages. It's faster, you don't do the casting of types, it works on big numbers, it works with different number systems like bin, hex, oct.
The equation does the logarithm with base 10 then makes the floor of it and adds 1.
This solution can work independently on the base, so if you want to calculate the length of binary or hex just change the base of the logarithm.
Working fiddle
The accepted solution presents a problem when evaluating negative numbers.
It works with a positive number:
$num = 245354;
$numlength = strlen((string)$num);
// Result: 6
But with a negative number, the (-) is added to the count:
$num = -245354;
$numlength = strlen((string)$num);
// Result: 7
Quick workaround:
$num = -245354;
$numlength = strlen((string)abs($num));
// Result: 6
More elegant way :)
ceil(log10($num));
You could also use some basic math!
$digits = (int)(log($num,10)+1)
<?php
$num = 123;
$num2 = 1234;
$num3 = 12345;
function digits($num){
return (int) (log($num, 10) + 1);
}
echo "\n $num: " . digits($num); // 123: 3
echo "\n $num2:" . digits($num2); // 1234: 4
echo "\n $num3:" . digits($num3); // 12345: 5
echo "\n";
Another way to find out the length of a number in digits would be to divide the integer part of the number to 10 until it becomes 0.
Example:
2021/10 = 202.1
202/10 = 20.2
20/10 = 2
2/10 = 0.2
Code:
function numberGetLength($number) {
$count = 0;
while (intval($number) > 0) {
$number = intval($number) / 10;
$count += 1;
}
return $count
}
Just using some version of (int)(log($num,10)+1) fails for 10, 100, 1000, etc. It counts the number 10 as 1 digit, 100 as two digits, etc. It also fails with 0 or any negative number.
If you must use math (and the number is non-negative), use:
$numlength = (int)(log($num+1, 10)+1);
Or for a math solution that counts the digits in positive OR negative numbers:
$numlength = ($num>=0) ? (int)(log($num+1, 10)+1) : (int)(log(1-$num, 10)+1);
But the strlen solution is just about as fast in PHP.
In PHP types are loosely set and guessed, if you want to see something as a string if it is an integer, float, and (i have not tried this) bool then #Gorjunav is the most correct answer.
Reset the variable as a string
$stringNum = (string) $num;
Then you can go anything string related you want with it! And vice-versa for changing a string to an int
$number = (int) $stringNum;
and so on...
count only integer value
`<?php
$n1 =12345;
$n2 =123454.55;
$n3 =12345564.557;
echo "The Number you Type: ".$n1."<br>";
$count = 0;
while ($n1 != 0)
{
$n1 = $n1 / 10;
$n1 = intval($n1);
++$count;
}
echo "The Digit in a Number: ".$count;
}
?>`
echo strlen((string) abs($num)); // using **abs** it'll work with negative integers as well
Tested in PHP 4.4.9 - 8.0.0
$array = array(-1, 0, -0, 1, 4, 9, 10, -10, 20, -20, 100, -100);
foreach( $array as $key => $num ){
echo $key."\t{$num}\t=>\t".($num !== 0 ? floor(log10(abs($num)) + 1) : 1)."\n";
}
/* Output:
0 -1 => 1
1 0 => 1
2 0 => 1
3 1 => 1
4 4 => 1
5 9 => 1
6 10 => 2
7 -10 => 2
8 20 => 2
9 -20 => 2
10 100 => 3
11 -100 => 3
*/
The following function work for either integers or floats (works with PHP7+):
function digitsCount($number): int
{
$number = abs($number);
$numberParts = explode(".", $number);
return
strlen($numberParts[0]) +
(strlen($numberParts[1] ?? 0));
}

Rounding Mechanism to nearest 0.05

I would like to solve rounding mechanism by using php4,5.2 and below (not 5.3)
Currently I am doing 0.05 rounding, something like this page:
http://www.bnm.gov.my/index.php?ch=209&pg=657&ac=568
before rounding | after rounding
89.90 | 89.90
89.91 | 89.90
89.92 | 89.90
89.93 | 89.95
89.94 | 89.95
89.95 | 89.95
89.96 | 89.95
89.97 | 89.95
89.98 | 90.00
89.99 | 90.00
I try to use string to split it out and manually do adding, but not really a good solution, hoping here can find someone to solve it.
use this function
function rndfunc($x){
return round($x * 2, 1) / 2;
}
Conceptually, the procedure can be done as:
Divide by 0.05
or multiply by (1 / 0.05)
Round to nearest integer
Multiply by 0.05
You basically want to map values to a grid. The grid is defined as a multiple of .05. In general, you need to find the multiplicands your value lies between.
What isn't in the table are the negative numbers. You need to decide on whether to round away from zero (symmetrical) or always in the same direction (i.e. positive).
code:
$step = .05;
$multiplicand = floor( $value / $step );
$rest = $value % $step ;
if( $rest > $step/2 ) $multiplicand++; // round up if needed
$roundedvalue = $step*$multiplicand;
Multiply by two, then round, then divide by two.
Hint:-
$input1 = 24.05;
$things = abs($input * 20 ); // 481 ".05"s
$tenpcnt = abs($things / 10); // 48 ".05"s
$ouput = $tenpcnt / 20;
echo $ouput; // 2.40
function round5Sen ($value) {
return number_format(round($value*20,0)/20,2,'.','');
}
echo round5Sen(155.13);
echo "\n";
echo round5Sen(155.12);
echo "\n";
echo round5Sen(155.0);
echo "\n";
echo round5Sen(155.18);
echo "\n";
I'm sure there are more elegant solutions, but this appears to suit the task:
<?php
// setup test
$start_num = 89.90;
$iterations = 10;
// loop through test numbers
for ($i = 0; $i < $iterations; $i++) {
nickleRound($start_num + (0.01 * $i));
echo "\n\n";
}
//
function nickleRound($num) {
$p = 0.05;
echo "\n" . 'p= ' . $p;
$num = round($num, 2);
echo "\n" . 'num= ' . $num;
$r = ($num / $p);
echo "\n" . 'r= ' . $r;
$r2 = ceil($r) - $r;
echo "\n" . 'r2= ' . $r2;
$a = round($num, 1);
if (($r2 > 0) && ($r2 < 0.5)) {
$a = $a + 0.05;
}
echo "\n" . 'a= ' . $a;
}
Expanding a little on #xtofl to allow for more precise steps (not technically required for this question)
$step = 0.0005;
$multiplicand = floor($value / $step);
$rest = fmod($value, $step);
$value = $step * $multiplicand;
if ($rest > $step / 2) {
$value += $step;
}
//Round to nearest 0.05
echo round ($number * 20, 0) / 20;
//Round Up to nearest 0.05
echo ceil ($number * 20) / 20;
//Round Down to nearest 0.05
echo floor ($number * 20) / 20;
Thank you #mauris for the solution to solve my problem on Malaysia GST rounding mechanism. It also works in SQL.
DECLARE #tempTable AS TABLE(Number Decimal(20,4));
INSERT INTO #tempTable VALUES (89.90),(89.91),(89.92),(89.93),(89.94),(89.95),(89.96),(89.97),(89.98),(89.99)
SELECT Number, round(Number * 2, 1) / 2 AS 'Rounded' FROM #tempTable
PHP has the function round() for the PHP 4, PHP 5, PHP 7, PHP 8
https://www.php.net/manual/en/function.round.php

Categories