⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bigint.pm

📁 1. 记录每个帖子的访问人情况
💻 PM
📖 第 1 页 / 共 5 页
字号:
  my $e = int("$$es$$ev");			# exponent (avoid recursion)  if ($e > 0)    {    my $diff = $e - CORE::length($$mfv);    if ($diff < 0)				# Not integer      {      #print "NOI 1\n";      return $upgrade->new($wanted,$a,$p,$r) if defined $upgrade;      $self->{sign} = $nan;      }    else					# diff >= 0      {      # adjust fraction and add it to value      # print "diff > 0 $$miv\n";      $$miv = $$miv . ($$mfv . '0' x $diff);      }    }  else    {    if ($$mfv ne '')				# e <= 0      {      # fraction and negative/zero E => NOI      #print "NOI 2 \$\$mfv '$$mfv'\n";      return $upgrade->new($wanted,$a,$p,$r) if defined $upgrade;      $self->{sign} = $nan;      }    elsif ($e < 0)      {      # xE-y, and empty mfv      #print "xE-y\n";      $e = abs($e);      if ($$miv !~ s/0{$e}$//)		# can strip so many zero's?        {        #print "NOI 3\n";        return $upgrade->new($wanted,$a,$p,$r) if defined $upgrade;        $self->{sign} = $nan;        }      }    }  $self->{sign} = '+' if $$miv eq '0';			# normalize -0 => +0  $self->{value} = $CALC->_new($miv) if $self->{sign} =~ /^[+-]$/;  # if any of the globals is set, use them to round and store them inside $self  # do not round for new($x,undef,undef) since that is used by MBF to signal  # no rounding  $self->round($a,$p,$r) unless @_ == 4 && !defined $a && !defined $p;  $self;  }sub bnan  {  # create a bigint 'NaN', if given a BigInt, set it to 'NaN'  my $self = shift;  $self = $class if !defined $self;  if (!ref($self))    {    my $c = $self; $self = {}; bless $self, $c;    }  $self->import() if $IMPORT == 0;		# make require work  return if $self->modify('bnan');  my $c = ref($self);  if ($self->can('_bnan'))    {    # use subclass to initialize    $self->_bnan();    }  else    {    # otherwise do our own thing    $self->{value} = $CALC->_zero();    }  $self->{sign} = $nan;  delete $self->{_a}; delete $self->{_p};	# rounding NaN is silly  return $self;  }sub binf  {  # create a bigint '+-inf', if given a BigInt, set it to '+-inf'  # the sign is either '+', or if given, used from there  my $self = shift;  my $sign = shift; $sign = '+' if !defined $sign || $sign !~ /^-(inf)?$/;  $self = $class if !defined $self;  if (!ref($self))    {    my $c = $self; $self = {}; bless $self, $c;    }  $self->import() if $IMPORT == 0;		# make require work  return if $self->modify('binf');  my $c = ref($self);  if ($self->can('_binf'))    {    # use subclass to initialize    $self->_binf();    }  else    {    # otherwise do our own thing    $self->{value} = $CALC->_zero();    }  $sign = $sign . 'inf' if $sign !~ /inf$/;	# - => -inf  $self->{sign} = $sign;  ($self->{_a},$self->{_p}) = @_;		# take over requested rounding  return $self;  }sub bzero  {  # create a bigint '+0', if given a BigInt, set it to 0  my $self = shift;  $self = $class if !defined $self;   if (!ref($self))    {    my $c = $self; $self = {}; bless $self, $c;    }  $self->import() if $IMPORT == 0;		# make require work  return if $self->modify('bzero');  if ($self->can('_bzero'))    {    # use subclass to initialize    $self->_bzero();    }  else    {    # otherwise do our own thing    $self->{value} = $CALC->_zero();    }  $self->{sign} = '+';  if (@_ > 0)    {    if (@_ > 3)      {      # call like: $x->bzero($a,$p,$r,$y);      ($self,$self->{_a},$self->{_p}) = $self->_find_round_parameters(@_);      }    else      {      $self->{_a} = $_[0]       if ( (!defined $self->{_a}) || (defined $_[0] && $_[0] > $self->{_a}));      $self->{_p} = $_[1]       if ( (!defined $self->{_p}) || (defined $_[1] && $_[1] > $self->{_p}));      }    }  $self;  }sub bone  {  # create a bigint '+1' (or -1 if given sign '-'),  # if given a BigInt, set it to +1 or -1, respecively  my $self = shift;  my $sign = shift; $sign = '+' if !defined $sign || $sign ne '-';  $self = $class if !defined $self;   if (!ref($self))    {    my $c = $self; $self = {}; bless $self, $c;    }  $self->import() if $IMPORT == 0;		# make require work  return if $self->modify('bone');  if ($self->can('_bone'))    {    # use subclass to initialize    $self->_bone();    }  else    {    # otherwise do our own thing    $self->{value} = $CALC->_one();    }  $self->{sign} = $sign;  if (@_ > 0)    {    if (@_ > 3)      {      # call like: $x->bone($sign,$a,$p,$r,$y);      ($self,$self->{_a},$self->{_p}) = $self->_find_round_parameters(@_);      }    else      {      $self->{_a} = $_[0]       if ( (!defined $self->{_a}) || (defined $_[0] && $_[0] > $self->{_a}));      $self->{_p} = $_[1]       if ( (!defined $self->{_p}) || (defined $_[1] && $_[1] > $self->{_p}));      }    }  $self;  }############################################################################### string conversationsub bsstr  {  # (ref to BFLOAT or num_str ) return num_str  # Convert number from internal format to scientific string format.  # internal format is always normalized (no leading zeros, "-0E0" => "+0E0")  my $x = shift; $class = ref($x) || $x; $x = $class->new(shift) if !ref($x);   # my ($self,$x) = ref($_[0]) ? (ref($_[0]),$_[0]) : objectify(1,@_);   if ($x->{sign} !~ /^[+-]$/)    {    return $x->{sign} unless $x->{sign} eq '+inf';	# -inf, NaN    return 'inf';					# +inf    }  my ($m,$e) = $x->parts();  my $sign = 'e+'; # e can only be positive  return $m->bstr().$sign.$e->bstr();  }sub bstr   {  # make a string from bigint object  my $x = shift; $class = ref($x) || $x; $x = $class->new(shift) if !ref($x);   # my ($self,$x) = ref($_[0]) ? (ref($_[0]),$_[0]) : objectify(1,@_);   if ($x->{sign} !~ /^[+-]$/)    {    return $x->{sign} unless $x->{sign} eq '+inf';	# -inf, NaN    return 'inf';					# +inf    }  my $es = ''; $es = $x->{sign} if $x->{sign} eq '-';  return $es.${$CALC->_str($x->{value})};  }sub numify   {  # Make a "normal" scalar from a BigInt object  my $x = shift; $x = $class->new($x) unless ref $x;  return $x->bstr() if $x->{sign} !~ /^[+-]$/;  my $num = $CALC->_num($x->{value});  return -$num if $x->{sign} eq '-';  $num;  }############################################################################### public stuff (usually prefixed with "b")sub sign  {  # return the sign of the number: +/-/-inf/+inf/NaN  my ($self,$x) = ref($_[0]) ? (ref($_[0]),$_[0]) : objectify(1,@_);     $x->{sign};  }sub _find_round_parameters  {  # After any operation or when calling round(), the result is rounded by  # regarding the A & P from arguments, local parameters, or globals.  # This procedure finds the round parameters, but it is for speed reasons  # duplicated in round. Otherwise, it is tested by the testsuite and used  # by fdiv().    my ($self,$a,$p,$r,@args) = @_;  # $a accuracy, if given by caller  # $p precision, if given by caller  # $r round_mode, if given by caller  # @args all 'other' arguments (0 for unary, 1 for binary ops)  # leave bigfloat parts alone  return ($self) if exists $self->{_f} && $self->{_f} & MB_NEVER_ROUND != 0;  my $c = ref($self);				# find out class of argument(s)  no strict 'refs';  # now pick $a or $p, but only if we have got "arguments"  if (!defined $a)    {    foreach ($self,@args)      {      # take the defined one, or if both defined, the one that is smaller      $a = $_->{_a} if (defined $_->{_a}) && (!defined $a || $_->{_a} < $a);      }    }  if (!defined $p)    {    # even if $a is defined, take $p, to signal error for both defined    foreach ($self,@args)      {      # take the defined one, or if both defined, the one that is bigger      # -2 > -3, and 3 > 2      $p = $_->{_p} if (defined $_->{_p}) && (!defined $p || $_->{_p} > $p);      }    }  # if still none defined, use globals (#2)  $a = ${"$c\::accuracy"} unless defined $a;  $p = ${"$c\::precision"} unless defined $p;   # no rounding today?   return ($self) unless defined $a || defined $p;		# early out  # set A and set P is an fatal error  return ($self->bnan()) if defined $a && defined $p;  $r = ${"$c\::round_mode"} unless defined $r;  die "Unknown round mode '$r'" if $r !~ /^(even|odd|\+inf|\-inf|zero|trunc)$/;   return ($self,$a,$p,$r);  }sub round  {  # Round $self according to given parameters, or given second argument's  # parameters or global defaults   # for speed reasons, _find_round_parameters is embeded here:  my ($self,$a,$p,$r,@args) = @_;  # $a accuracy, if given by caller  # $p precision, if given by caller  # $r round_mode, if given by caller  # @args all 'other' arguments (0 for unary, 1 for binary ops)  # leave bigfloat parts alone  return ($self) if exists $self->{_f} && $self->{_f} & MB_NEVER_ROUND != 0;  my $c = ref($self);				# find out class of argument(s)  no strict 'refs';  # now pick $a or $p, but only if we have got "arguments"  if (!defined $a)    {    foreach ($self,@args)      {      # take the defined one, or if both defined, the one that is smaller      $a = $_->{_a} if (defined $_->{_a}) && (!defined $a || $_->{_a} < $a);      }    }  if (!defined $p)    {    # even if $a is defined, take $p, to signal error for both defined    foreach ($self,@args)      {      # take the defined one, or if both defined, the one that is bigger      # -2 > -3, and 3 > 2      $p = $_->{_p} if (defined $_->{_p}) && (!defined $p || $_->{_p} > $p);      }    }  # if still none defined, use globals (#2)  $a = ${"$c\::accuracy"} unless defined $a;  $p = ${"$c\::precision"} unless defined $p;   # no rounding today?   return $self unless defined $a || defined $p;		# early out  # set A and set P is an fatal error  return $self->bnan() if defined $a && defined $p;  $r = ${"$c\::round_mode"} unless defined $r;  die "Unknown round mode '$r'" if $r !~ /^(even|odd|\+inf|\-inf|zero|trunc)$/;  # now round, by calling either fround or ffround:  if (defined $a)    {    $self->bround($a,$r) if !defined $self->{_a} || $self->{_a} >= $a;    }  else # both can't be undefined due to early out    {    $self->bfround($p,$r) if !defined $self->{_p} || $self->{_p} <= $p;    }  $self->bnorm();			# after round, normalize  }sub bnorm  {   # (numstr or BINT) return BINT  # Normalize number -- no-op here  my ($self,$x) = ref($_[0]) ? (ref($_[0]),$_[0]) : objectify(1,@_);  $x;  }sub babs   {  # (BINT or num_str) return BINT  # make number absolute, or return absolute BINT from string  my ($self,$x) = ref($_[0]) ? (ref($_[0]),$_[0]) : objectify(1,@_);  return $x if $x->modify('babs');  # post-normalized abs for internal use (does nothing for NaN)  $x->{sign} =~ s/^-/+/;  $x;  }sub bneg   {   # (BINT or num_str) return BINT  # negate number or make a negated number from string  my ($self,$x) = ref($_[0]) ? (ref($_[0]),$_[0]) : objectify(1,@_);    return $x if $x->modify('bneg');  # for +0 dont negate (to have always normalized)  $x->{sign} =~ tr/+-/-+/ if !$x->is_zero();	# does nothing for NaN  $x;  }sub bcmp   {  # Compares 2 values.  Returns one of undef, <0, =0, >0. (suitable for sort)  # (BINT or num_str, BINT or num_str) return cond_code    # set up parameters  my ($self,$x,$y) = (ref($_[0]),@_);  # objectify is costly, so avoid it   if ((!ref($_[0])) || (ref($_[0]) ne ref($_[1])))    {    ($self,$x,$y) = objectify(2,@_);    }  return $upgrade->bcmp($x,$y) if defined $upgrade &&    ((!$x->isa($self)) || (!$y->isa($self)));  if (($x->{sign} !~ /^[+-]$/) || ($y->{sign} !~ /^[+-]$/))    {    # handle +-inf and NaN    return undef if (($x->{sign} eq $nan) || ($y->{sign} eq $nan));    return 0 if $x->{sign} eq $y->{sign} && $x->{sign} =~ /^[+-]inf$/;    return +1 if $x->{sign} eq '+inf';    return -1 if $x->{sign} eq '-inf';    return -1 if $y->{sign} eq '+inf';    return +1;    }  # check sign for speed first  return 1 if $x->{sign} eq '+' && $y->{sign} eq '-';	# does also 0 <=> -y  return -1 if $x->{sign} eq '-' && $y->{sign} eq '+';  # does also -x <=> 0   # have same sign, so compare absolute values. Don't make tests for zero here  # because it's actually slower than testin in Calc (especially w/ Pari et al)  # post-normalized compare for internal use (honors signs)  if ($x->{sign} eq '+')     {    # $x and $y both > 0    return $CALC->_acmp($x->{value},$y->{value});    }  # $x && $y both < 0  $CALC->_acmp($y->{value},$x->{value});	# swaped (lib returns 0,1,-1)  }sub bacmp   {  # Compares 2 values, ignoring their signs.   # Returns one of undef, <0, =0, >0. (suitable for sort)  # (BINT, BINT) return cond_code    # set up parameters  my ($self,$x,$y) = (ref($_[0]),@_);  # objectify is costly, so avoid it   if ((!ref($_[0])) || (ref($_[0]) ne ref($_[1])))

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -