[ Index ]

PHP Cross Reference of Unnamed Project

title

Body

[close]

/se3-unattended/var/se3/unattended/install/linuxaux/opt/perl/lib/5.10.0/Math/BigInt/ -> CalcEmu.pm (source)

   1  package Math::BigInt::CalcEmu;
   2  
   3  use 5.006002;
   4  use strict;
   5  # use warnings;    # dont use warnings for older Perls
   6  use vars qw/$VERSION/;
   7  
   8  $VERSION = '0.05';
   9  
  10  package Math::BigInt;
  11  
  12  # See SYNOPSIS below.
  13  
  14  my $CALC_EMU;
  15  
  16  BEGIN
  17    {
  18    $CALC_EMU = Math::BigInt->config()->{'lib'};
  19    # register us with MBI to get notified of future lib changes
  20    Math::BigInt::_register_callback( __PACKAGE__, sub { $CALC_EMU = $_[0]; } );
  21    }
  22  
  23  sub __emu_band
  24    {
  25    my ($self,$x,$y,$sx,$sy,@r) = @_;
  26  
  27    return $x->bzero(@r) if $y->is_zero() || $x->is_zero();
  28    
  29    my $sign = 0;                    # sign of result
  30    $sign = 1 if $sx == -1 && $sy == -1;
  31  
  32    my ($bx,$by);
  33  
  34    if ($sx == -1)                # if x is negative
  35      {
  36      # two's complement: inc and flip all "bits" in $bx
  37      $bx = $x->binc()->as_hex();            # -1 => 0, -2 => 1, -3 => 2 etc
  38      $bx =~ s/-?0x//;
  39      $bx =~ tr/0123456789abcdef/\x0f\x0e\x0d\x0c\x0b\x0a\x09\x08\x07\x06\x05\x04\x03\x02\x01\x00/;
  40      }
  41    else
  42      {
  43      $bx = $x->as_hex();                # get binary representation
  44      $bx =~ s/-?0x//;
  45      $bx =~ tr/fedcba9876543210/\x0f\x0e\x0d\x0c\x0b\x0a\x09\x08\x07\x06\x05\x04\x03\x02\x01\x00/;
  46      }
  47    if ($sy == -1)                # if y is negative
  48      {
  49      # two's complement: inc and flip all "bits" in $by
  50      $by = $y->copy()->binc()->as_hex();        # -1 => 0, -2 => 1, -3 => 2 etc
  51      $by =~ s/-?0x//;
  52      $by =~ tr/0123456789abcdef/\x0f\x0e\x0d\x0c\x0b\x0a\x09\x08\x07\x06\x05\x04\x03\x02\x01\x00/;
  53      }
  54    else
  55      {
  56      $by = $y->as_hex();                # get binary representation
  57      $by =~ s/-?0x//;
  58      $by =~ tr/fedcba9876543210/\x0f\x0e\x0d\x0c\x0b\x0a\x09\x08\x07\x06\x05\x04\x03\x02\x01\x00/;
  59      }
  60    # now we have bit-strings from X and Y, reverse them for padding
  61    $bx = reverse $bx;
  62    $by = reverse $by;
  63  
  64    # padd the shorter string
  65    my $xx = "\x00"; $xx = "\x0f" if $sx == -1;
  66    my $yy = "\x00"; $yy = "\x0f" if $sy == -1;
  67    my $diff = CORE::length($bx) - CORE::length($by);
  68    if ($diff > 0)
  69      {
  70      # if $yy eq "\x00", we can cut $bx, otherwise we need to padd $by
  71      $by .= $yy x $diff;
  72      }
  73    elsif ($diff < 0)
  74      {
  75      # if $xx eq "\x00", we can cut $by, otherwise we need to padd $bx
  76      $bx .= $xx x abs($diff);
  77      }
  78    
  79    # and the strings together
  80    my $r = $bx & $by;
  81  
  82    # and reverse the result again
  83    $bx = reverse $r;
  84  
  85    # One of $x or $y was negative, so need to flip bits in the result.
  86    # In both cases (one or two of them negative, or both positive) we need
  87    # to get the characters back.
  88    if ($sign == 1)
  89      {
  90      $bx =~ tr/\x0f\x0e\x0d\x0c\x0b\x0a\x09\x08\x07\x06\x05\x04\x03\x02\x01\x00/0123456789abcdef/;
  91      }
  92    else
  93      {
  94      $bx =~ tr/\x0f\x0e\x0d\x0c\x0b\x0a\x09\x08\x07\x06\x05\x04\x03\x02\x01\x00/fedcba9876543210/;
  95      }
  96  
  97    # leading zeros will be stripped by _from_hex()
  98    $bx = '0x' . $bx;
  99    $x->{value} = $CALC_EMU->_from_hex( $bx );
 100  
 101    # calculate sign of result
 102    $x->{sign} = '+';
 103    $x->{sign} = '-' if $sign == 1 && !$x->is_zero();
 104  
 105    $x->bdec() if $sign == 1;
 106  
 107    $x->round(@r);
 108    }
 109  
 110  sub __emu_bior
 111    {
 112    my ($self,$x,$y,$sx,$sy,@r) = @_;
 113  
 114    return $x->round(@r) if $y->is_zero();
 115  
 116    my $sign = 0;                    # sign of result
 117    $sign = 1 if ($sx == -1) || ($sy == -1);
 118  
 119    my ($bx,$by);
 120  
 121    if ($sx == -1)                # if x is negative
 122      {
 123      # two's complement: inc and flip all "bits" in $bx
 124      $bx = $x->binc()->as_hex();            # -1 => 0, -2 => 1, -3 => 2 etc
 125      $bx =~ s/-?0x//;
 126      $bx =~ tr/0123456789abcdef/\x0f\x0e\x0d\x0c\x0b\x0a\x09\x08\x07\x06\x05\x04\x03\x02\x01\x00/;
 127      }
 128    else
 129      {
 130      $bx = $x->as_hex();                # get binary representation
 131      $bx =~ s/-?0x//;
 132      $bx =~ tr/fedcba9876543210/\x0f\x0e\x0d\x0c\x0b\x0a\x09\x08\x07\x06\x05\x04\x03\x02\x01\x00/;
 133      }
 134    if ($sy == -1)                # if y is negative
 135      {
 136      # two's complement: inc and flip all "bits" in $by
 137      $by = $y->copy()->binc()->as_hex();        # -1 => 0, -2 => 1, -3 => 2 etc
 138      $by =~ s/-?0x//;
 139      $by =~ tr/0123456789abcdef/\x0f\x0e\x0d\x0c\x0b\x0a\x09\x08\x07\x06\x05\x04\x03\x02\x01\x00/;
 140      }
 141    else
 142      {
 143      $by = $y->as_hex();                # get binary representation
 144      $by =~ s/-?0x//;
 145      $by =~ tr/fedcba9876543210/\x0f\x0e\x0d\x0c\x0b\x0a\x09\x08\x07\x06\x05\x04\x03\x02\x01\x00/;
 146      }
 147    # now we have bit-strings from X and Y, reverse them for padding
 148    $bx = reverse $bx;
 149    $by = reverse $by;
 150  
 151    # padd the shorter string
 152    my $xx = "\x00"; $xx = "\x0f" if $sx == -1;
 153    my $yy = "\x00"; $yy = "\x0f" if $sy == -1;
 154    my $diff = CORE::length($bx) - CORE::length($by);
 155    if ($diff > 0)
 156      {
 157      $by .= $yy x $diff;
 158      }
 159    elsif ($diff < 0)
 160      {
 161      $bx .= $xx x abs($diff);
 162      }
 163  
 164    # or the strings together
 165    my $r = $bx | $by;
 166  
 167    # and reverse the result again
 168    $bx = reverse $r;
 169  
 170    # one of $x or $y was negative, so need to flip bits in the result
 171    # in both cases (one or two of them negative, or both positive) we need
 172    # to get the characters back.
 173    if ($sign == 1)
 174      {
 175      $bx =~ tr/\x0f\x0e\x0d\x0c\x0b\x0a\x09\x08\x07\x06\x05\x04\x03\x02\x01\x00/0123456789abcdef/;
 176      }
 177    else
 178      {
 179      $bx =~ tr/\x0f\x0e\x0d\x0c\x0b\x0a\x09\x08\x07\x06\x05\x04\x03\x02\x01\x00/fedcba9876543210/;
 180      }
 181  
 182    # leading zeros will be stripped by _from_hex()
 183    $bx = '0x' . $bx;
 184    $x->{value} = $CALC_EMU->_from_hex( $bx );
 185  
 186    # calculate sign of result
 187    $x->{sign} = '+';
 188    $x->{sign} = '-' if $sign == 1 && !$x->is_zero();
 189  
 190    # if one of X or Y was negative, we need to decrement result
 191    $x->bdec() if $sign == 1;
 192  
 193    $x->round(@r);
 194    }
 195  
 196  sub __emu_bxor
 197    {
 198    my ($self,$x,$y,$sx,$sy,@r) = @_;
 199  
 200    return $x->round(@r) if $y->is_zero();
 201  
 202    my $sign = 0;                    # sign of result
 203    $sign = 1 if $x->{sign} ne $y->{sign};
 204  
 205    my ($bx,$by);
 206  
 207    if ($sx == -1)                # if x is negative
 208      {
 209      # two's complement: inc and flip all "bits" in $bx
 210      $bx = $x->binc()->as_hex();            # -1 => 0, -2 => 1, -3 => 2 etc
 211      $bx =~ s/-?0x//;
 212      $bx =~ tr/0123456789abcdef/\x0f\x0e\x0d\x0c\x0b\x0a\x09\x08\x07\x06\x05\x04\x03\x02\x01\x00/;
 213      }
 214    else
 215      {
 216      $bx = $x->as_hex();                # get binary representation
 217      $bx =~ s/-?0x//;
 218      $bx =~ tr/fedcba9876543210/\x0f\x0e\x0d\x0c\x0b\x0a\x09\x08\x07\x06\x05\x04\x03\x02\x01\x00/;
 219      }
 220    if ($sy == -1)                # if y is negative
 221      {
 222      # two's complement: inc and flip all "bits" in $by
 223      $by = $y->copy()->binc()->as_hex();        # -1 => 0, -2 => 1, -3 => 2 etc
 224      $by =~ s/-?0x//;
 225      $by =~ tr/0123456789abcdef/\x0f\x0e\x0d\x0c\x0b\x0a\x09\x08\x07\x06\x05\x04\x03\x02\x01\x00/;
 226      }
 227    else
 228      {
 229      $by = $y->as_hex();                # get binary representation
 230      $by =~ s/-?0x//;
 231      $by =~ tr/fedcba9876543210/\x0f\x0e\x0d\x0c\x0b\x0a\x09\x08\x07\x06\x05\x04\x03\x02\x01\x00/;
 232      }
 233    # now we have bit-strings from X and Y, reverse them for padding
 234    $bx = reverse $bx;
 235    $by = reverse $by;
 236  
 237    # padd the shorter string
 238    my $xx = "\x00"; $xx = "\x0f" if $sx == -1;
 239    my $yy = "\x00"; $yy = "\x0f" if $sy == -1;
 240    my $diff = CORE::length($bx) - CORE::length($by);
 241    if ($diff > 0)
 242      {
 243      $by .= $yy x $diff;
 244      }
 245    elsif ($diff < 0)
 246      {
 247      $bx .= $xx x abs($diff);
 248      }
 249  
 250    # xor the strings together
 251    my $r = $bx ^ $by;
 252  
 253    # and reverse the result again
 254    $bx = reverse $r;
 255  
 256    # one of $x or $y was negative, so need to flip bits in the result
 257    # in both cases (one or two of them negative, or both positive) we need
 258    # to get the characters back.
 259    if ($sign == 1)
 260      {
 261      $bx =~ tr/\x0f\x0e\x0d\x0c\x0b\x0a\x09\x08\x07\x06\x05\x04\x03\x02\x01\x00/0123456789abcdef/;
 262      }
 263    else
 264      {
 265      $bx =~ tr/\x0f\x0e\x0d\x0c\x0b\x0a\x09\x08\x07\x06\x05\x04\x03\x02\x01\x00/fedcba9876543210/;
 266      }
 267  
 268    # leading zeros will be stripped by _from_hex()
 269    $bx = '0x' . $bx;
 270    $x->{value} = $CALC_EMU->_from_hex( $bx );
 271  
 272    # calculate sign of result
 273    $x->{sign} = '+';
 274    $x->{sign} = '-' if $sx != $sy && !$x->is_zero();
 275  
 276    $x->bdec() if $sign == 1;
 277  
 278    $x->round(@r);
 279    }
 280  
 281  ##############################################################################
 282  ##############################################################################
 283  
 284  1;
 285  __END__
 286  
 287  =head1 NAME
 288  
 289  Math::BigInt::CalcEmu - Emulate low-level math with BigInt code
 290  
 291  =head1 SYNOPSIS
 292  
 293      use Math::BigInt::CalcEmu;
 294  
 295  =head1 DESCRIPTION
 296  
 297  Contains routines that emulate low-level math functions in BigInt, e.g.
 298  optional routines the low-level math package does not provide on it's own.
 299  
 300  Will be loaded on demand and called automatically by BigInt.
 301  
 302  Stuff here is really low-priority to optimize, since it is far better to
 303  implement the operation in the low-level math libary directly, possible even
 304  using a call to the native lib.
 305  
 306  =head1 METHODS
 307  
 308  =head2 __emu_bxor
 309  
 310  =head2 __emu_band
 311  
 312  =head2 __emu_bior
 313  
 314  =head1 LICENSE
 315   
 316  This program is free software; you may redistribute it and/or modify it under
 317  the same terms as Perl itself. 
 318  
 319  =head1 AUTHORS
 320  
 321  (c) Tels http://bloodgate.com 2003, 2004 - based on BigInt code by
 322  Tels from 2001-2003.
 323  
 324  =head1 SEE ALSO
 325  
 326  L<Math::BigInt>, L<Math::BigFloat>, L<Math::BigInt::BitVect>,
 327  L<Math::BigInt::GMP> and L<Math::BigInt::Pari>.
 328  
 329  =cut


Generated: Tue Mar 17 22:47:18 2015 Cross-referenced by PHPXref 0.7.1