אופרטורי השוואה מספרית#
שבעה אופרטורים שמשווים שני מספרים ומחזירים או בוליאני (ששת הראשונים) או תוצאה תלת־כיוונית (<=>).
אופרטור | שאלה | מחזיר |
|---|---|---|
| קטן מ | אמת / שקר |
| קטן או שווה | אמת / שקר |
| שווה | אמת / שקר |
| גדול או שווה | אמת / שקר |
| גדול מ | אמת / שקר |
| לא שווה | אמת / שקר |
| תלת־כיווני (sort) |
|
כל השבעה כופים את שני האופרנדים למספרים לפני ההשוואה.
$age >= 18 # true if 18 or older
$count == 0 # true if numerically zero
$x != $y # true if they differ numerically
$a <=> $b # -1 if $a < $b, 0 if equal, +1 if $a > $b
== הוא למספרים, eq הוא למחרוזות#
זהו הבאג הנפוץ ביותר שמתכנתי Perl חדשים מפיצים. == משווה מספרית - שני האופרנדים עוברים כפיית מספר, וכל מחרוזת לא־מספרית הופכת ל־0:
"foo" == "bar" # TRUE -- both coerce to 0
"42x" == "42y" # TRUE -- both coerce to 42
"1e2" == 100 # TRUE -- "1e2" is 100 in scientific notation
לשוויון מחרוזות, השתמשו ב־eq:
"foo" eq "bar" # FALSE -- the actual question
"42x" eq "42y" # FALSE
אם use warnings בתחום, האזהרה Argument "..." isn't numeric נורית בכל פעם ש־== (או כל אופרטור מספרי אחר) רואה מחרוזת לא־מספרית. אזהרה זו היא ידידתכם.
<=> - אופרטור החללית#
<=> מחזיר -1 אם השמאלי קטן יותר, 0 אם שווים, +1 אם גדול יותר. הוא המשווה למיון:
my @sorted = sort { $a <=> $b } @numbers; # ascending
my @rev = sort { $b <=> $a } @numbers; # descending
# multi-key: by length, ties broken by content
my @lines = sort { length($a) <=> length($b) || $a cmp $b } @raw;
התבנית cmp1 || cmp2 || cmp3 עובדת משום ש־<=> מחזיר 0 בתיקו ו־|| נופל הלאה על 0. ראו לוגיקה.
<=> ו־cmp הם שני האופרטורים היחידים במשפחה זו שאינם בוליאניים - הם בעלי ערך שלם וקיימים לצורך מיון, לא לתנאי if.
שוויון נקודה צפה#
== על מספרי נקודה צפה הוא שוויון מדויק ביט־לביט. עבור ערכים המיוצרים מאריתמטיקה של נקודה צפה זה כמעט לעולם אינו מה שאתם רוצים:
0.1 + 0.2 == 0.3 # FALSE -- 0.30000000000000004
השוו עם סבילות:
abs($a - $b) < 1e-9 # absolute tolerance
abs($a - $b) < 1e-9 * abs($a) # relative tolerance, when $a ≠ 0
abs הוא אופרטור אונרי־בעל־שם.
שרשור אינו קסם#
Perl אינו תומך בשרשור מתמטי של השוואות. $a < $b < $c אינו בודק ״$b נמצא בין $a ל־$c״ - הוא מפוענח כ־($a < $b) < $c, שבו ההשוואה הראשונה מניבה בוליאני ("" או 1) שאז מושווה מספרית עם $c:
1 < 5 < 3 # parses as (1 < 5) < 3
# = 1 < 3
# = TRUE -- which is *not* what you meant.
כתבו את הקוניונקציה במפורש:
$a < $b && $b < $c # the actual "between" test
קדימות#
אופרטורי ההשוואה יושבים בשורה 11 בטבלת הקדימות - רופפים יותר מהאופרטורים האריתמטיים (כך ש־$a + $b == $c + $d עובד), הדוקים יותר מהאופרטורים הלוגיים (כך ש־$a < $b && $c > $d עובד). הם לא־אסוציאטיביים: $a < $b < $c אינו פסול, אך אזהרת אי־האסוציאטיביות שהוסברה לעיל חלה.
ראו גם#
השוואת מחרוזות -
eq ne lt le gt ge cmp, משפחת הסדר הלקסיקלי.אופרטורים לוגיים - שילוב תוצאות השוואה.
<=>ב־sort - מקרה השימוש הקנוני.Boolean Logic for Perl Programmers
the ”two flavours of comparison“ overview that motivates the numeric/string split.
מספרים ומחרוזות - מתי סקלר נכפה למספר, וסיפור הדיוק/Inf/NaN שמאחורי
==.