¿Cómo puedo convertir una cadena en un número en Perl?

86

Tengo una cadena que contiene un valor decimal y necesito convertir esa cadena en una variable de punto flotante. Entonces, un ejemplo de la cadena que tengo es "5.45" y quiero un equivalente en coma flotante para poder agregarle .1. He buscado en Internet, pero solo veo cómo convertir una cadena en un número entero.

Anton
fuente
La pregunta necesita más detalles. ¿La cadena solo se compone de números? ¿Alfanumérico? ¿Está bien si se eliminan los alfas? ¿Existe un propósito específico para el número resultante?
JGurtz

Respuestas:

90

No es necesario convertirlo en absoluto:

% perl -e 'print "5.45" + 0.1;'
5.55
Alnitak
fuente
26
5.55 no es un número entero
OrangeDog
15
@OrangeDog el OP editó la pregunta (algunos meses después de que se publicara esta respuesta): la pregunta original en realidad tenía números de punto flotante.
Alnitak
1
¿Qué pasa con las comparaciones cuando la cadena tiene una coma?
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

Esta es una solución simple:

Ejemplo 1

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

Resultado

123

Ejemplo 2

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

Resultado

0
porquero
fuente
7
AFAIU esta es la única respuesta a lo que se preguntó
Puma
4
Tenga cuidado al agregar cero a una cadena. Si la cadena comienza con "inf" o con "nan", el valor no será cero. Por ejemplo, my $ var2 = "info123"; print $ var2 + 0: El resultado será: Inf
Rodrigo De Almeida Siqueira
Estaba haciendo una foreach my $i ('00'..'15')y necesitaba eliminar los ceros iniciales en algunos lugares. Este 0+casting a un número también lo logra.
stevesliva
Aparentemente, esto no funciona con cadenas hexadecimales: '0x14C' + 0 resulta en 0 (arrggg)
También
41

Perl es un lenguaje basado en el contexto. No hace su trabajo de acuerdo con los datos que le proporcionas. En cambio, descubre cómo tratar los datos según los operadores que usa y el contexto en el que los usa. Si haces todo tipo de cosas con números, obtienes números:

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

Si haces un tipo de cosas con cadenas, obtienes cadenas:

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

Perl principalmente averigua qué hacer y en general es correcto. Otra forma de decir lo mismo es que Perl se preocupa más por los verbos que por los sustantivos.

¿Estás intentando hacer algo y no funciona?

Brian D Foy
fuente
Perdone mi falta de conocimiento aquí, pero no entiendo su segundo ejemplo. Estás dividiendo dos números y luego multiplicándolos, ¿cómo / por qué resulta en una cadena?
gideon
4
No estoy multiplicando números. El xes el operador de repetición de cadena.
brian d foy
3
¿No debería ser my $string = ( 45/2 ) x 3; # "22.522.522.5"con 45 en lugar de 44? De lo contrario, no entiendo de dónde vienen los '.5 en el resultado ...
Vickster
10

Google me llevó aquí mientras buscaba la misma pregunta que phill hizo (clasificando flotantes), así que pensé que valdría la pena publicar la respuesta a pesar de que el hilo es un poco antiguo. Soy nuevo en perl y todavía estoy pensando en ello, pero la declaración de brian d foy "Perl se preocupa más por los verbos que por los sustantivos". arriba realmente da en el clavo. No es necesario convertir las cadenas en flotantes antes de aplicar la ordenación. Debe indicarle a la ordenación que ordene los valores como números y no como cadenas. es decir

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

Consulte http://perldoc.perl.org/functions/sort.html para obtener más detalles sobre la ordenación

Norma
fuente
8

Según tengo entendido, int () no está destinado a ser una función de 'conversión' para designar el tipo de datos, simplemente se usa (ab) aquí para definir el contexto como aritmético. He (ab) usado (0 + $ val) en el pasado para asegurar que $ val sea tratado como un número.

mccutchm
fuente
sí, int()está siendo "(ab) usado"; Entendido.
Sapphire_Brick
6
$var += 0

probablemente lo que quieras. Sin embargo, tenga en cuenta que si $ var es una cadena que no se puede convertir a numérica, obtendrá el error y $ var se restablecerá a 0 :

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

registros

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

Perl realmente solo tiene tres tipos: escalares, matrices y hashes. E incluso esa distinción es discutible. ;) La forma en que se trata cada variable depende de lo que hagas con ella:

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


% perl -e "print '5.4' + '3.4';"
8.8
Rini
fuente
5
Perl tiene muchos más tipos que, pero para valores individuales, es solo un valor único.
Brian D Foy
1

En las comparaciones, hay una diferencia si un escalar es un número de una cadena. Y no siempre es decidible. Puedo informar un caso en el que perl recuperó un flotador en notación "científica" y lo usó unas pocas líneas a continuación en una comparación:

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

Y aquí $valno se interpretó como numérico, por ejemplo, "2e-77"recuperado de $line. Agregar 0 (o 0.0 para los buenos programadores de ole C) ayudó.

Steffen Moeller
fuente
0

Perl tiene un tipo de letra débil y se basa en el contexto. Muchos escalares se pueden tratar como cadenas y números, según los operadores que utilice. $a = 7*6; $b = 7x6; print "$a $b\n";
Usted consigue 42 777777.

Sin embargo, existe una sutil diferencia. Cuando lee datos numéricos de un archivo de texto en una estructura de datos y luego los ve con Data::Dumper, notará que sus números están entrecomillados. Perl los trata internamente como cadenas.
Lea: $my_hash{$1} = $2 if /(.+)=(.+)\n/;.
Tugurio:'foo' => '42'

Si desea que los números no cotizados en un vertedero:
Leer: $my_hash{$1} = $2+0 if /(.+)=(.+)\n/;.
Tugurio:'foo' => 42

Después de que $2+0Perl advierte que ha tratado $ 2 como un número, porque utilizó un operador numérico.

Me di cuenta de esto mientras intentaba comparar dos hashes con Data::Dumper.

SzG
fuente