$sum = 000000000117800;
$sum = number_format($sum, 2, ".", ".");
I am looking for the output 1 178.
The sum is always a length of 15. Like assigned above. The sum could also be:
000000001117800;
Then it would be
11 178
and so on.
The last two defines the decimals: So for example
000000000117805;
would be
1 178,05
My code above gives me: 79.00 though...
I am wondering if I could solve this perhaps with ltrim, but perhaps there is another more better way ?
Your code is correct, you simply have to use a string
$sum = "000000000117800";
echo number_format($sum, 2, ".", ".");
prints ( http://ideone.com/534ATu )
117.800.00
Although, you have to divide by 100 to get the fractional part right
$sum = "000000000117800";
echo number_format($sum / 100, 2, ".", ".");
which prints ( http://ideone.com/A5LFpS )
1.178.00
the problem is when you assign
$sum = 000000000117800;
it is already being converted to 79 (as an octal value of $sum) and you cannot do anything about it.
so why do strings work? Because number_format expetcs float as a first argument, so PHP performs conversion from string to float, which ignores leading 0's. As a result we have 117800 which we have to further divide by 100 to get decimals right, then we can use number_format for nice display, or simply do (http://ideone.com/IeBCmF)
$sum = "000000000117800";
echo $sum / 100;
and get
1178
and for
$sum = "000000000117805";
echo $sum / 100;
we get
1178.05
as requested
One final remark about number_format - to get desired formatting you should use
number_format( $value, 2, ',', ' ')
so (http://ideone.com/yDQXde)
$sum = "000000000117805";
echo number_format( $sum / 100, 2, ',', ' ');
prints
1 178,05
It looks like you need to remove the leading 0's before hand. I went to http://writecodeonline.com/php/ and ran the code
$sum = 000000000117800;
$sum = number_format($sum, 2, ",", ".");<br>
echo $sum;
Then ran the code
$sum = 117800;
$sum = number_format($sum, 2, ",", ".");
echo $sum;
and it worked, it;s like the leading 0's are causing the numbers to be interpreted as another format (OCTAL as a commenter said) and not decimal.EDIT:
As a solution try ltrim before running the number_format to remove leading0'shttp://php.net/manual/en/function.ltrim.php string ltrim ( string $str [, string $charlist ] )
Strip whitespace (or other characters) from the beginning of a string.
That is because you number is treated like octal because of leading zero.
0117 in octal system is exactly 79 in decimal system.
Your initial value 000000000117800 is reduced to 0117 because 8 is not octal digit, so PHP cuts the last digits of your number.
Your output is 79 for two reasons:
Numbers starting with a leading zero are octal, octal 0117 is 7*1 + 1*8 + 1*64 == 79
PHP is broken, and will blindly ignore invalid characters at the end
Why does your number contain those leading zeros? A number has no concept of "length" - that's a property of it's string representation.
Related
Is there a way with number_format() to leave out decimal places if the number is not a float/decimal?
For example, I would like the following input/output combos:
50.8 => 50.8
50.23 => 50.23
50.0 => 50
50.00 => 50
50 => 50
Is there a way to do this with just a standard number_format()?
You can add 0 to the formatted string. It will remove trailing zeros.
echo number_format(3.0, 1, ".", "") + 0; // 3
A Better Solution: The above solution fails to work for specific locales. So in that case, you can just type cast the number to float data type. Note: You might loose precision after type casting to float, bigger the number, more the chances of truncating the number.
echo (float) 3.0; // 3
Ultimate Solution: The only safe way is to use regex:
echo preg_replace("/\.?0+$/", "", 3.0); // 3
echo preg_replace("/\d+\.?\d*(\.?0+)/", "", 3.0); // 3
Snippet 1 DEMO
Snippet 2 DEMO
Snippet 3 DEMO
If you want to use whitespace here is better solution
function real_num ($num, $float)
{
if (!is_numeric($num) OR is_nan($num) ) return 0;
$r = number_format($num, $float, '.', ' ');
if (false !== strpos($r, '.'))
$r = rtrim(rtrim($r, '0'), '.');
return $r;
}
Use:
$a = 50.00;
$a = round($a, 2);
Even though the number has 2 zeros trailing it, if you round it, it won't show the decimal places, unless they have some kind of value.
So 50.00 rounded using 2 places will be 50, BUT 50.23 will be 50.23.
Unless you specify at which point to round up or down, it won't change your decimal values. So just use default round()
I want to display a large number with a leading zero and a dot after.
The balance i want to display starts with 0.000000000000000000 ( 18 zeros after the dot ). This should be able to go up to 99.00000000000000000.( 17 zeros after the dot ).
I did a lot of trial and error but i just can't seem to get the dot in there. As far as for the zeros i got it working. What i have now is:
$leadingBalance = sprintf("%019d", $balance);
echo $leadingBalance;
This will display the correct balance but i need to place the dot in there. It means that if my balance has 17 or 18 numbers it should place the dot as 0.0000... If the balance has 19 numbers it should place the dot as 00.0000...
Whatever i try, how much i look up i can't figure it out.
For eg:
$n1 = 0;
$n2 = 99;
echo number_format($n1,18)."<br>";
echo number_format($n2,18)."<br>";
See the documentation for number_format: http://php.net/number_format
The functions parameters are:
string number_format ( float $number , int $decimals = 0 , string $dec_point = '.' , string $thousands_sep = ',' )
So use:
number_format(1000000000000000, 2, '.', '');
Which means that you don't use any (= empty string) thousands separator, only a decimal point.
or if you just want padding of 19 zero after decimal point
just use
sprintf("%0.19f",$number);
or else
if u want a number always 20 digit without caring about whole no and decimal value than use str_pad()
eg:
$no = sprintf("%0.2f",100); //100.00
this will convert your no to decimal point with 2 digit after decimal now just pad some digit if require to make it 20 digit long
echo str_pad($no,20,"0"); //100.00(15 zero after this)
this will check no of digit available and pad 0 to make it 20 digit
for more ref:https://www.w3schools.com/php/func_string_number_format.asp
You are using %019d when you actually wants a float number, try this:
<?php
$format = '%0.19f';
$args = 9;
$result = sprintf ($format, $args);
//$result will be equal to 9.0000000000000000000
?>
<?php
$format = '%0.19f';
$args = 99;
$result = sprintf ($format, $args);
//$result will be equal to 99.0000000000000000000
?>
Edit:
Since it looks like you want your whole number to be equal to 20 digits only, you may try to do some math if number_format doesn't do your job. You can try something like:
<?php
$number = 999;
$number_length = strlen($number);
$format_len = 20 - $number_length;
$format = '%0.'. $format_len .'f';
$result = sprintf($format, $number);
?>
I have variables of bitcoin values all rounded to 8 decimal places. eg
1.00645600
I need a way in jQuery or php to get the whole number [1], The decimal values [006456], and trailing zeros [00]. I have already tried php substr but it messed up with the results since im dealing with variables.
Simple and general solution in PHP without involving regular expressions (that is an option also):
$number = '1.00645600';
$flooredNumber = floor($number); // 1
$decimalPart = (string) (floatval($number) - $flooredNumber); // 0.006456
$decimals = str_replace('0.', '', $decimalPart); // 006456
$trailingZeros = str_replace(rtrim($number, '0'), '', $number); // 00
substr
Returns the portion of string specified by the start and length parameters.
http://php.net/manual/en/function.substr.php
If the numbers in your string are always in the same position you can use substr() to get the desired values:
$str = '1.00645600';
echo substr($str, 0, 1)."\r\n";
echo substr($str, 2, 2)."\r\n";
echo substr($str, 2, 6)."\r\n";
Output:
1
00
006456
Perhaps, this way?
<?php
$i = '1.00645600';
echo rtrim(rtrim($i, '0'), '.');
?>
Is there a term for the idea of storing large numbers as letters? For example let's say I have the (relatively small) number 138201162401719 and I want to shrink the number of characters (I know this does not help with saving disk space) to the fewest possible number of characters. There are 26 letters in the English alphabet (but i count them as 25 since we need a zero letter). If I start splitting up my large number into pieces that are each 25 or less I get:
13, 8, 20, 11, 6, 24, 0, 17, 19
If I then count the numbers of the alphabet a=0, b=1, c=2, d=3... I can convert this to:
NIULGYART
So I went from 15 digits long (138201162401719) to 9 characters long (NIULGYART). This could of course be easily converted back to the original number as well.
So...my first question is "Does this have a name" and my second "Does anyone have PHP code that will do the conversion (in both directions)?"
I am looking for proper terminology so that I can do my own research in Google...though working code examples are cool too.
This only possible if you're considering to store your number before processing as a string. Because you can't store huge number as integers. You will lost the precision (13820116240171986468445 will be stored as 1.3820116240172E+22) so the alot of digits are lost.
If you're considering storing the number as a string this will be your answer:
Functions used: intval, chr and preg_match_all.
<?php
$regex = '/(2[0-5])|(1[0-9])|([0-9])/';
$numberString = '138201162401719';
preg_match_all($regex, $numberString, $numberArray, PREG_SET_ORDER);
echo($numberString . " -> ");
foreach($numberArray as $value){
$character = chr (intval($value[0]) + 65);
echo($character);
}
?>
Demo
This is the result:
138201162401719 -> NIULGYART
Here's how I would do it:
Store the big number as a string and split it into an array of numbers containing one digit each
Loop through the array extract 2-digit chunks using substr()
Check if the number is less than 26 (in which case, it is an alphabet) and add them to an array
Use array_map() with chr() to create a new array of characters from the above array
Implode the resulting array to get the cipher
In code:
$str = '138201162401719';
$arr = str_split($str);
$i = 0; // starting from the left
while ($i < count($arr)) {
$n = substr($str, $i, 2);
$firstchar = substr($n, 0, 1);
if ($n < 26 && $firstchar != 0) {
$result[] = substr($str, $i, 2);
$i += 2; // advance two characters
} else {
$result[] = substr($str, $i, 1);
$i++; // advance one character
}
}
$output = array_map(function($n) {
return chr($n+65);
}, $result);
echo implode($output); // => NIULGYART
Demo.
As an alternative, you could convert the input integer to express it in base 26, instead of base 10. Something like (pseudocode):
func convertBase26(num)
if (num < 0)
return "-" & convertBase26(-num) // '&' is concatenate.
else if (num = 0)
return "A"
endif
output = "";
while (num > 0)
output <- ('A' + num MOD 26) & output // Modulus operator.
num <- num DIV 26 // Integer division.
endwhile
return output
endfunc
This uses A = 0, B = 1, up to Z = 25 and standard place notation: 26 = BA. Obviously a base conversion is easily reversible.
strtr() is a magnificent tool for this task! It replaces the longest match as is traverses the string.
Code: (Demo)
function toAlpha ($num) {
return strtr($num, range("A", "Z"));
}
$string = toAlpha("138201162401719");
echo "$string\n";
$string = toAlpha("123456789012345");
echo "$string\n";
$string = toAlpha("101112131415161");
echo "$string\n";
$string = toAlpha("2625242322212019");
echo "$string";
Output:
NIULGYART
MDEFGHIJAMDEF
KLMNOPQB
CGZYXWVUT
Just flip the lookup array to reverse the conversion: https://3v4l.org/YsFZu
Merged: https://3v4l.org/u3NQ5
Of course, I must mention that there is a vulnerability with converting a sequence of letters to numbers and back to letters. Consider BB becomes 11 then is mistaken for eleven which would traslate to L when converted again.
There are ways to mitigate this by adjusting the lookup array, but that may not be necessary/favorable depending on program requirements.
And here is another consideration from CodeReview.
I have been trying to do the same thing in PHP without success.
Assuming I'm using the 26 letters of the English alphabet, starting with A = 0 down to Z as 25:
I find the highest power of 26 lower than the number I am encoding. I divide it by the best power of 26 I found. Of the result I take away the integer, convert it to a letter and multiply the decimals by 26. I keep doing that until I get a whole number. It's ok to get a zero as it's an A, but if it has decimals it must be multiplied.
For 1 billion which is DGEHTYM and it's done in 6 loops obviously. Although my answer demonstrates how to encode, I'm afraid it does not help doing so on PHP which is what I'm trying to do myself. I hope the algorithm helps people out there though.
The number is 13911392101301011 and regardless of using sprintf or number_format i get the same strange result.
sprintf('%017.0f', "13911392101301011"); // Result is 13911392101301012
number_format(13911392101301011, 0, '', ''); // Result is 13911392101301012
sprintf('%017.0f', "13911392101301013"); // Result is 13911392101301012
number_format(13911392101301013, 0, '', ''); // Result is 13911392101301012
As you actually have the number as a string, use the %s modifier:
sprintf('%s', "13911392101301011"); // 13911392101301011
Note that PHP is using a signed integer internally. The size depends on your system.
32bit system:
2^(32-1) = 2147483648
64bit system:
2^(64-1) = 9223372036854775808
-1 because 1 bit is reserved for the signage flag.
Since you are dealing with large numbers here, you may want to keep them as strings and perform numerical operation on the string values using BCMath functions.
$val = "13911392101301011";
echo $val; // 13911392101301011
echo bcadd($val, '4'); // 13911392101301015
echo bcmul($val, '2'); // 27822784202602022
You can do easily this way :-
ini_set("precision",25); // change 25 to whatever number you want or need
$num = 13911392101301011;
print $num;
Documentation states that $number in number_format is float so there is explicit typecast. Equivalent would look like this:
sprintf('%017.0f', (float) "13911392101301011");
Float is precise to around 14 digits and your number has 17 digits.
Your number_format call is setting the . and , to blank
string number_format ( float $number , int $decimals = 0 , string $dec_point = '.' , string $thousands_sep = ',' )
try this:
number_format(13911392101301011, 0, '.', ',');