Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Perl compare operators and stringified "numbers"

I've been working a lot lately with perl, still I dont really know how <,>,>=,=<, ne,gt, etc.. on stringified "numbers", by "number" I mean something like: '1.4.5.6.7.8.0'

correct me If I'm wrong, the following returns true:

if ('1.4.5' > '8.7.8');

because both will be coerced to true (not an empty string). but, how does ne,gt,etc string operators work on such numbers?

basically I'm trying to compare version numbers consisted of the following form:

1.3.4.0.2

I can make a numerical comparison of each digit, but before, I ranther want to know of the string comparing operators perform on such strings.

Thanks,

like image 265
snoofkin Avatar asked Mar 30 '12 11:03

snoofkin


People also ask

How do I compare numbers in Perl?

To see if two numeric values are greater than or equal to each other, we use the comparison operator >=. To see if two string values are greater than or equal to each other, we use the comparison operator ge (Greater-than Equal-to).

Is it faster to compare strings or numbers?

Normally it is faster to compare two integers than two strings. This is particularly true if the length of the string is variable. Integers can generally be compared by using a fast single machine instruction with integers either in memory or registers.

What is == in Perl?

"== does a numeric comparison: it converts both arguments to a number and then compares them."

Which is comparison operator in Perl?

There are two types of sets of Perl comparison operators. Explanations for above Numeric and String Scalars Comparison Operators: == and eq: This operator is used to check the equality.


3 Answers

First: Please use warnings all the time. You would have realized the following at once:

$ perl -wle 'print 1 unless "1.4.5" > "8.7.8"'
Argument "8.7.8" isn't numeric in numeric gt (>) at -e line 1.
Argument "1.4.5" isn't numeric in numeric gt (>) at -e line 1.

Perl v5.9.0 came distributed with version. And this module makes it very easy to compare version numbers:

use warnings;
use version;

my ($small, $large) =  (version->parse('1.4.5'), version->parse('8.7.8'));

print "larger\n"    if $small > $large;
print "smaller\n"   if $small < $large;
like image 101
Sebastian Stumpf Avatar answered Oct 17 '22 05:10

Sebastian Stumpf


A string comparison will only work if every number between the dots has the same length. A string comparison has no knowledge of number and will begin to compare dots and digits (as they are both characters in a string).

There a CPAN module that does exactly what you are looking for: Sort::Versions

like image 8
Matteo Avatar answered Oct 17 '22 05:10

Matteo


When you compare strings using numerical relation operators <, >, etc., Perl issues a warning if you use warnings. However, Perl will still attempt to convert the strings into numbers. If the string starts with digits, Perl will use these, otherwise the string equates to 0. In your example comparing '1.4.5' and '8.7.8' has the same effect as comparing numbers 1.4 and 8.7.

But for ne, gt, etc. it really doesn't matter if your strings consist of numbers or anything else (including dots). Therefore:

print "greater" if '2.3.4' gt '10.1.2'  # prints 'greater' because '2' > '1' stringwise 
print "greater" if '02.3.4' gt '10.1.2' # prints nothing because '0' < '1' stringwise

Therefore you cannot use neither >, <, etc. nor gt, lt, etc. for version comparison, you have to choose different approach, as proposed in another answers, for example.

like image 3
Igor Korkhov Avatar answered Oct 17 '22 06:10

Igor Korkhov