Is there a number_format alternative in PHP that allows me to chose thousands and decimal separator, while keeping the number of decimals? E.g. something like this:
number_format_alternative( '1234.617', ',', '.' );
>1 234,617
but
number_format_alternative( '120.0', ',', '.' );
>120.0
I realize that I could achieve almost the same thing, by using a ridiculously high number of decimals, and trimming all zeros from the right, though the second example would then look like:
number_format_alternative( 120.0, ',', '.' );
>120
edit: This is what I ended up doing:
function numberOfDecimals( $number ) {
return strlen(strstr(rtrim(sprintf('%.10F', $number), '0'), '.'))-1;
}
Since you are inputting the number to the function as a string you could use a regular expression to see how many digits are after the decimal point, represented by '.' in this case, and then execute number_format with the $decimals parameter set to the number you just calculated.
One regular expression that would work would be \.\d+ and then minus 1 off the length to find the decimals number, you could use a look behind how ever I think the performance would be worse. Some testing may be needed and I am sure there will be other regular expressions that would work.
Related
I am working on a PHP-script that handles monetairy amounts, and therefore needs to be exact with 2 decimals. To do this, I convert the user-input to a number by multiplying it with 100, and then casting it to int. This works fine, untill I recently discovered a number that increases by 1 when cast to int.
the malfunctioning code:
$number = (int)(str_replace(',','.',$_POST["input"])*100);
The number that gives problems is 2509,22 (I live in the Netherlands, so we use comma's for decimals, hence the str_replace in the above line of code).
This value creates the integer $number 250921, which is obviously 1 too low.
I know that int has limits, but this number is well within those limits as far as I'm aware...
When you multiply the string by 100 you get a float and its representation is not always what you expect, in this case 250921.99999999997. See it with:
echo serialize(str_replace(',','.','2509,22')*100);
Then you cast to an integer which trucates the fraction to get 250921. See Is floating point math broken?.
The solution would be to remove the comma and use as is and optionally cast to an integer:
$number = (int)str_replace(',', '', '2509,22');
For the issue of users entering too many fractional numbers, you should either use two inputs, one for whole number and one for fraction and/or restrict/validate that the inputs are correctly formatted. However, you can format the number first:
echo $number = (number_format(str_replace(',', '.', '2509,22'), 2, '.', '')*100);
You can use regex to match the int and zero - two decimals.
This will not do any conversions and nothing is multiplied or casted.
It will be treated as a string and nothing changes but the number of decimals.
$input = "2509,2222222";
// Regex number comma number (zero - two)
Preg_match("/(\d+),*(\d{0,2})/", $input, $m);
Unset($m[0]); // remove full match
Echo implode("", $m); // implode parts
https://3v4l.org/MjcYV
I have a need to extract a sub-string from a longer string. I know how I would approach it using PHP posstr(); and strpos();, but the data is very large and I suspect that it would be more efficient if I could extract the part string using regex.
For example, if I have a number, (say a latitude) that has the format
"3203.79453"
where the the two characters before and "all" the characters after the decimal point represent decimal seconds, then to obtain the decimal latitude I need to compute the following:
32 + (03.79453)/60 = 32.06324217
So in essence I need a regex method of extracting the sub-string "03.79453".
So two questions how do I achieve it using regex and is it faster than using the method of using strpos() and posstr().
Thanks
It's easy to achieve with both options:
substr($line, strpos($line, '.') - 2);
or:
preg_match("/(\d{2}\..*)/", $line, $matches);
As for performance, I guess you would need to benchmark it. I've done a quick test to compare the performance of each example by running one million reps of each of those lines:
preg_match: average around 1.6 seconds for 1,000,000 matches
substr: average around 0.85 seconds for 1,000,000 matches
In this case it seems clear that using substr is the winner in terms of performance.
You could use preg_replace() like so:
<?php
$geoCoordinate = "3203.79453";
$degrees = preg_replace("#(\d{2}\.\d*?$)#", "", $geoCoordinate);
$seconds = preg_replace("#(\d*?)(\d{2}\.\d*?)#", "$2", $geoCoordinate);
$degAndSecs = round($degrees + ($seconds/60), 8);
var_dump($degAndSecs); //<== PRODUCES::: float 32.06324217
I have been handling long numbers in PHP. Like the following examples.
12.020000
12.000000
To get rid of trailing zeros and the decimal point I have been using the following inside a function.
return rtrim(rtrim($str, "0"),".");
So the above turns out like.
12.02
12
It was a bit short sighted as when 1000 gets entered it gets turned into 1.
Can someone please help me with the code to remove trailing zeros after the decimal point only?
Bonus points if the code removes the decimal place but I can always feed it into rtim($str,".").
EDIT: To be clear, I am stripping the decimal place and zeros only when displaying to the screen. Also casting to float is not an option as I also handle numbers like 0.00000001 which come out like 1.0e-9 sort of thing.
Why are you using string to hold numbers? Cast it to float and it'll solve your problem.
$string = '12.020000';
$number = (float) $string; // will be 12.02
Then, if you want to use it as string (but why?)
$string = (string) $number;
The thing that perplexes me about your question is that extra zeros won't be included in a number variable without intentionally adding them with number_format. (This may be why someone down-voted it).
Normally you don't want to use string functions (meant for text) on variables that hold numbers. If you want to round off a number, use a function like round.
http://php.net/manual/en/function.round.php
There's also number_format, which can format numbers by adding zero padding: (it doesn't actuall round, just trims off excess numbers).
http://php.net/manual/en/function.number-format.php
Since your zeros are appearing, it's likely that you simply need to multiple the variable by 1, which will essentially convert a string to a number.
Good luck!
I would like to format numbers, so numbers woul format like this:
1=1
10=10
100=100
1000=1,000
10000=10,000
100000=100,000
1000000=1,000,000
I think it can be done with number_format(), but right now I`m having a problem, so if the number is 35679 it shows 35,679,000.
If you want 35679 to show up as 35,679:
number_format(35679,0,'',',');
First parameter is the input number. Second is the amount of decimals. Third is the decimal separator (not needed without decimals).
Last is the thousands separator.
(You probably set the number of decimals to 3)
Please see THIS for a complete explanation of number_format().
For example you would need number_format($number, 0) if the default settings are present or number_format($number, 0, '.', ',') for comma to be used as thousand seperator.
I want to make a bid system on a website. That means users can post their bid (natural number). I want to make sure users don't try to post characters, decimal numbers, etc.
I don't want to use is_numeric function because hexadecimal notation is allowed.
I was thinking to use preg_match for this. But in php.net the documentation for this function is little and I have no idea how to use preg_match.
So how should I check if a variable is a natural number with preg_match?
If you don't require decimal points: ctype_digit or filter_var($var, FILTER_VALIDATE_INT).
If you do: filter_var($var, FILTER_VALIDATE_FLOAT).
ctype_digit does what you want:
Checks if all of the characters in the provided string, text, are numerical.
(Before PHP 5.1.0, this function returned TRUE when text was an empty string.)
Either preg_match('/^[0-9]+$/', $var); or ctype_digit
I would generally caution against using regex for parsing numerics, as there are generally better solutions than regex for this, but since you're asking, I'll try to give you some assistance with it:
preg_match uses regular expressions (regex) for it's matching.
You can find out more about regex syntax at sites like http://www.regular-expressions.info/
If you want to match a digit in regex, you can either use [0-9] or \d.
If you want to match one or more of anything, you would use a plus sign.
Finally, regex strings need to be enclosed in a pair of characters. The character chosen is usually a slash (/) character, as some languages specifically require this character, but PHP also allows other characters to be used; tilde (~) is quite common.
So your regex string to match any number of digits would be "/\d+/". This can then be put into a preg_match call like so:
$isnumeric = preg_match("/\d+/",$input_string);
If you have more specific requirements, you can limit the number of characters allowed by replacing the plus sign with {max} or {min,max} where 'min' and 'max' are the number of times the preceding match is allowed. So to allow a number between two and six digits long, you would use this:
$isnumeric = preg_match("/\d{2,6}/",$input_string);
If you need to allow a decimal point, you need to know that the dot character is a special character in regex (it means 'match any character at all'), so you need to escape it with a back-slash.
Therefore, a regex to match a currency amount with two decimal places, and at least one digit before the point would be like this:
$isnumeric = preg_match("/\d+\.\d\d/",$input_string);
Finally, note that regex will return true in all the above if the string simply contains the matched value. To ensure it doesn't contain anything else, you would need to 'anchor' it to the front and end of the string, using the anchor characters: ^ for the start of the string, and $ for the end.
So for the previous example, if you want it to only contain a decimal number, and nothing else, you would need this:
$isnumeric = preg_match("/^\d+\.\d\d$/",$input_string);
Regex is a complex subject, but I hope that gives you a start.
I know this is very old but I wanted to share the next solution in case someone else comes up with this problem.
I'm assuming that by natural number you meant positive integer (which excludes the number 0).
function is_positive_integer( $value ) {
// Check if is integer and greater than zero
if( is_int( $value ) && $value > 0 ) {
return true;
}
// Is not a positive integer
else {
return false;
}
}
This kind of depends on your definition of natural numbers - according to different theories, the number zero (0) does or does not count as a natural number.
To answer your question on how to solve this with preg_match:
If you want to include zero, using preg_match is pretty easy preg_match('^[0-9]+$', $input).
Usage:
if (preg_match('^[0-9]+$', $input))
// $input represents a non-negative numeric value
else
// $input does not represent a non-negative numeric value
If you don't want to include the zero, use preg_match('^[1-9][0-9]*$', $input):
if (preg_match('^[1-9][0-9]*$', $input))
// $input represents a positive numeric value
else
// $input does not represent a positive numeric value
That said - for your particular problem, using ctype_digit is a faster solution, as others already pointed out (you'd have to do a second check if you don't want to allow the number zero).
in_array(str_replace(str_split('0123456789'), '', $s), array(',','.',''));
simple function:
function isnature($x){
$y = ceil($x)-floor($x);
return $y == 0 ? true : false;
}
From a mathematical point of view, a natural number is a positive integer, including zero, so you could check it like this:
is_int($bid) && $bid >= 0
Simplest and faster
if( is_numeric( $key ) && intval( $key ) == $key )
{
//key == number
}