Pertanyaan Bagaimana saya tahu apakah suatu variabel memiliki nilai numerik dalam Perl?


Apakah ada cara sederhana dalam Perl yang akan memungkinkan saya untuk menentukan apakah suatu variabel yang diberikan adalah numerik? Sesuatu di sepanjang baris:

if (is_number($x))
{ ... }

akan menjadi ideal. Suatu teknik yang tidak akan memberikan peringatan ketika -w sakelar yang digunakan tentu lebih disukai.


75
2017-08-15 19:43


asal


Jawaban:


Menggunakan Scalar::Util::looks_like_number() yang menggunakan fungsi tampak_s_like_number () dari Perl C API internal, yang mungkin merupakan cara paling efisien untuk melakukan ini. Perhatikan bahwa string "inf" dan "infinity" diperlakukan sebagai angka.

Contoh:

#!/usr/bin/perl

use warnings;
use strict;

use Scalar::Util qw(looks_like_number);

my @exprs = qw(1 5.25 0.001 1.3e8 foo bar 1dd inf infinity);

foreach my $expr (@exprs) {
    print "$expr is", looks_like_number($expr) ? '' : ' not', " a number\n";
}

Memberikan hasil ini:

1 is a number
5.25 is a number
0.001 is a number
1.3e8 is a number
foo is not a number
bar is not a number
1dd is not a number
inf is a number
infinity is a number

Lihat juga:

[perldoc Scalar::Util][1]
[perldoc perlapi][2] 

114
2017-08-26 16:53



Lihat modul CPAN Regexp :: Umum. Saya pikir itu persis apa yang Anda butuhkan dan menangani semua kasus tepi (misalnya bilangan real, notasi ilmiah, dll). misalnya

use Regexp::Common;
if ($var =~ /$RE{num}{real}/) { print q{a number}; }

23
2017-08-15 21:01



Pertanyaan aslinya adalah bagaimana mengetahui apakah suatu variabel bersifat numerik, tidak jika itu "memiliki nilai numerik".

Ada beberapa operator yang memiliki mode operasi terpisah untuk operan numerik dan string, di mana "numerik" berarti apa saja yang semula merupakan angka atau pernah digunakan dalam konteks numerik (misalnya di $x = "123"; 0+$x, sebelum penambahan, $x adalah string, setelah itu dianggap numerik).

Satu cara untuk mengetahui ini:

if ( length( do { no warnings "numeric"; $x & "" } ) ) {
    print "$x is numeric\n";
}

20
2017-09-27 17:16



Jawaban sederhana (dan mungkin sederhananya) untuk pertanyaan itu adalah isi dari $x numerik adalah sebagai berikut:

if ($x  eq  $x+0) { .... }

Itu adalah perbandingan tekstual dari aslinya $x dengan $x dikonversi ke nilai numerik.


8
2017-10-17 15:10



Biasanya validasi nomor dilakukan dengan ekspresi reguler. Kode ini akan menentukan apakah sesuatu itu numerik serta memeriksa variabel yang tidak terdefinisi agar tidak membuang peringatan:

sub is_integer {
   defined $_[0] && $_[0] =~ /^[+-]?\d+$/;
}

sub is_float {
   defined $_[0] && $_[0] =~ /^[+-]?\d+(\.\d+)?$/;
}

Ini beberapa bahan bacaan Anda harus melihat.


7
2017-08-15 19:58



Tidak sempurna, tetapi Anda dapat menggunakan regex:

sub isnumber 
{
    shift =~ /^-?\d+\.?\d*$/;
}

3
2017-08-15 19:49



Saya tidak percaya ada sesuatu yang dibangun untuk melakukannya. Untuk lebih dari yang Anda ingin lihat pada subjek, lihat Perlmonks tentang Mendeteksi Numeric


3
2017-08-15 20:44



Regex yang sedikit lebih kuat dapat ditemukan di Regexp :: Umum.

Kedengarannya seperti Anda ingin tahu apakah Perl mengira suatu variabel adalah numerik. Inilah fungsi yang menjebak peringatan itu:

sub is_number{
  my $n = shift;
  my $ret = 1;
  $SIG{"__WARN__"} = sub {$ret = 0};
  eval { my $x = $n + 1 };
  return $ret
}

Pilihan lain adalah untuk mematikan peringatan secara lokal:

{
  no warnings "numeric"; # Ignore "isn't numeric" warning
  ...                    # Use a variable that might not be numeric
}

Perhatikan bahwa variabel non-numerik akan dikonversi secara diam-diam menjadi 0, yang mungkin adalah apa yang Anda inginkan.


2
2017-08-15 20:56



rexep tidak sempurna ... ini adalah:

use Try::Tiny;

sub is_numeric {
  my ($x) = @_;
  my $numeric = 1;
  try {
    use warnings FATAL => qw/numeric/;
    0 + $x;
  }
  catch {
    $numeric = 0;
  };
  return $numeric;
}

2
2017-12-10 18:58