I don't know how is called the thing I'm looking for, that's why I ask the question.
So, I have numbers like 5, 35, 1823, 355581. And when I use something like totalNumbers(35) then it should return 2, because it has 3 and 5. It should be applicable to all the numbers.
I know I can create a code like this:
function totalNumbers($int) {
if($int / 1000 > 0) return 3;
if($int / 100 > 0) return 2;
if($int / 10 > 0) return 1;
}
But I don't want to add if for every number in the world. How do you call this?
Use the strlen function
$number = 4353;
echo strlen($number);
Result: 4
You could use
function totalNumbers($int){
return strlen((string) $int);
}
Why not use a string for that purpose? In the example below we use the function that returns the number of characters in string.
function totalNumbers($int) {
return strlen($int);
}
Related
I have a number that needs to be rounded up to a specific decimal, is there any function in PHP to do that?
I need every number (which reflects an amount of money) to have a specific decimal number.
For example:
The decimal needs to be 25, so if I got $ 25.50 I need it to be $ 26.25, and if I got $ 25.10 it needs to be $ 25.25.
I've checked PHP round(), and specifically ceil(), and I've come across this answer in Python, but I'm not sure it applies to my case, because what I need is different.
Any ideas? Even pseudo code as a tip on where to start will help me. Thanks!
I think you need a custom function, something like this:
function my_round($number, $decimal = 0.25) {
$result = floor($number) + $decimal;
if ($result < $number) $result = ceil($number) + $decimal;
return $result;
}
print my_round(25.50);
I modified this answer for your case:
<?php
function roundUp($number){
$int = floor($number);
$float = $number-$int;
if ($float*10 < 2.5)
$result = $int;
else
$result = ceil($number);
$result+= 0.25;
echo $number." becomes ".$result."\n";
}
roundUp(25.50);
roundUp(25.10);
Look for demo here
Following axiac's advice mentioned in the comments and following this thread, the best way to deal with floating point numbers in the context of currencies, is to treat the dollars and cents' values as 2 separate entities.
One way I can think of it to split the numbers before and after the decimal into 2 separate variables and process accordingly.
<?php
function customRound($amount){
$amount = strval($amount);
if(preg_match('/(\d+)\.?(\d{1,2})?/', $amount, $matches) !== 1){
throw new \Exception("Invalid amount.");
}
$dollars = intval($matches[1]);
$cents = intval($matches[2] ?? 0);
if($cents < 10) $cents *= 10;
if($cents <= 25) return $dollars . ".25";
return ($dollars + 1) . ".25";
}
$tests = [25.51,25.49,26.25,25.10,25.49];
foreach ($tests as $test){
echo $test," => ",customRound($test),PHP_EOL;
}
Here's another approach:
<?php
function roundUp($number, $decimal=0.25){
$dollars = floor($number);
$cents = $number - $dollars;
if($cents > $decimal) {
++$dollars;
}
return $dollars + $decimal;
}
echo roundUp(25.50).PHP_EOL;
echo roundUp(25.10);
I have this array which links numbers to letters at the moment like this:
1-26 = A-Z
But there is more, 27=AA and 28=AB etc...
so basically when I do this:
var_dump($array[2]); //shows B
var_dump($array[29]); //shows AC
Now this array I made myself but it's becoming way too long. Is there a way to actually get this going on till lets say 32? I know there is chr but I dont think I can use this.
Is there an easier way to actually get this without using this way too long of an array?
It's slower calculating it this way, but you can take advantage of the fact that PHP lets you increment letters in the same way as numbers, Perl style:
function excelColumnRange($number) {
$character = 'A';
while ($number > 1) {
++$character;
--$number;
}
return $character;
}
var_dump(excelColumnRange(2));
var_dump(excelColumnRange(29));
here is the code which you are looking for :
<?php
$start = "A";
$max = 50;
$result = array();
for($i=1; $i<=$max; $i++) {
$result[$i] = $start++;
}
print_r($result);
?>
Ref: http://www.xpertdeveloper.com/2011/01/php-strings-unusual-behaviour/
This should work for you:
Even without any loops. First I calculate how many times the alphabet (26) goes into the number. With this I define how many times it has to str_repleat() A. Then I simply subtract this number and calculate the number in the alphabet with the number which is left.
<?php
function numberToLetter($number) {
$fullSets = (($num = floor(($number-1) / 26)) < 0 ? 0 : $num);
return str_repeat("A", $fullSets) . (($v = ($number-$fullSets*26)) > 0 ? chr($v+64) : "");
}
echo numberToLetter(53);
?>
output:
AAA
$result = reduce($number);
function reduce($number) {
$new_number = 0;
if($number < 10) {
return $number;
}
$q = floor($number / 10 );
$r = $number % 10;
$new_number = $q + $r;
if($new_number <= 9) {
return $new_number;
}
else {
reduce($new_number);
}
}
I want to sum the numbers by its digits
For example, if i pass 10, it should return 1+0 = 1
This works if i pass 10
But not working when i pass 100.
This should work for you:
Just split your number into an array with str_split() and then use array_sum() to add all digits together.
echo array_sum(str_split($number));
EDIT:
If you don't want the checksum, but go down to a single digit, you also don't have to write that much code. Just call the function over and over again until the array_sum() is equal or less than 9.
function reduceToOneSingleDigit($result) {
$result = str_split($result);
while(array_sum($result) > 9)
return reduceToOneSingleDigit(array_sum($result));
return array_sum($result);
}
echo reduceToOneSingleDigit(99);
Just too much code, take a look at next one
print sum(125); // 8
// 5 12
// 2 1
// 1 + ~>0
function findSum($num)
{
if($num == 0)
return 0;
return $num%10 + findSum(floor($num/10));
}
so, even 100000 or 000001 will be 1, works just as U want, but it will have troubles if the paramater will be 0001000
You are missing the word return near the end. It should look like this:
return reduce($new_number);
I need a function in PHP to move the decimal to the beginning of the number if one exists otherwise if there is no decimal add 0. to the beginning.
I have:
function toDecimal($input){
return (stripos($input, ".")!==false)? $input: "0." . $input;
}
which was provided in a previous question of mine (thanks #shiplu.mokadd.im) but I need to extend it to also move the decimal to the beginning like:
Input Output
0.1234 0.1234
1.2345 0.12345
1234 0.1234
0.001234 0.001234
so basically the outputted number can never be larger than 1.
Thanks!
A little recursive magic should do the trick:
function divideNumber($number, $divide_by, $max)
{
if($number > $max)
{
return divideNumber($number/$divide_by, $divide_by, $max);
}
else
{
return $number;
}
}
// Outputs 0.950
print(divideNumber(950, 10, 1));
EDIT:
Here's a loop version (recursion was the first thing that came to mind):
function divideNumber($number, $divide_by, $max)
{
while($number > $max)
{
$number = $number / $divide_by;
}
return $number;
}
There's a better way. Use some math properties - something like this (this will also bring numbers less than 0.1 up front; you didn't specify what we should do with say 0.001234 - if you want to leave numbers less than 0.1 alone, just add a branch)
function foo($num) {
if ($num == 0) return $num; // can't take log of 0
return $num / pow(10, ceil(log($num, 10)));
}
echo foo(10.23);
Is there any slick way to round down to the nearest significant figure in php?
So:
0->0
9->9
10->10
17->10
77->70
114->100
745->700
1200->1000
?
$numbers = array(1, 9, 14, 53, 112, 725, 1001, 1200);
foreach($numbers as $number) {
printf('%d => %d'
, $number
, $number - $number % pow(10, floor(log10($number)))
);
echo "\n";
}
Unfortunately this fails horribly when $number is 0, but it does produce the expected result for positive integers. And it is a math-only solution.
Here's a pure math solution. This is also a more flexible solution if you ever wanted to round up or down, and not just down. And it works on 0 :)
if($num === 0) return 0;
$digits = (int)(log10($num));
$num = (pow(10, $digits)) * floor($num/(pow(10, $digits)));
You could replace floor with round or ceil. Actually, if you wanted to round to the nearest, you could simplify the third line even more.
$num = round($num, -$digits);
If you do want to have a mathy solution, try this:
function floorToFirst($int) {
if (0 === $int) return 0;
$nearest = pow(10, floor(log($int, 10)));
return floor($int / $nearest) * $nearest;
}
Something like this:
$str = (string)$value;
echo (int)($str[0] . str_repeat('0', strlen($str) - 1));
It's totally non-mathy, but I would just do this utilizing sting length... there's probably a smoother way to handle it but you could acomplish it with
function significant($number){
$digits = count($number);
if($digits >= 2){
$newNumber = substr($number,0,1);
$digits--;
for($i = 0; $i < $digits; $i++){
$newNumber = $newNumber . "0";
}
}
return $newNumber;
}
A math based alternative:
$mod = pow(10, intval(round(log10($value) - 0.5)));
$answer = ((int)($value / $mod)) * $mod;
I know this is an old thread but I read it when looking for inspiration on how to solve this problem. Here's what I came up with:
class Math
{
public static function round($number, $numberOfSigFigs = 1)
{
// If the number is 0 return 0
if ($number == 0) {
return 0;
}
// Deal with negative numbers
if ($number < 0) {
$number = -$number;
return -Math::sigFigRound($number, $numberOfSigFigs);
}
return Math::sigFigRound($number, $numberOfSigFigs);
}
private static function sigFigRound($number, $numberOfSigFigs)
{
// Log the number passed
$log = log10($number);
// Round $log down to determine the integer part of the log
$logIntegerPart = floor($log);
// Subtract the integer part from the log itself to determine the fractional part of the log
$logFractionalPart = $log - $logIntegerPart;
// Calculate the value of 10 raised to the power of $logFractionalPart
$value = pow(10, $logFractionalPart);
// Round $value to specified number of significant figures
$value = round($value, $numberOfSigFigs - 1);
// Return the correct value
return $value * pow(10, $logIntegerPart);
}
}
While the functions here worked, I needed significant digits for very small numbers (comparing low-value cryptocurrency to bitcoin).
The answer at Format number to N significant digits in PHP worked, somewhat, though very small numbers are displayed by PHP in scientific notation, which makes them hard for some people to read.
I tried using number_format, though that needs a specific number of digits after the decimal, which broke the 'significant' part of the number (if a set number is entered) and sometimes returned 0 (for numbers smaller than the set number).
The solution was to modify the function to identify really small numbers and then use number_format on them - taking the number of scientific notation digits as the number of digits for number_format:
function roundRate($rate, $digits)
{
$mod = pow(10, intval(round(log10($rate))));
$mod = $mod / pow(10, $digits);
$answer = ((int)($rate / $mod)) * $mod;
$small = strstr($answer,"-");
if($small)
{
$answer = number_format($answer,str_replace("-","",$small));
}
return $answer;
}
This function retains the significant digits as well as presents the numbers in easy-to-read format for everyone. (I know, it is not the best for scientific people nor even the most consistently length 'pretty' looking numbers, but it is overall the best solution for what we needed.)