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

📄 bigint.pm

📁 视频监控网络部分的协议ddns,的模块的实现代码,请大家大胆指正.
💻 PM
📖 第 1 页 / 共 5 页
字号:
  $scale = ${ $class . '::precision' } unless defined $scale;  $mode = ${ $class . '::round_mode' } unless defined $mode;  if (defined $scale)    {    $scale = $scale->can('numify') ? $scale->numify() : "$scale" if ref($scale);    $scale = int($scale);    }  ($scale,$mode);  }############################################################################### constructorssub copy  {  # if two arguments, the first one is the class to "swallow" subclasses  if (@_ > 1)    {    my  $self = bless {	sign => $_[1]->{sign}, 	value => $CALC->_copy($_[1]->{value}),    }, $_[0] if @_ > 1;    $self->{_a} = $_[1]->{_a} if defined $_[1]->{_a};    $self->{_p} = $_[1]->{_p} if defined $_[1]->{_p};    return $self;    }  my $self = bless {	sign => $_[0]->{sign}, 	value => $CALC->_copy($_[0]->{value}),	}, ref($_[0]);  $self->{_a} = $_[0]->{_a} if defined $_[0]->{_a};  $self->{_p} = $_[0]->{_p} if defined $_[0]->{_p};  $self;  }sub new   {  # create a new BigInt object from a string or another BigInt object.   # see hash keys documented at top  # the argument could be an object, so avoid ||, && etc on it, this would  # cause costly overloaded code to be called. The only allowed ops are  # ref() and defined.  my ($class,$wanted,$a,$p,$r) = @_;   # avoid numify-calls by not using || on $wanted!  return $class->bzero($a,$p) if !defined $wanted;	# default to 0  return $class->copy($wanted,$a,$p,$r)   if ref($wanted) && $wanted->isa($class);		# MBI or subclass  $class->import() if $IMPORT == 0;		# make require work    my $self = bless {}, $class;  # shortcut for "normal" numbers  if ((!ref $wanted) && ($wanted =~ /^([+-]?)[1-9][0-9]*\z/))    {    $self->{sign} = $1 || '+';    if ($wanted =~ /^[+-]/)     {      # remove sign without touching wanted to make it work with constants      my $t = $wanted; $t =~ s/^[+-]//;      $self->{value} = $CALC->_new($t);      }    else      {      $self->{value} = $CALC->_new($wanted);      }    no strict 'refs';    if ( (defined $a) || (defined $p)         || (defined ${"${class}::precision"})        || (defined ${"${class}::accuracy"})        )      {      $self->round($a,$p,$r) unless (@_ == 4 && !defined $a && !defined $p);      }    return $self;    }  # handle '+inf', '-inf' first  if ($wanted =~ /^[+-]?inf\z/)    {    $self->{sign} = $wanted;		# set a default sign for bstr()    return $self->binf($wanted);    }  # split str in m mantissa, e exponent, i integer, f fraction, v value, s sign  my ($mis,$miv,$mfv,$es,$ev) = _split($wanted);  if (!ref $mis)    {    if ($_trap_nan)      {      require Carp; Carp::croak("$wanted is not a number in $class");      }    $self->{value} = $CALC->_zero();    $self->{sign} = $nan;    return $self;    }  if (!ref $miv)    {    # _from_hex or _from_bin    $self->{value} = $mis->{value};    $self->{sign} = $mis->{sign};    return $self;	# throw away $mis    }  # make integer from mantissa by adjusting exp, then convert to bigint  $self->{sign} = $$mis;			# store sign  $self->{value} = $CALC->_zero();		# for all the NaN cases  my $e = int("$$es$$ev");			# exponent (avoid recursion)  if ($e > 0)    {    my $diff = $e - CORE::length($$mfv);    if ($diff < 0)				# Not integer      {      if ($_trap_nan)        {        require Carp; Carp::croak("$wanted not an integer in $class");        }      #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      if ($_trap_nan)        {        require Carp; Carp::croak("$wanted not an integer in $class");        }      #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?        {        if ($_trap_nan)          {          require Carp; Carp::croak("$wanted not an integer in $class");          }        #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;    }  no strict 'refs';  if (${"${class}::_trap_nan"})    {    require Carp;    Carp::croak ("Tried to set $self to NaN in $class\::bnan()");    }  $self->import() if $IMPORT == 0;		# make require work  return if $self->modify('bnan');  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  $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;    }  no strict 'refs';  if (${"${class}::_trap_inf"})    {    require Carp;    Carp::croak ("Tried to set $self to +-inf in $class\::binf()");    }  $self->import() if $IMPORT == 0;		# make require work  return if $self->modify('binf');  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  $self;  }sub bzero  {  # create a bigint '+0', if given a BigInt, set it to 0  my $self = shift;  $self = __PACKAGE__ 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, respectively  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      {      # call like: $x->bone($sign,$a,$p,$r);      $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 ($self,$x) = ref($_[0]) ? (undef,$_[0]) : objectify(1,@_);   if ($x->{sign} !~ /^[+-]$/)    {    return $x->{sign} unless $x->{sign} eq '+inf';	# -inf, NaN    return 'inf';					# +inf    }  my ($m,$e) = $x->parts();  #$m->bstr() . 'e+' . $e->bstr(); 	# e can only be positive in BigInt  # 'e+' because E can only be positive in BigInt  $m->bstr() . 'e+' . $CALC->_str($e->{value});   }sub bstr   {  # make a string from bigint object  my ($self,$x) = ref($_[0]) ? (undef,$_[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 '-';  $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]) ? (undef,$_[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.  # !!!!!!! If you change this, remember to change round(), too! !!!!!!!!!!  # 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().   # returns ($self) or ($self,$a,$p,$r) - sets $self to NaN of both A and P  # were requested/defined (locally or globally or both)    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)  my $c = ref($self);				# find out class of argument(s)  no strict 'refs';  # convert to normal scalar for speed and correctness in inner parts  $a = $a->can('numify') ? $a->numify() : "$a" if defined $a && ref($a);  $p = $p->can('numify') ? $p->numify() : "$p" if defined $p && ref($p);  # 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;  # A == 0 is useless, so undef it to signal no rounding  $a = undef if defined $a && $a == 0;   # 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;		# error  $r = ${"$c\::round_mode"} unless defined $r;  if ($r !~ /^(even|odd|\+inf|\-inf|zero|trunc|common)$/)    {    require Carp; Carp::croak ("Unknown round mode '$r'");    }  $a = int($a) if defined $a;  $p = int($p) if defined $p;  ($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)  my $c = ref($self);				# find out class of argument(s)

⌨️ 快捷键说明

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