2009-09-08 7 views

Répondre

3

est ici un moyen de vérifier les débordements (qui est en fait juste à virgule flottante + Infinity et -Infinity):

#!perl -w 
use strict; 

my $x = 10 ** 200; 
my $positive_overflow = $x * $x; 
my $negative_overflow = -$x * $x; 

print is_infinity($positive_overflow) ? 'true' : 'false'; 
print "\n"; 
print is_infinity($negative_overflow) ? 'true' : 'false'; 
print "\n"; 

sub is_infinity 
{ 
    my $x = shift; 
    return $x =~ /inf/i; 
} 

division par zéro est difficile parce que vous ne pouvez pas effectuer réellement la division dans la portée du programme normal sans le faire mourir sur vous. Vous pouvez envelopper dans eval si:

#!perl -w 
use strict; 

my $x = 100; 
my $y = 0; 

my $q = try_divide($x, $y); 
print "Might be division by zero...\n" if !defined $q; 

$y = 10; 
$q = try_divide($x, $y); 
print "$q\n"; 

sub try_divide 
{ 
    my $x = shift; 
    my $y = shift; 
    my $q; 

    eval { $q = $x/$y }; 

    return $q; 
} 
+2

L'infini négatif est un débordement et non un débordement. Un sous-flux est quelque chose de très différent: http://en.wikipedia.org/wiki/Arithmetic_underflow – ysth

+0

En outre, la chose 1. # INF est une perversion de Microsoft. La norme POSIX dit: «une infinité doit être convertie dans l'un des styles» [-] inf "ou" [-] infinity "; quel style est défini par l'implémentation. ' Donc/inf/i serait un meilleur test. – ysth

+0

Merci, j'ai corrigé ma réponse. – bobbymcr

1

Si votre dividende est non nul et votre quotient (résultat) est égal à zéro, vous avez eu un dépassement. Si votre résultat est différent de zéro, le dépassement de capacité peut être vérifié en trouvant le nombre le plus proche de 1 et en multipliant votre non-résultat par celui-ci et en vérifiant s'il change; s'il s'agissait d'un résultat inférieur à la normale, il demeurera inchangé, car il ne comportera pas toute la précision qu'un résultat normal aurait.

my $underflow_checker; 
for (my $i = 1; 1 + $i > 1; $i /= 2) { $underflow_checker = 1 + $i } 
... 
$x = 2**-520; 
$y = 2**520; 
$result = $x/$y; 
if ($result == 0 && $x != 0 || $result != 0 && $result * $underflow_checker == $result) { print "Underflow!\n" } 
+0

Merci à vous tous qui avez essayé de m'aider .... –