Bir dizgeyi Perl'de bir sayıya nasıl dönüştürebilirim?


86

İçinde ondalık bir değer tutan bir dizem var ve bu dizeyi bir kayan noktalı değişkene dönüştürmem gerekiyor. Dolayısıyla, sahip olduğum dizeye bir örnek "5.45" ve kayan nokta eşdeğeri istiyorum, böylece ona .1 ekleyebilirim. İnternette arama yaptım, ancak yalnızca bir dizeyi tam sayıya nasıl dönüştüreceğimi görüyorum.


Sorunun daha fazla ayrıntıya ihtiyacı var. Dizi yalnızca rakamlardan mı oluşuyor? Alfasayısal mı? Tamam, alfalar çıkarılırsa? Ortaya çıkan sayı için belirli bir amaç var mı?
JGurtz 01

Yanıtlar:


91

Hiç dönüştürmenize gerek yok:

% perl -e 'print "5.45" + 0.1;'
5.55

15
@OrangeDog OP soruyu düzenledi (bu cevabın gönderilmesinden birkaç ay sonra) - orijinal sorunun içinde gerçekte kayan nokta sayıları vardı.
Alnitak

1
dizede virgül olduğunda karşılaştırmalar ne olacak?
Ramy

[rabdelaz@Linux_Desktop:~/workspace/akatest_5]$perl -e 'print "nope\n" unless "1,000" > 10;' nope [rabdelaz@Linux_Desktop:~/workspace/akatest_5]$perl -e 'print "nope\n" if "1,000" > 10;'
Ramy

73

Bu basit bir çözümdür:

örnek 1

my $var1 = "123abc";
print $var1 + 0;

Sonuç

123

Örnek 2

my $var2 = "abc123";
print $var2 + 0;

Sonuç

0

7
AFAIU sorulanların tek cevabı bu
Cougar

4
Bir dizeye sıfır eklerken dikkatli olun. Dize "inf" veya "nan" ile başlıyorsa, değer sıfır olmayacaktır. Örneğin $ var2 = "info123"; print $ var2 + 0: Sonuç: Inf
Rodrigo De Almeida Siqueira

A yapıyordum foreach my $i ('00'..'15')ve bazı yerlerde baştaki sıfırları kaldırmam gerekiyordu. 0+Bir sayıya bu döküm de bunu başarır.
stevesliva

Görünüşe göre bu, onaltılık dizelerle çalışmıyor: '0x14C' + 0, 0 (arrggg) ile
sonuçlanır

41

Perl, bağlama dayalı bir dildir. Verdiğiniz verilere göre işini yapmaz. Bunun yerine, verileri kullandığınız operatörlere ve bunları kullandığınız bağlama göre nasıl ele alacağınızı belirler. Sayılar gibi şeyler yaparsanız, sayılar elde edersiniz:

# numeric addition with strings:
my $sum = '5.45' + '0.01'; # 5.46

Eğer dizge gibi şeyler yaparsanız, dizeler elde edersiniz:

# string replication with numbers:
my $string = ( 45/2 ) x 4; # "22.522.522.522.5"

Perl çoğunlukla ne yapılacağını anlıyor ve bu çoğunlukla doğru. Aynı şeyi söylemenin başka bir yolu da Perl'in isimlerden çok fiillere önem vermesidir.

Bir şey mi yapmaya çalışıyorsun ve işe yaramıyor mu?


Buradaki bilgisizliğimi affedin ama ikinci örneğinizi tam olarak alamıyorum. İki sayıyı bölüyorsunuz, sonra çarpıyorsunuz, bu nasıl / neden bir dizeyle sonuçlanıyor?
gideon

4
Sayıları çarpmıyorum. xDize çoğaltma operatörüdür.
brian d foy

3
my $string = ( 45/2 ) x 3; # "22.522.522.5"44 yerine 45 olması gerekmez mi? Aksi takdirde sonuçta '
.5'lerin

10

Google, phill'in sorduğu aynı soruyu ararken (kayan sayıları sıralayarak) beni buraya yönlendirdi, bu yüzden iş parçacığı eski olmasına rağmen cevabı göndermeye değer olacağını düşündüm. Perl konusunda yeniyim ve hala kafamı etrafına dolaştırıyorum ama brian d foy'un "Perl isimlerden çok fiilleri önemsiyor." yukarıda gerçekten çivi kafasına çarpıyor. Sıralamayı uygulamadan önce dizeleri kayan sayılara dönüştürmenize gerek yoktur. Sıralamaya, değerleri dizeler olarak değil sayılar olarak sıralaması gerektiğini söylemeniz gerekir. yani

my @foo = ('1.2', '3.4', '2.1', '4.6');
my @foo_sort = sort {$a <=> $b} @foo;

Sıralama hakkında daha fazla ayrıntı için http://perldoc.perl.org/functions/sort.html adresine bakın


8

Anladığım kadarıyla int () , veri tipini belirlemek için bir 'cast' fonksiyonu olarak tasarlanmadı, sadece burada (ab) bağlamı aritmetik olarak tanımlamak için kullanılıyor. Geçmişte $ val'in bir sayı olarak değerlendirilmesini sağlamak için (ab) (0 + $ val) kullandım.


evet, int()"(ab) kullanılıyor"; anladım.
Sapphire_Brick

6
$var += 0

muhtemelen ne istiyorsan. Ancak, $ var is string sayısal değere dönüştürülemezse, hatayı alırsınız ve $ var 0 olarak sıfırlanır :

my $var = 'abc123';
print "var = $var\n";
$var += 0;
print "var = $var\n";

kütükler

var = abc123
Argument "abc123" isn't numeric in addition (+) at test.pl line 7.
var = 0

3

Perl'in gerçekten yalnızca üç türü vardır: skalarlar, diziler ve karmalar. Ve bu ayrım bile tartışılabilir. ;) Her bir değişkenin nasıl ele alınacağı, onunla ne yaptığınıza bağlıdır:

% perl -e "print 5.4 . 3.4;"
5.43.4


% perl -e "print '5.4' + '3.4';"
8.8

5
Perl'den çok daha fazla türü vardır, ancak tek değerler için bu sadece tek bir değerdir.
brian d foy

1

Karşılaştırmalarda, skalerin bir dizi sayısı olması fark yaratır. Ve her zaman karar verilemez. Perl'in "bilimsel" gösterimde bir float elde ettiği ve bir karşılaştırmada aşağıdaki birkaç satırı kullandığı bir durumu rapor edebilirim:

use strict;
....
next unless $line =~ /and your result is:\s*(.*)/;
my $val = $1;
if ($val < 0.001) {
   print "this is small\n";
}

Ve burada $val, örneğin "2e-77"alındığı için sayısal olarak yorumlanmadı $line. 0 (veya iyi ole C programcıları için 0.0) eklemek yardımcı oldu.


0

Perl zayıf yazılmıştır ve içeriğe dayalıdır. Çoğu skaler, kullandığınız işleçlere bağlı olarak hem dizeler hem de sayılar olarak ele alınabilir. $a = 7*6; $b = 7x6; print "$a $b\n";
Sen alırsın 42 777777.

Bununla birlikte, ince bir fark var. Bir metin dosyasındaki sayısal verileri bir veri yapısına okuduğunuzda ve ardından bunu ile görüntülediğinizde Data::Dumper, sayılarınızın alıntı yapıldığını fark edeceksiniz. Perl bunları dahili olarak dizeler olarak ele alır.
Oku: $my_hash{$1} = $2 if /(.+)=(.+)\n/;.
Dökümü:'foo' => '42'

: Eğer çöplükte tırnaksız numaralarını isterseniz
okuyun: $my_hash{$1} = $2+0 if /(.+)=(.+)\n/;.
Dökümü:'foo' => 42

$2+0Perl, 2 $ 'ı bir sayı olarak ele aldığınızı fark ettikten sonra , çünkü sayısal bir operatör kullandınız.

Bunu iki karma ile karşılaştırmaya çalışırken fark ettim Data::Dumper.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.