Frage

Betrachten Sie den folgenden Code ein, und sein Ausgang:

Code

#!/usr/bin/perl -w
use strict;
use Data::Dumper;
my $HOURS_PER_DAY = 24.0 * 1.0;
my $BSA = 1.7 * 1.0;
my $MCG_PER_MG = 1000.0 * 1.0;
my $HOURS_DURATION    = 20.0 * $HOURS_PER_DAY;
my $dummy = $HOURS_PER_DAY * $BSA * $MCG_PER_MG * $HOURS_DURATION;
print Dumper($HOURS_PER_DAY);
print Dumper( $BSA);
print Dumper( $MCG_PER_MG);
print Dumper( $HOURS_DURATION );

Output

$VAR1 = 24;
$VAR1 = '1.7';
$VAR1 = 1000;
$VAR1 = 480;

Wie Sie sehen können, ist die zweite Variable als Strings behandelt, während die ersten und die viert diejenigen als Zahlen behandelt werden. Jeder hat eine Vorstellung davon, was die zugrunde liegende Logik ist?

Bearbeiten arithmetische Berechnungen, die hinzugefügt wurden nicht vollständig das Problem lösen (siehe $ BSA Variable).


$ perl -v

This is perl, v5.10.0 built for cygwin-thread-multi-64int
(with 6 registered patches, see perl -V for more detail)

Copyright 1987-2007, Larry Wall
War es hilfreich?

Lösung

Data :: Dumper Aufgabe ist es Daten serialisiert werden und man kann nicht viel sagen über das, was Perl intern mit den Daten auf seinem Ausgang auf Basis tun. Die Devel :: Peek Modul kann Dump die zugrunde liegenden Fahnen und in den Variablen gespeicherten Werte. Die Devel :: Peek POD erklärt die Bedeutung der Fahnen.

#!/usr/bin/perl

use warnings;
use strict;
use Devel::Peek;

my $HOURS_PER_DAY = 24.0 * 1.0;
my $BSA = 1.7 * 1.0;
my $MCG_PER_MG = 1000.0 * 1.0;
my $HOURS_DURATION    = 20.0 * $HOURS_PER_DAY;
my $dummy = $HOURS_PER_DAY * $BSA * $MCG_PER_MG * $HOURS_DURATION;

Dump($HOURS_PER_DAY);
Dump($BSA);
Dump($MCG_PER_MG);
Dump($HOURS_DURATION);

__END__
SV = PVNV(0xd71ff0) at 0xd87f90
  REFCNT = 1
  FLAGS = (PADBUSY,PADMY,IOK,NOK,pIOK,pNOK)
  IV = 24
  NV = 24
  PV = 0
SV = PVNV(0xd71fc8) at 0xd87f60
  REFCNT = 1
  FLAGS = (PADBUSY,PADMY,NOK,pIOK,pNOK)
  IV = 1
  NV = 1.7
  PV = 0
SV = PVNV(0xd72040) at 0xd87f40
  REFCNT = 1
  FLAGS = (PADBUSY,PADMY,IOK,NOK,pIOK,pNOK)
  IV = 1000
  NV = 1000
  PV = 0
SV = IV(0xd8b408) at 0xd87f30
  REFCNT = 1
  FLAGS = (PADBUSY,PADMY,IOK,pIOK)
  IV = 480
# compare the above output to output without the assignment to $dummy:
SV = IV(0x7b0eb8) at 0x7adf90
  REFCNT = 1
  FLAGS = (PADBUSY,PADMY,IOK,pIOK)
  IV = 24
SV = NV(0x7c7c90) at 0x7adf60
  REFCNT = 1
  FLAGS = (PADBUSY,PADMY,NOK,pNOK)
  NV = 1.7
SV = IV(0x7b13d8) at 0x7adf40
  REFCNT = 1
  FLAGS = (PADBUSY,PADMY,IOK,pIOK)
  IV = 1000
SV = IV(0x7b1408) at 0x7adf30
  REFCNT = 1
  FLAGS = (PADBUSY,PADMY,IOK,pIOK)
  IV = 480

Andere Tipps

Ihr gesamtes Konzept der Perl-Variablen als Strings oder Zahlen Behandlung ist fehlerhaft. Perl wird Ihre Variablen die richtige Art und Weise zu behandeln, wenn Sie es brauchen beispielsweise arithmetische Operatoren immer , um ihre Argumentation als Zahlen behandeln (vorausgesetzt, Sie missbrauchen Bediener nicht oder so eine Überlastung).

Sie sollten sich keine Sorgen darüber. Perl weiß, was es tut,

Data :: Dumper ist ein einfaches Muster auf der String-Darstellung der Variablen, um festzustellen, ob es eine Zahl ist. Aus dem Quellcode:

...
elsif ($val =~ /^(?:0|-?[1-9]\d{0,8})\z/) { # safe decimal number
  $out .= $val;
}
else {               # string
...

Dies gilt nicht Zahlen überein, die eine Dezimalstelle, die das Verhalten erklären Sie beobachtet.

Schnell schmutzige Art und Weise einen numerischen Kontext zu erzwingen:

print Dumper( $HOURS_DURATION + 0.0 );

Wenn Ihr Anliegen ist, wie die Daten dann angezeigt werden, die saubere Art und Weise ist: -

printf "%5.2d",$HOURS_DURATION;
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top