Identifiy float values in array with text strings [duplicate] - php

This is really weird. I have this piece of code.
$rewardAmt = $amt;
if(is_float($rewardAmt)){
print_r("is float");die;
} else {
print_r("is not float"); die;
}
value of $amt is 0.01. But it is going into else condition. So I did a var_dump of $amt. it says string(4)
So I decided to typecast $amt
$rewardAmt = (float)$amt;
But the problem with this is even if the value of $amt is 1, it still gets typecast to float and goes into if condition, which shouldn't happen. Is there any other way to do this ? Thanks

Use filter_var() with FILTER_VALIDATE_FLOAT
if (filter_var($amount, FILTER_VALIDATE_FLOAT))
{
// good
}

If you change the first line to
$rewardAmt = $amt+0;
$rewardAmt should be cast to a number.

You can check this by
$float = floatval($num); //Convert the string to a float
if($float && intval($float) != $float) // Check if the converted int is same as the float value...
{
// $num is a float
}else{
// $num is an integer
}

You can use the unary + operator, which will cast the string to the appropriate type (int or float), and then test the resulting data type with is_float:
$s = "3.00";
$n = +$s;
var_dump( $n ); // float(3)
var_dump( is_float($n) ); // true
$s = "3";
$n = +$s;
var_dump( $n ); // int(3)
var_dump( is_float($n) ); // false

As suggested in the documentation of is_float function:
Note: To test if a variable is a number or a numeric string (such as
form input, which is always a string), you must use is_numeric().
The answer is using is_numeric() and not is_float().
This works also if the number tested is "0" or 0.

Related

How to determine the type of a numerical value passed as a string without losing data or being converted to wrong datatype

I want to allow users to submit numerical values through an online form but I've ran into a problem trying to validate the correct datatype(integer or float) for the submitted value.
Lets say a user submits:
3.14
I cannot use is_float() because the user-value is technically a string.
floatval() would work, except when the user only supplies an integer floatval() still considers it a float instead of an integer.
gettype(floatval("3"))
returns float, but I need it to return integer.
I even tried checking if it was an integer like this:
is_int(floatval(3)) // returns false
But why does the above return false?
The below prints 3 as if it was an integer:
echo floatval(3)
Therefore, I need a function that can be able to tell the difference between a float and integer passed as a string so it doesn't
pass an integer off as a float.
doesn't truncate a float into an integer.
Pattern checking with regular expressions could possibly be a solution, but are there any other alternatives?
NOTE: I am not using classes or objects and I prefer not to if possible.
Convert it to a float and integer, then check if they're equal.
$i = intval($input);
$f = floatval($input);
if ($i == $f) {
$type = "int";
} else {
$type = "float";
}
Below function will solve your problem
function checkType($inputNumber){
if (strpos($inputNumber, '.') !== false) {
return 'Number is float';
} else {
return 'Number is integer';
}
}
echo checkType(3.5); o/p Number is float.
echo checkType(3); o/p Number is integer.
First of all, If you checking float then obviously it will only return true or false on float value weather or not it's a integer.
You are checking for float then how can you expect that it will return integer. Use intval() to check integer value.
<?php
echo intval(42); // 42
echo intval(4.2); // 4
echo intval('42'); // 42
echo intval('+42'); // 42
echo intval('-42'); // -42
echo intval(042); // 34
echo intval('042'); // 42
echo intval(1e10); // 1410065408
echo intval('1e10'); // 1
Or you can do one thing you can check if dot(.) exist then check with floatval() and not then check with intval()
You can alos do something like following
<?php
$a = '1.6';
if(str_pos($a, '.') !== 'false){
$a = intval($a);
}else{
$a = floatval($a);
}

check php post value is numeric and well formatted

I need to check POST value is numeric and well formatted. My expected format is
number.number
1.0
11.5
If POST value comes without .(DOT) only 1 then I would want that php convert that to 1.0
I tried this code but it doesn't work.
$foo = '2';
$foo = preg_match('/\\d{2}\\:\\d{2}\\.\\d{2}/', $foo);
Thanks :)
Working code
//$value = '22';
$value = $_POST["input_value"];
if (is_numeric($value)) {
$new_value = number_format($value, 1);
} else {
$new_value = "$value is not numeric. <br>";
}
echo $new_value;
You basically want to check if the variable from the POST array is a float/double or not (float/double is a type of number in the format of x.x).
Cheking if a string is a float/double number
To do that, use this php built-in function: is_double or more accurate:is_float, that will tell you if the string is a float/double.
Checking if a string is an integer and converting it to a double/float value
If it's not a double, check if it's an integer (regular number): is_int, and if it's indeed an int, cast it to double by using number_format, look at the usage here: integer to double/float in php.
Example
$final_value;
$value = $_POST["wanted_value"];
if (is_float($value))
{
$final_value = $value;
}
else if (is_int($value))
{
$final_value = number_format($value, 1); // or 2 instead of 1 (2.0 or 2.00)
}
else
{
$final_value = "ERROR";
}
Hope this helps!

PHP - need clarification on is_int() and while loop

I want to convert a decimal number to an integer by multiplying it by 10 until it gives me an integer.
Example:
0.2 should become 2 and
0.004 should become 4
Here is my function
function make_integer($num){
if (!is_int($num)){
$temp = $num;
while (!is_int($temp)){
$temp *= 10;
}
return $temp;
}
return $num;
}
I want
make_integer(0.2) => 2
Shouldn't the function stop when $temp becomes an integer?
The function seems to be going in an infinite loop.
Could someone tell me why this isn't working please?
Short answer
This will solve your problem
function make_integer($num){
if ((int)$num != $num){
$temp = $num;
while ((int)$temp != $temp){
$temp *= 10;
}
return $temp;
}
return $num;
}
Long Answer
The problem is that is_int does not test if your value is an integer or not. It will test if its type is an integer or not. So is_int($var) will do the same as if you ran gettype($var) == 'integer'.
Some basic tests:
is_int((int) 0.57); # returns true, because the type is an int.
is_int((float) 4); # returns false, because the type is a float
is_int(10 * 0.2); # returns false, because int*float will be typecasted to a float
To make your code work, and to test if a value is an integer, you should cast your variable to an integer and then test if it is still equal to the original variable, like this:
(int) $var == $var; # will return true if the value is int
To fix your code, substitute the !is_int($num) with (int) $num != $num and !is_int($temp) with (int) $temp != $temp, just like the code in the short answer above.
But, I can't resist to give an alternative solution to your problem. Personally, I would opt to use recursion for this problem. Like this:
function make_integer($num) {
return (int)$num == $num ? $num : make_integer($num * 10);
}
Or if you dislike the ternary operator:
function make_integer($num) {
if ((int)$num == $num)
return $num; # We're all done!
else
return make_integer($num * 10); # Try to increase by 10
}
Even longer answer
The type casting of php will take some time to learn. In general, PHP will allways try to type cast if it can. When you multiply an integer with a float, the result will be a float, even if it "looks" like an integer.
So try this code and pay special attention to the output:
$var = 0.03;
var_dump($var); # float(0.03)
var_dump(gettype($var)); # string(6) "double"
var_dump(is_int($var)); # bool(false)
Now, if you multiply by the integer 100, php will stick the float, as <float>*<int> multiplication allways will result in a float, regardless of the value.
$var *= 100; # (100 * 0.03)
var_dump($var); # float(3)
var_dump(gettype($var)); # string(6) "double"
var_dump(is_int($var)); # bool(false)
Note that the value is a natural number, but the type is still a float, and thus is_int will not return true.
To test if a actual value of a variable is indeed an integer, we will need to do our own little trick with manual typecasting.
$var = 2.33;
var_dump($var); # float(2.33)
$var = (int) $var;
var_dump($var); # int(2)
Note that when we tried to cast a float to an int the value changed. But if we try to cast a float that is an integer to an int, the value remains unaffected, only the type gets changed:
$var = 2.0;
var_dump($var); # float(2)
$var = (int) $var;
var_dump($var); # int(2)
And now, remember how <int>*<float> resulted in a float? PHP will work in the same way when you do comparisons. In php, "2.0" == 2 will be true because of this automatic typecasting. So when you do <int> == <float> what really happens is (float)<int> == <float>.
So what happens if we do (float)(int)0.3. First we typecast 0.3 to int(0), then we typecast back to float(0). Obviously, float(0) == float(0.3) will be false. But (float)(int)3.0 will be cast first to int(3) then to float(3), which was the same value we started with.
$var = 3.0;
var_dump($var); # float(3)
$var = (int) $var;
var_dump($var); # int(3)
$var = (float) $var;
var_dump($var); # float(3)
So if we do (int) 3.0 == 3.0, it will result in (float)(int) 3.0 == 3.0 which is true.
So the way to test if a value is integer is to do
(int)$var == $var
answer:
$i=0.0004 ;
gettype($i) == 'float'
$i*= 10;
gettype($i) == 'float'
float != int
to resolve your problem, change the logic test.
(int) $i == $i
This isn't the prettiest but it works.
function make_int($num){
//if it's not an int...
if(!is_int($num)){
//find out how many decimal places and store in a variable
$multiply = strlen(substr(strrchr($num, "."), 1));
//multiply the number by the power of the multiple.
$num *= (pow (10,$multiply));
return $num;
}
}
make_int(0.004);

How do I convert a string to a number in PHP?

I want to convert these types of values, '3', '2.34', '0.234343', etc. to a number. In JavaScript we can use Number(), but is there any similar method available in PHP?
Input Output
'2' 2
'2.34' 2.34
'0.3454545' 0.3454545
You don't typically need to do this, since PHP will coerce the type for you in most circumstances. For situations where you do want to explicitly convert the type, cast it:
$num = "3.14";
$int = (int)$num;
$float = (float)$num;
There are a few ways to do so:
Cast the strings to numeric primitive data types:
$num = (int) "10";
$num = (double) "10.12"; // same as (float) "10.12";
Perform math operations on the strings:
$num = "10" + 1;
$num = floor("10.1");
Use intval() or floatval():
$num = intval("10");
$num = floatval("10.1");
Use settype().
To avoid problems try intval($var). Some examples:
<?php
echo intval(42); // 42
echo intval(4.2); // 4
echo intval('42'); // 42
echo intval('+42'); // 42
echo intval('-42'); // -42
echo intval(042); // 34 (octal as starts with zero)
echo intval('042'); // 42
echo intval(1e10); // 1410065408
echo intval('1e10'); // 1
echo intval(0x1A); // 26 (hex as starts with 0x)
echo intval(42000000); // 42000000
echo intval(420000000000000000000); // 0
echo intval('420000000000000000000'); // 2147483647
echo intval(42, 8); // 42
echo intval('42', 8); // 34
echo intval(array()); // 0
echo intval(array('foo', 'bar')); // 1
?>
In whatever (loosely-typed) language you can always cast a string to a number by adding a zero to it.
However, there is very little sense in this as PHP will do it automatically at the time of using this variable, and it will be cast to a string anyway at the time of output.
Note that you may wish to keep dotted numbers as strings, because after casting to float it may be changed unpredictably, due to float numbers' nature.
Instead of having to choose whether to convert the string to int or float, you can simply add a 0 to it, and PHP will automatically convert the result to a numeric type.
// Being sure the string is actually a number
if (is_numeric($string))
$number = $string + 0;
else // Let the number be 0 if the string is not a number
$number = 0;
Yes, there is a similar method in PHP, but it is so little known that you will rarely hear about it. It is an arithmetic operator called "identity", as described here:
Aritmetic Operators
To convert a numeric string to a number, do as follows:
$a = +$a;
If you want get a float for $value = '0.4', but int for $value = '4', you can write:
$number = ($value == (int) $value) ? (int) $value : (float) $value;
It is little bit dirty, but it works.
You can use:
(int)(your value);
Or you can use:
intval(string)
In PHP you can use intval(string) or floatval(string) functions to convert strings to numbers.
You can always add zero to it!
Input Output
'2' + 0 2 (int)
'2.34' + 0 2.34 (float)
'0.3454545' + 0 0.3454545 (float)
Just a little note to the answers that can be useful and safer in some cases.
You may want to check if the string actually contains a valid numeric value first and only then convert it to a numeric type (for example if you have to manipulate data coming from a db that converts ints to strings). You can use is_numeric() and then floatval():
$a = "whatever"; // any variable
if (is_numeric($a))
var_dump(floatval($a)); // type is float
else
var_dump($a); // any type
Here is the function that achieves what you are looking for. First we check if the value can be understood as a number, if so we turn it into an int and a float. If the int and float are the same (e.g., 5 == 5.0) then we return the int value. If the int and float are not the same (e.g., 5 != 5.3) then we assume you need the precision of the float and return that value. If the value isn't numeric we throw a warning and return null.
function toNumber($val) {
if (is_numeric($val)) {
$int = (int)$val;
$float = (float)$val;
$val = ($int == $float) ? $int : $float;
return $val;
} else {
trigger_error("Cannot cast $val to a number", E_USER_WARNING);
return null;
}
}
If you want the numerical value of a string and you don't want to convert it to float/int because you're not sure, this trick will convert it to the proper type:
function get_numeric($val) {
if (is_numeric($val)) {
return $val + 0;
}
return 0;
}
Example:
<?php
get_numeric('3'); // int(3)
get_numeric('1.2'); // float(1.2)
get_numeric('3.0'); // float(3)
?>
Source: https://www.php.net/manual/en/function.is-numeric.php#107326
I've been reading through answers and didn't see anybody mention the biggest caveat in PHP's number conversion.
The most upvoted answer suggests doing the following:
$str = "3.14"
$intstr = (int)$str // now it's a number equal to 3
That's brilliant. PHP does direct casting. But what if we did the following?
$str = "3.14is_trash"
$intstr = (int)$str
Does PHP consider such conversions valid?
Apparently yes.
PHP reads the string until it finds first non-numerical character for the required type. Meaning that for integers, numerical characters are [0-9]. As a result, it reads 3, since it's in [0-9] character range, it continues reading. Reads . and stops there since it's not in [0-9] range.
Same would happen if you were to cast to float or double. PHP would read 3, then ., then 1, then 4, and would stop at i since it's not valid float numeric character.
As a result, "million" >= 1000000 evaluates to false, but "1000000million" >= 1000000 evaluates to true.
See also:
https://www.php.net/manual/en/language.operators.comparison.php how conversions are done while comparing
https://www.php.net/manual/en/language.types.string.php#language.types.string.conversion how strings are converted to respective numbers
In addition to Boykodev's answer I suggest this:
Input Output
'2' * 1 2 (int)
'2.34' * 1 2.34 (float)
'0.3454545' * 1 0.3454545 (float)
Only multiply the number by 1 so that the string is converted to type number.
//String value
$string = "5.1"
if(is_numeric($string)){
$numeric_string = $string*1;
}
Alright so I just ran into this issue. My problem is that the numbers/strings in question having varying numbers of digits. Some have no decimals, others have several. So for me, using int, float, double, intval, or floatval all gave me different results depending on the number.
So, simple solution... divide the string by 1 server-side. This forces it to a number and retains all digits while trimming unnecessary 0's. It's not pretty, but it works.
"your number string" / 1
Input Output
"17" 17
"84.874" 84.874
".00234" .00234
".123000" .123
"032" 32
Here is a function I wrote to simplify things for myself:
It also returns shorthand versions of boolean, integer, double and real.
function type($mixed, $parseNumeric = false)
{
if ($parseNumeric && is_numeric($mixed)) {
//Set type to relevant numeric format
$mixed += 0;
}
$t = gettype($mixed);
switch($t) {
case 'boolean': return 'bool'; //shorthand
case 'integer': return 'int'; //shorthand
case 'double': case 'real': return 'float'; //equivalent for all intents and purposes
default: return $t;
}
}
Calling type with parseNumeric set to true will convert numeric strings before checking type.
Thus:
type("5", true) will return int
type("3.7", true) will return float
type("500") will return string
Just be careful since this is a kind of false checking method and your actual variable will still be a string. You will need to convert the actual variable to the correct type if needed. I just needed it to check if the database should load an item id or alias, thus not having any unexpected effects since it will be parsed as string at run time anyway.
Edit
If you would like to detect if objects are functions add this case to the switch:
case 'object': return is_callable($mixed)?'function':'object';
$a = "10";
$b = (int)$a;
You can use this to convert a string to an int in PHP.
I've found that in JavaScript a simple way to convert a string to a number is to multiply it by 1. It resolves the concatenation problem, because the "+" symbol has multiple uses in JavaScript, while the "*" symbol is purely for mathematical multiplication.
Based on what I've seen here regarding PHP automatically being willing to interpret a digit-containing string as a number (and the comments about adding, since in PHP the "+" is purely for mathematical addition), this multiply trick works just fine for PHP, also.
I have tested it, and it does work... Although depending on how you acquired the string, you might want to apply the trim() function to it, before multiplying by 1.
Late to the party, but here is another approach:
function cast_to_number($input) {
if(is_float($input) || is_int($input)) {
return $input;
}
if(!is_string($input)) {
return false;
}
if(preg_match('/^-?\d+$/', $input)) {
return intval($input);
}
if(preg_match('/^-?\d+\.\d+$/', $input)) {
return floatval($input);
}
return false;
}
cast_to_number('123.45'); // (float) 123.45
cast_to_number('-123.45'); // (float) -123.45
cast_to_number('123'); // (int) 123
cast_to_number('-123'); // (int) -123
cast_to_number('foo 123 bar'); // false
function convert_to_number($number) {
return is_numeric($number) ? ($number + 0) : FALSE;
}
You can use:
((int) $var) ( but in big number it return 2147483647 :-) )
But the best solution is to use:
if (is_numeric($var))
$var = (isset($var)) ? $var : 0;
else
$var = 0;
Or
if (is_numeric($var))
$var = (trim($var) == '') ? 0 : $var;
else
$var = 0;
Simply you can write like this:
<?php
$data = ["1","2","3","4","5"];
echo json_encode($data, JSON_NUMERIC_CHECK);
?>
There is a way:
$value = json_decode(json_encode($value, JSON_NUMERIC_CHECK|JSON_PRESERVE_ZERO_FRACTION|JSON_UNESCAPED_SLASHES), true);
Using is_* won't work, since the variable is a: string.
Using the combination of json_encode() and then json_decode() it's converted to it's "true" form. If it's a true string then it would output wrong.
$num = "Me";
$int = (int)$num;
$float = (float)$num;
var_dump($num, $int, $float);
Will output: string(2) "Me" int(0) float(0)
Now we are in an era where strict/strong typing has a greater sense of importance in PHP, I use json_decode:
$num = json_decode('123');
var_dump($num); // outputs int(123)
$num = json_decode('123.45');
var_dump($num); // outputs float(123.45)
You can change the data type as follows
$number = "1.234";
echo gettype ($number) . "\n"; //Returns string
settype($number , "float");
echo gettype ($number) . "\n"; //Returns float
For historical reasons "double" is returned in case of a float.
PHP Documentation
If you don't know in advance if you have a float or an integer,
and if the string may contain special characters (like space, €, etc),
and if it may contain more than 1 dot or comma,
you may use this function:
// This function strip spaces and other characters from a string and return a number.
// It works for integer and float.
// It expect decimal delimiter to be either a '.' or ','
// Note: everything after an eventual 2nd decimal delimiter will be removed.
function stringToNumber($string) {
// return 0 if the string contains no number at all or is not a string:
if (!is_string($string) || !preg_match('/\d/', $string)) {
return 0;
}
// Replace all ',' with '.':
$workingString = str_replace(',', '.', $string);
// Keep only number and '.':
$workingString = preg_replace("/[^0-9.]+/", "", $workingString);
// Split the integer part and the decimal part,
// (and eventually a third part if there are more
// than 1 decimal delimiter in the string):
$explodedString = explode('.', $workingString, 3);
if ($explodedString[0] === '') {
// No number was present before the first decimal delimiter,
// so we assume it was meant to be a 0:
$explodedString[0] = '0';
}
if (sizeof($explodedString) === 1) {
// No decimal delimiter was present in the string,
// create a string representing an integer:
$workingString = $explodedString[0];
} else {
// A decimal delimiter was present,
// create a string representing a float:
$workingString = $explodedString[0] . '.' . $explodedString[1];
}
// Create a number from this now non-ambiguous string:
$number = $workingString * 1;
return $number;
}
All suggestions lose the numeric type.
This seems to me a best practice:
function str2num($s){
// Returns a num or FALSE
$return_value = !is_numeric($s) ? false : (intval($s)==floatval($s)) ? intval($s) :floatval($s);
print "\nret=$return_value type=".gettype($return_value)."\n";
}
//Get Only number from string
$string = "123 Hello Zahid";
$res = preg_replace("/[^0-9]/", "", $string);
echo $res."<br>";
//Result 123

is_int returns false for negative values like "-10"?

Does php's is_int function return false for negative numbers because integers in php are unsigned, or is there other behaviour that I'm missing? I'm trying to check if something is a whole number, and I don't want to rely on that behaviour of is_int (for the first part of the test) if it's doing something different.
Clarification: I know that is_int returns false for negative numbers, but I'm asking why because of this behaviour: var_dump(intval("-10")) prints int(-10), and var_dump(intval("10")) prints int(1), so both negative and positive values are considered integers, yet is_int("-10") returns false.
EDIT: Ok, sorry everyone, I got quite a bit confused about the behaviour of is_int and integers in general. I was thinking of it acting on a string with contents like "-10" when what I need is is_numeric on a string, or is_int on an integer itself. Thanks for the help.
It doesn't:
var_dump( is_int(-10) ); // bool(true)
Probably, it isn't a number to begin with:
var_dump( is_int('-10') ); // bool(false)
If so, try out is_numeric(), which is designed for strings.
Why not test it for yourself?
<?php
var_dump(is_int(-1));
var_dump(is_int('-1'));
produces:
bool(true)
bool(false)
use
is_int(-10)
not
is_int("-10")
I know this question is old, bu if someone need to check if a string represents an valid int, or, for example, a float, here is a simple script that will make that validation
$is_int = (is_int($val))||(((int)$val)&&(((int)$val)==((float)$val)&&((string)$val==$val))||$val==='0');
It works as a check. Forst, the simple is_int() function, then, it checks, for non zero values if the int conversion is equal to its float one, and finally, if the string is literally "0".
<?php
$val = 3;
$is_int = (is_int($val))||(((int)$val)&&(((int)$val)==((float)$val)&&((string)$val==$val))||$val==='0');
var_dump($is_int);
$val = 5.5;
$is_int = (is_int($val))||(((int)$val)&&(((int)$val)==((float)$val)&&((string)$val==$val))||$val==='0');
var_dump($is_int);
$val = 'hola';
$is_int = (is_int($val))||(((int)$val)&&(((int)$val)==((float)$val)&&((string)$val==$val))||$val==='0');
var_dump($is_int);
$val = '3';
$is_int = (is_int($val))||(((int)$val)&&(((int)$val)==((float)$val)&&((string)$val==$val))||$val==='0');
var_dump($is_int);
$val = '5.5';
$is_int = (is_int($val))||(((int)$val)&&(((int)$val)==((float)$val)&&((string)$val==$val))||$val==='0');
var_dump($is_int);
$val = '0';
$is_int = (is_int($val))||(((int)$val)&&(((int)$val)==((float)$val)&&((string)$val==$val))||$val==='0');
var_dump($is_int);
$val = 0;
$is_int = (is_int($val))||(((int)$val)&&(((int)$val)==((float)$val)&&((string)$val==$val))||$val==='0');
var_dump($is_int);
//bool(true) bool(false) bool(false) bool(true) bool(false) bool(true) bool(true)

Categories