Track /etc/gitconfig
[msysgit.git] / lib / perl5 / 5.8.8 / Math / BigInt / CalcEmu.pm
blobf56b51a3b90393bc9ebd5ef693ea970fb77ca336
1 package Math::BigInt::CalcEmu;
3 use 5.005;
4 use strict;
5 # use warnings; # dont use warnings for older Perls
6 use vars qw/$VERSION/;
8 $VERSION = '0.05';
10 package Math::BigInt;
12 # See SYNOPSIS below.
14 my $CALC_EMU;
16 BEGIN
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]; } );
23 sub __emu_band
25 my ($self,$x,$y,$sx,$sy,@r) = @_;
27 return $x->bzero(@r) if $y->is_zero() || $x->is_zero();
29 my $sign = 0; # sign of result
30 $sign = 1 if $sx == -1 && $sy == -1;
32 my ($bx,$by);
34 if ($sx == -1) # if x is negative
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/;
41 else
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/;
47 if ($sy == -1) # if y is negative
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/;
54 else
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/;
60 # now we have bit-strings from X and Y, reverse them for padding
61 $bx = reverse $bx;
62 $by = reverse $by;
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)
70 # if $yy eq "\x00", we can cut $bx, otherwise we need to padd $by
71 $by .= $yy x $diff;
73 elsif ($diff < 0)
75 # if $xx eq "\x00", we can cut $by, otherwise we need to padd $bx
76 $bx .= $xx x abs($diff);
79 # and the strings together
80 my $r = $bx & $by;
82 # and reverse the result again
83 $bx = reverse $r;
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)
90 $bx =~ tr/\x0f\x0e\x0d\x0c\x0b\x0a\x09\x08\x07\x06\x05\x04\x03\x02\x01\x00/0123456789abcdef/;
92 else
94 $bx =~ tr/\x0f\x0e\x0d\x0c\x0b\x0a\x09\x08\x07\x06\x05\x04\x03\x02\x01\x00/fedcba9876543210/;
97 # leading zeros will be stripped by _from_hex()
98 $bx = '0x' . $bx;
99 $x->{value} = $CALC_EMU->_from_hex( $bx );
101 # calculate sign of result
102 $x->{sign} = '+';
103 $x->{sign} = '-' if $sign == 1 && !$x->is_zero();
105 $x->bdec() if $sign == 1;
107 $x->round(@r);
110 sub __emu_bior
112 my ($self,$x,$y,$sx,$sy,@r) = @_;
114 return $x->round(@r) if $y->is_zero();
116 my $sign = 0; # sign of result
117 $sign = 1 if ($sx == -1) || ($sy == -1);
119 my ($bx,$by);
121 if ($sx == -1) # if x is negative
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/;
128 else
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/;
134 if ($sy == -1) # if y is negative
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/;
141 else
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/;
147 # now we have bit-strings from X and Y, reverse them for padding
148 $bx = reverse $bx;
149 $by = reverse $by;
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)
157 $by .= $yy x $diff;
159 elsif ($diff < 0)
161 $bx .= $xx x abs($diff);
164 # or the strings together
165 my $r = $bx | $by;
167 # and reverse the result again
168 $bx = reverse $r;
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)
175 $bx =~ tr/\x0f\x0e\x0d\x0c\x0b\x0a\x09\x08\x07\x06\x05\x04\x03\x02\x01\x00/0123456789abcdef/;
177 else
179 $bx =~ tr/\x0f\x0e\x0d\x0c\x0b\x0a\x09\x08\x07\x06\x05\x04\x03\x02\x01\x00/fedcba9876543210/;
182 # leading zeros will be stripped by _from_hex()
183 $bx = '0x' . $bx;
184 $x->{value} = $CALC_EMU->_from_hex( $bx );
186 # calculate sign of result
187 $x->{sign} = '+';
188 $x->{sign} = '-' if $sign == 1 && !$x->is_zero();
190 # if one of X or Y was negative, we need to decrement result
191 $x->bdec() if $sign == 1;
193 $x->round(@r);
196 sub __emu_bxor
198 my ($self,$x,$y,$sx,$sy,@r) = @_;
200 return $x->round(@r) if $y->is_zero();
202 my $sign = 0; # sign of result
203 $sign = 1 if $x->{sign} ne $y->{sign};
205 my ($bx,$by);
207 if ($sx == -1) # if x is negative
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/;
214 else
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/;
220 if ($sy == -1) # if y is negative
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/;
227 else
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/;
233 # now we have bit-strings from X and Y, reverse them for padding
234 $bx = reverse $bx;
235 $by = reverse $by;
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)
243 $by .= $yy x $diff;
245 elsif ($diff < 0)
247 $bx .= $xx x abs($diff);
250 # xor the strings together
251 my $r = $bx ^ $by;
253 # and reverse the result again
254 $bx = reverse $r;
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)
261 $bx =~ tr/\x0f\x0e\x0d\x0c\x0b\x0a\x09\x08\x07\x06\x05\x04\x03\x02\x01\x00/0123456789abcdef/;
263 else
265 $bx =~ tr/\x0f\x0e\x0d\x0c\x0b\x0a\x09\x08\x07\x06\x05\x04\x03\x02\x01\x00/fedcba9876543210/;
268 # leading zeros will be stripped by _from_hex()
269 $bx = '0x' . $bx;
270 $x->{value} = $CALC_EMU->_from_hex( $bx );
272 # calculate sign of result
273 $x->{sign} = '+';
274 $x->{sign} = '-' if $sx != $sy && !$x->is_zero();
276 $x->bdec() if $sign == 1;
278 $x->round(@r);
281 ##############################################################################
282 ##############################################################################
285 __END__
287 =head1 NAME
289 Math::BigInt::CalcEmu - Emulate low-level math with BigInt code
291 =head1 SYNOPSIS
293 use Math::BigInt::CalcEmu;
295 =head1 DESCRIPTION
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.
300 Will be loaded on demand and called automatically by BigInt.
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.
306 =head1 METHODS
308 =head2 __emu_bxor
310 =head2 __emu_band
312 =head2 __emu_bior
314 =head1 LICENSE
316 This program is free software; you may redistribute it and/or modify it under
317 the same terms as Perl itself.
319 =head1 AUTHORS
321 (c) Tels http://bloodgate.com 2003, 2004 - based on BigInt code by
322 Tels from 2001-2003.
324 =head1 SEE ALSO
326 L<Math::BigInt>, L<Math::BigFloat>, L<Math::BigInt::BitVect>,
327 L<Math::BigInt::GMP> and L<Math::BigInt::Pari>.
329 =cut