Как мне создать или протестировать NaN или infinity в Perl?

StackOverflow https://stackoverflow.com/questions/1185822

  •  19-09-2019
  •  | 
  •  

Вопрос

Как мне создать или протестировать NaN или бесконечные значения в Perl?

Это было полезно?

Решение 2

Вот довольно надежный способ:

my $inf    = 9**9**9;
my $neginf = -9**9**9;
my $nan    = -sin(9**9**9);

sub isinf { $_[0]==9**9**9 || $_[0]==-9**9**9 }
sub isnan { ! defined( $_[0] <=> 9**9**9 ) }
# useful for detecting negative zero
sub signbit { substr( sprintf( '%g', $_[0] ), 0, 1 ) eq '-' }

for my $num ( $inf, $neginf, $nan ) {
   printf("%s:\tisinf: %d,\tisnan: %d,\tsignbit: %d\n", $num, isinf($num), isnan($num), signbit($num));
}

Результат равен:

inf:    isinf: 1,   isnan: 0,   signbit: 0
-inf:   isinf: 1,   isnan: 0,   signbit: 1
nan:    isinf: 0,   isnan: 1,   signbit: 0

Другие советы

print "Is NaN\n" if $a eq 'nan';
print "Is Inf\n" if $a eq 'inf' or $a eq '-inf';

Редактировать:Исправлено для отрицательной бесконечности.

Использование Данные::С плавающей точкой из CPAN.Он экспортирует следующие функции:

  • float_is_infinite()
  • float_is_nan()
  • ...

И в отличие от других полурабочих решений, размещенных здесь, у него есть тестовый набор.

Лично я бы использовал Math::BigFloat (или BigInt) для всего , что соприкасается с бесконечностью NaN.

Зачем изобретать велосипед с помощью хакерского решения, когда уже есть модули, которые выполняют эту работу?

Когда я искал, я нашел этот сайт (здесь) и http://www.learning-perl.com/2015/05/perls-special-not-a-numbers/

В связанной статье указывается, что "nan" == "nan" никогда не является истинным, когда базовая реализация c поддерживает NaN, потому что Nan не может соответствовать самому себе.

Это прекрасно иллюстрируется

die "This perl does not support NaN!\n" if "NaN" == "NaN";

Я предполагаю, что риск запуска вашего кода в среде, где perl изящно деградировал, а ваш код - нет, может быть достаточно низким, чтобы вы не слишком беспокоились.

И, конечно, если вы не хотите, чтобы perl интерполировал как число, используйте 'eq', а не '=='

Ниже приводится краткий ответ, который работает.

1:Как создать переменную "NAN" для вывода (например, в printf):

 {no strict 'subs'; $NAN="NAN"+1;}

2:Как протестировать "NAN" (выглядит как ascii-изображение):

 sub isnan {!($_[0]<=0||$_[0]>=0)}

3:Как создать переменные "INF" и INFN:

{$INF="INF"+1; $INFN=-"INF"+1}

4:Как проверить наличие "INF" (любого знака):

sub isinf {($_[0]==+"INF")||($_[0]==-"INF")}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top