Compare string "numerically first" - php

I want to compare two string "numerically". I mean like 2C is less than 11A. I tried this and it's not working:
if("2A" < "11A"){
echo "First corect";
}
if(strcmp("2A", "11A") < 0){
echo "Last corect";
}
echo "Tests completed";

You are looking for strnatcmp (or its case-insensitive sibling, strnatcasecmp).
This will compare the numeric parts of your input as numbers (placing "2whatever" before "11whatever") and the textual parts as text (placing "2a" before "2b").

Try it like this:
if((int) '2A' < (int) '11A'){
echo "First correct";
}
You can also take a look at: http://php.net/manual/en/function.intval.php

if(intval(0x2A) < intval(0x11A)){
echo "First corect";
}
else
{
echo "Tests incompleted";
}
try this code

Write a function that:
Tokenizes each String into a List <Object> where each object can be a String or Integer with the Integers being created from a contiguous string of digits between non-digits, the Strings being contiguous non-digits between any 2 digits.
In a loop compare the two Lists element by element. If the type of the objects doesn't match (i.e. comparing an Integer to a String) make the less/greater decision on which you want to sort as smaller, letters or digits. If they match just do a less than, equals, greater than comparison.
If the two Nth elements in the list are equal, go on to compare the N+1th elements, otherwise return t/f based on the integer to integer or string to string comparison.

Related

PHP "is_numeric" accepts "E" as a number

I noticed PHP is_numeric() accepts "E" as a number.
I have a string: "88205052E00" and I want the result to be: NOT numeric.
Here is the code which I tested.
<?php
$notnumber = '88205052E00';
if(is_numeric($notnumber)) {
echo $notnumber . ' is a number';
} else {
echo $notnumber . ' is NOT a number';
}
?>
The Code above gives result:
88205052E00 is a number
How can I get the result to be: 88205052E00 is NOT a number?
I will keep the answer incase it helps but as pointed out there are shortcomings with ctype_digit in that it does not like - or ..
More likely then you want to use ctype_digit which checks if all of the characters in the provided string, text, are numerical.
Where as is_numeric — Finds whether a variable is a number or a numeric string
<?php
$s = "88205052E00";
if(ctype_digit($s)){
echo "Yes";
} else {
echo "No";
}
returns no.
Just use a regular expression:
<?php
if (preg_match("/^\-?[0-9]*\.?[0-9]+\z/", $notnumber)) {
echo "$notnumber is numeric\n";
} else {
echo "$notnumber is not numeric\n";
}
Results:
1234 is numeric
1234E56 is not numeric
-1234 is numeric
.1234 is numeric
-.1234 is numeric
-12.34 is numeric
E is valid because of floating point numbers (http://php.net/manual/en/language.types.float.php).
If you don't want to allow E for whatever reason, you could check for it independently:
if (strpos(strtolower($notnumber), 'e') === false && is_numeric($notnumber))
This makes sure that there isn't an E and that it is also numeric.
Assuming you want to ensure that the string is a valid integer you could use filter_var:
$tests = ['1', '1.1', '1e0', '0x1'];
foreach($tests as $str) {
$int = filter_var($str, FILTER_VALIDATE_INT);
if ($int === false) {
echo $str . ' is not an integer' . PHP_EOL;
} else {
echo $str . ' is an integer' . PHP_EOL;
}
}
Result:
1 is an integer
1.1 is not an integer
1e0 is not an integer
0x1 is not an integer
Let's check the definition:
Finds whether the given variable is numeric. Numeric strings consist
of optional sign, any number of digits, optional decimal part and
optional exponential part. Thus +0123.45e6 is a valid numeric value.
Hexadecimal (e.g. 0xf4c3b00c) and binary (e.g. 0b10100111001) notation
is not allowed.
The relationship with floating point literals is clear but, how does it all relate to integer literals?
Octal notation is considered numeric.
Hexadecimal notation stopped being considered in PHP/7.0.
Binary notation has never been.
Integer overflow is not a direct concern but will lead to precision loss.
The manual doesn't state explicitly what the use cases are but in general it's more a helper tool (to ensure that you can feed stringified data to functions that expect numeric values) than a proper form validator. If input is collected in an environment where 88205052E00 is not expected then it might be a good idea to expect (and generate) localised data and implement a locale-aware solution.

Addition to number formed using number_format() php function

When i try to add a integer to 3 digit number formed using php number_format() function give right result but when number become 4 digit it give wrong output.
I have tried this. please explain me the reason behind this??
$num1=number_format(1000.5,2);
$num1+=1;
echo $num1;
Output:2
But
$num1=number_format(100.5,2);
$num1+=1;
echo $num1."\n";`
Output:101.5
number_format() returns a string not a number. It is there to format a numeric type (integer, float) to a string with a specific, desired "layout". So what you do is add the number 1 to the string resulting from number_format, which will try to cast the string back to a number, apparently resulting in 1 for the string cast as well, which gives you 2 total.
tl;dr; Do calculations on numbers only and then do number_format at the very end to output in a defined format.
$num1 = number_format(1000.5, 2);
var_dump($num1);
// => string(8) "1,000.50"
$num1 += 1;
var_dump($num1);
// => int(2)
Function number_format() returns string.
And that string is type cast to integer when you are adding 1
See Type Juggling
The quickest solution would be using str_replace() on your formatted number.
Something like this would do:
(float)str_replace( ',', '', $formatted_number )
By removing the commas from the string and asking for the float value, you'll get a usable number.

Correct the float values

I read some data from a csv file. Each line in the file has a float value. these values can be either:
.123 : starting with a period, so I need to add a zero before.
1,23: having a delimter comma ',' instead of period so I need to change that.
1.2e3 having an exponential-format so I need to convert it to decimal format.
I can't use the function number_format because I can't set the number of decimal points (the float numbers don't have a fixed length of the decimal part and we want to take them as they are to not lose data).
Here is what I tried so far; I built two functions, the first one filters the floats, the second one corrects them when the filter returns false:
function validateFloat($float){
if(!filter_var($float,FILTER_VALIDATE_FLOAT,array('flags' => FILTER_FLAG_ALLOW_FRACTION))){
return false;
}
}
function correctFloat($float){
if (validateFloat($float)==false){
$number = number_format($float,null,'.');
str_replace($number,'',$line);
}
}
I don't know how to build the correctFloat function. Any suggestions ? Appreciate it.
Your function can check if there is a comma and get the correct deliminator then use floarval on any other case
function change_format($value){
if(is_string($value)){
//has to be a string if using ','
$value= str_replace(",",".",$value);
}
return floatval($value);
}
echo change_format(.123) ."<br>";
echo change_format("1,23") ."<br>";
echo change_format("1.2e3");
Outputs:
0.123
1.23
1200

php compare 01 to 1 from datetime object

DateTime object outputs 01, 02, 03 etc when I
use
$num = $dt->format('d');
to get the day number
Then I compare the $num value if it's
the first day of the month like so:
if ($num == 1)
but the $num value is '01'.
Now php compares it as expected
var_dump($num == 1)
returns true
I was thinking, should this be enough for me
or I should enclose the $num variable with an intval
like so:
intval($num)
this way if it is 01 it will display '1'
Basically $num = $dt->format('d') returns a String.
If you have == as a Comparison Operators and the two values are not from the same data type, PHP try to match them.
So in your case ($num == 1) you are comparing a String with a literal Integer
Therefore PHP is trying to converting the Sting into a Integer (only for the comparison).In the end you are already comparing two Integers.
The type conversion does not take place when the Comparison Operator is === or !== as this involves comparing the type as well as the value.So with $num = '1';, a comparison like $num === 1 would always return false.If you like to strip of leading zeros but don't convert the data type, I would use: $num_as_str = ltrim($num,'0');
If you like to convert the variable to an Integer use this:
$num_as_int = intval($num);
From the PHP manual:
String conversion to numbers
When a string is evaluated in a numeric context, the resulting value and type are determined as follows.
The string will be evaluated as a float if it contains any of the characters '.', 'e', or 'E'. Otherwise it will be evaluated as an integer.
The value is given by the initial portion of the string. If the string starts with valid numeric data, this will be the value used. Otherwise, the value will be 0 (zero). Valid numeric data is an optional sign, followed by one or more digits (optionally containing a decimal point), followed by an optional exponent. The exponent is an 'e' or 'E' followed by one or more digits.
Everything written by Webdesigner is right, but you can simply get the day number without leading zero by 'j' parameter:
$num = $dt->format('j');
So you can compare it with an ordinary numbers without any explicit type cast.

string being treated as a number when using if statement

i am using an if statement to compare 2 variables against each other, mainly in this case barcodes. i have noticed if they are leading with zeros and the only difference is one variable as more zeros at the beginning and the rest is the same its giving a true result as if they are the same, which in INT/NUMBER format that would be true, however i have checked and both are strings, so cant get my head around why it thinks "000005" and "0000005" are the same when they are not.
echo "<pre>";
$params['barcode_new'] = "0000005";
$params['barcode_old'] = "000005";
echo "var type : " .gettype($params['barcode_new']) ."<br>";
if ($params['barcode_old'] == $params['barcode_new']) {
echo "Master barcode already set to {$params['barcode_new']} <br>";
print_r($params);
}
Strings will be compared per character. Numbers by their value. So the strings differ and numbers will be equal. For type correctness use === to check if the values are identical and == if they are equal (e.g. numbers)
<?php
var_dump("0000005" == "000005");
var_dump("0000005" === "000005");
?>
bool(true)
bool(false)
Use Identical === operator instead. With === it will not convert the values and will match for the exact. Try with -
if ($params['barcode_old'] === $params['barcode_new']) {
If you compare a number with a string or the comparison involves numerical strings, then each string is converted to a number and the comparison performed numerically. These rules also apply to the switch statement. The type conversion does not take place when the comparison is === or !== as this involves comparing the type as well as the value.

Categories