exiftool-vendored.exe 12.80.0 → 12.82.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -0
- package/bin/exiftool.exe +0 -0
- package/bin/exiftool_files/Changes +44 -0
- package/bin/exiftool_files/Licenses_Strawberry_Perl.zip +0 -0
- package/bin/exiftool_files/README +3 -2
- package/bin/exiftool_files/exiftool.pl +36 -14
- package/bin/exiftool_files/lib/Archive/Zip/Archive.pm +399 -65
- package/bin/exiftool_files/lib/Archive/Zip/DirectoryMember.pm +1 -1
- package/bin/exiftool_files/lib/Archive/Zip/FileMember.pm +1 -1
- package/bin/exiftool_files/lib/Archive/Zip/Member.pm +499 -195
- package/bin/exiftool_files/lib/Archive/Zip/NewFileMember.pm +1 -1
- package/bin/exiftool_files/lib/Archive/Zip/StringMember.pm +2 -2
- package/bin/exiftool_files/lib/Archive/Zip/ZipFileMember.pm +79 -20
- package/bin/exiftool_files/lib/Archive/Zip.pm +179 -29
- package/bin/exiftool_files/lib/AutoLoader.pm +453 -0
- package/bin/exiftool_files/lib/B/Deparse.pm +209 -137
- package/bin/exiftool_files/lib/B.pm +1 -1
- package/bin/exiftool_files/lib/Benchmark.pm +1123 -0
- package/bin/exiftool_files/lib/Class/Struct.pm +2 -2
- package/bin/exiftool_files/lib/Compress/Raw/Bzip2.pm +14 -9
- package/bin/exiftool_files/lib/Compress/Raw/Lzma.pm +982 -0
- package/bin/exiftool_files/lib/Compress/Raw/Zlib.pm +91 -86
- package/bin/exiftool_files/lib/Compress/Zlib.pm +105 -100
- package/bin/exiftool_files/lib/Config.pm +9 -9
- package/bin/exiftool_files/lib/Config_heavy.pl +36 -33
- package/bin/exiftool_files/lib/CryptX.pm +2 -82
- package/bin/exiftool_files/lib/Data/Dumper.pm +2 -2
- package/bin/exiftool_files/lib/Digest/MD5.pm +12 -9
- package/bin/exiftool_files/lib/Digest/Perl/MD5.pm +1 -191
- package/bin/exiftool_files/lib/Digest/base.pm +26 -20
- package/bin/exiftool_files/lib/DynaLoader.pm +7 -4
- package/bin/exiftool_files/lib/Encode.pm +3 -3
- package/bin/exiftool_files/lib/Errno.pm +13 -13
- package/bin/exiftool_files/lib/Exporter/Heavy.pm +2 -2
- package/bin/exiftool_files/lib/Exporter.pm +1 -1
- package/bin/exiftool_files/lib/ExtUtils/Command/MM.pm +323 -0
- package/bin/exiftool_files/lib/ExtUtils/Command.pm +382 -0
- package/bin/exiftool_files/lib/File/Find.pm +1 -1
- package/bin/exiftool_files/lib/File/Glob.pm +1 -8
- package/bin/exiftool_files/lib/File/GlobMapper.pm +2 -2
- package/bin/exiftool_files/lib/File/HomeDir/Darwin/Carbon.pm +2 -40
- package/bin/exiftool_files/lib/File/HomeDir/Darwin/Cocoa.pm +2 -34
- package/bin/exiftool_files/lib/File/HomeDir/Darwin.pm +2 -28
- package/bin/exiftool_files/lib/File/HomeDir/Driver.pm +2 -35
- package/bin/exiftool_files/lib/File/HomeDir/FreeDesktop.pm +2 -62
- package/bin/exiftool_files/lib/File/HomeDir/MacOS9.pm +2 -53
- package/bin/exiftool_files/lib/File/HomeDir/Test.pm +2 -43
- package/bin/exiftool_files/lib/File/HomeDir/Unix.pm +2 -53
- package/bin/exiftool_files/lib/File/HomeDir/Windows.pm +2 -69
- package/bin/exiftool_files/lib/File/HomeDir.pm +5 -416
- package/bin/exiftool_files/lib/File/Path.pm +3 -3
- package/bin/exiftool_files/lib/File/Spec/Win32.pm +2 -2
- package/bin/exiftool_files/lib/File/Temp.pm +70 -35
- package/bin/exiftool_files/lib/File/Which.pm +1 -240
- package/bin/exiftool_files/lib/File/stat.pm +3 -2
- package/bin/exiftool_files/lib/IO/Compress/Adapter/Bzip2.pm +16 -17
- package/bin/exiftool_files/lib/IO/Compress/Adapter/Deflate.pm +19 -20
- package/bin/exiftool_files/lib/IO/Compress/Base/Common.pm +5 -5
- package/bin/exiftool_files/lib/IO/Compress/Base.pm +35 -26
- package/bin/exiftool_files/lib/IO/Compress/Brotli.pm +159 -0
- package/bin/exiftool_files/lib/IO/Compress/Bzip2.pm +50 -25
- package/bin/exiftool_files/lib/IO/Compress/Gzip/Constants.pm +6 -6
- package/bin/exiftool_files/lib/IO/Compress/Gzip.pm +58 -32
- package/bin/exiftool_files/lib/IO/Compress/RawDeflate.pm +63 -38
- package/bin/exiftool_files/lib/IO/Compress/Zlib/Extra.pm +20 -20
- package/bin/exiftool_files/lib/IO/Dir.pm +1 -1
- package/bin/exiftool_files/lib/IO/File.pm +1 -1
- package/bin/exiftool_files/lib/IO/Handle.pm +1 -21
- package/bin/exiftool_files/lib/IO/Pipe.pm +1 -1
- package/bin/exiftool_files/lib/IO/Seekable.pm +1 -1
- package/bin/exiftool_files/lib/IO/Select.pm +16 -2
- package/bin/exiftool_files/lib/IO/Socket/INET.pm +14 -9
- package/bin/exiftool_files/lib/IO/Socket/UNIX.pm +17 -1
- package/bin/exiftool_files/lib/IO/Socket.pm +474 -126
- package/bin/exiftool_files/lib/IO/String.pm +425 -0
- package/bin/exiftool_files/lib/IO/Uncompress/Adapter/Inflate.pm +13 -14
- package/bin/exiftool_files/lib/IO/Uncompress/Base.pm +142 -132
- package/bin/exiftool_files/lib/IO/Uncompress/Brotli.pm +119 -0
- package/bin/exiftool_files/lib/IO/Uncompress/Gunzip.pm +43 -37
- package/bin/exiftool_files/lib/IO/Uncompress/RawInflate.pm +49 -43
- package/bin/exiftool_files/lib/IO.pm +2 -2
- package/bin/exiftool_files/lib/Image/ExifTool/BuildTagLookup.pm +44 -31
- package/bin/exiftool_files/lib/Image/ExifTool/CanonVRD.pm +2 -2
- package/bin/exiftool_files/lib/Image/ExifTool/FujiFilm.pm +20 -7
- package/bin/exiftool_files/lib/Image/ExifTool/GM.pm +543 -0
- package/bin/exiftool_files/lib/Image/ExifTool/Geolocation.pm +332 -149
- package/bin/exiftool_files/lib/Image/ExifTool/Geotag.pm +9 -4
- package/bin/exiftool_files/lib/Image/ExifTool/M2TS.pm +32 -4
- package/bin/exiftool_files/lib/Image/ExifTool/MakerNotes.pm +2 -2
- package/bin/exiftool_files/lib/Image/ExifTool/Microsoft.pm +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/Nikon.pm +331 -22
- package/bin/exiftool_files/lib/Image/ExifTool/NikonCustom.pm +55 -1
- package/bin/exiftool_files/lib/Image/ExifTool/Olympus.pm +1 -0
- package/bin/exiftool_files/lib/Image/ExifTool/OpenEXR.pm +21 -3
- package/bin/exiftool_files/lib/Image/ExifTool/PNG.pm +3 -3
- package/bin/exiftool_files/lib/Image/ExifTool/QuickTime.pm +40 -24
- package/bin/exiftool_files/lib/Image/ExifTool/QuickTimeStream.pl +61 -30
- package/bin/exiftool_files/lib/Image/ExifTool/README +2 -0
- package/bin/exiftool_files/lib/Image/ExifTool/Sony.pm +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/TagLookup.pm +4815 -4775
- package/bin/exiftool_files/lib/Image/ExifTool/TagNames.pod +931 -617
- package/bin/exiftool_files/lib/Image/ExifTool/WriteQuickTime.pl +30 -8
- package/bin/exiftool_files/lib/Image/ExifTool/Writer.pl +10 -4
- package/bin/exiftool_files/lib/Image/ExifTool/XMP.pm +4 -2
- package/bin/exiftool_files/lib/Image/ExifTool.pm +77 -41
- package/bin/exiftool_files/lib/Image/ExifTool.pod +24 -11
- package/bin/exiftool_files/lib/List/Util.pm +97 -8
- package/bin/exiftool_files/lib/MIME/Base64.pm +5 -5
- package/bin/exiftool_files/lib/MIME/Charset/_Compat.pm +106 -0
- package/bin/exiftool_files/lib/MIME/Charset.pm +1303 -0
- package/bin/exiftool_files/lib/Math/BigFloat.pm +444 -27
- package/bin/exiftool_files/lib/Math/BigInt/Calc.pm +296 -313
- package/bin/exiftool_files/lib/Math/BigInt/FastCalc.pm +1 -1
- package/bin/exiftool_files/lib/Math/BigInt/GMP.pm +2 -115
- package/bin/exiftool_files/lib/Math/BigInt/LTM.pm +2 -24
- package/bin/exiftool_files/lib/Math/BigInt/Lib.pm +61 -32
- package/bin/exiftool_files/lib/Math/BigInt.pm +292 -107
- package/bin/exiftool_files/lib/POSIX.pm +1 -1
- package/bin/exiftool_files/lib/PerlIO/scalar.pm +41 -0
- package/bin/exiftool_files/lib/PerlIO.pm +397 -0
- package/bin/exiftool_files/lib/Portable/CPAN.pm +94 -94
- package/bin/exiftool_files/lib/Portable/Config.pm +94 -94
- package/bin/exiftool_files/lib/Portable/FileSpec.pm +180 -180
- package/bin/exiftool_files/lib/Portable/HomeDir.pm +110 -110
- package/bin/exiftool_files/lib/Portable/LoadYaml.pm +430 -430
- package/bin/exiftool_files/lib/Portable/minicpan.pm +55 -55
- package/bin/exiftool_files/lib/Portable.pm +246 -320
- package/bin/exiftool_files/lib/Scalar/Util.pm +9 -4
- package/bin/exiftool_files/lib/Socket.pm +16 -12
- package/bin/exiftool_files/lib/Storable.pm +1444 -1441
- package/bin/exiftool_files/lib/TAP/Base.pm +133 -0
- package/bin/exiftool_files/lib/TAP/Formatter/Base.pm +467 -0
- package/bin/exiftool_files/lib/TAP/Formatter/Color.pm +116 -0
- package/bin/exiftool_files/lib/TAP/Formatter/Console/ParallelSession.pm +201 -0
- package/bin/exiftool_files/lib/TAP/Formatter/Console/Session.pm +205 -0
- package/bin/exiftool_files/lib/TAP/Formatter/Console.pm +100 -0
- package/bin/exiftool_files/lib/TAP/Formatter/File/Session.pm +95 -0
- package/bin/exiftool_files/lib/TAP/Formatter/File.pm +56 -0
- package/bin/exiftool_files/lib/TAP/Formatter/Session.pm +220 -0
- package/bin/exiftool_files/lib/TAP/Harness/Beyond.pod +426 -0
- package/bin/exiftool_files/lib/TAP/Harness/Env.pm +215 -0
- package/bin/exiftool_files/lib/TAP/Harness.pm +1054 -0
- package/bin/exiftool_files/lib/TAP/Object.pm +155 -0
- package/bin/exiftool_files/lib/TAP/Parser/Aggregator.pm +414 -0
- package/bin/exiftool_files/lib/TAP/Parser/Grammar.pm +584 -0
- package/bin/exiftool_files/lib/TAP/Parser/Iterator/Array.pm +100 -0
- package/bin/exiftool_files/lib/TAP/Parser/Iterator/Process.pm +378 -0
- package/bin/exiftool_files/lib/TAP/Parser/Iterator/Stream.pm +116 -0
- package/bin/exiftool_files/lib/TAP/Parser/Iterator.pm +162 -0
- package/bin/exiftool_files/lib/TAP/Parser/IteratorFactory.pm +339 -0
- package/bin/exiftool_files/lib/TAP/Parser/Multiplexer.pm +194 -0
- package/bin/exiftool_files/lib/TAP/Parser/Result/Bailout.pm +62 -0
- package/bin/exiftool_files/lib/TAP/Parser/Result/Comment.pm +60 -0
- package/bin/exiftool_files/lib/TAP/Parser/Result/Plan.pm +119 -0
- package/bin/exiftool_files/lib/TAP/Parser/Result/Pragma.pm +62 -0
- package/bin/exiftool_files/lib/TAP/Parser/Result/Test.pm +271 -0
- package/bin/exiftool_files/lib/TAP/Parser/Result/Unknown.pm +48 -0
- package/bin/exiftool_files/lib/TAP/Parser/Result/Version.pm +62 -0
- package/bin/exiftool_files/lib/TAP/Parser/Result/YAML.pm +61 -0
- package/bin/exiftool_files/lib/TAP/Parser/Result.pm +297 -0
- package/bin/exiftool_files/lib/TAP/Parser/ResultFactory.pm +183 -0
- package/bin/exiftool_files/lib/TAP/Parser/Scheduler/Job.pm +127 -0
- package/bin/exiftool_files/lib/TAP/Parser/Scheduler/Spinner.pm +61 -0
- package/bin/exiftool_files/lib/TAP/Parser/Scheduler.pm +448 -0
- package/bin/exiftool_files/lib/TAP/Parser/Source.pm +381 -0
- package/bin/exiftool_files/lib/TAP/Parser/SourceHandler/Executable.pm +184 -0
- package/bin/exiftool_files/lib/TAP/Parser/SourceHandler/File.pm +136 -0
- package/bin/exiftool_files/lib/TAP/Parser/SourceHandler/Handle.pm +124 -0
- package/bin/exiftool_files/lib/TAP/Parser/SourceHandler/Perl.pm +370 -0
- package/bin/exiftool_files/lib/TAP/Parser/SourceHandler/RawTAP.pm +130 -0
- package/bin/exiftool_files/lib/TAP/Parser/SourceHandler.pm +191 -0
- package/bin/exiftool_files/lib/TAP/Parser/YAMLish/Reader.pm +332 -0
- package/bin/exiftool_files/lib/TAP/Parser/YAMLish/Writer.pm +254 -0
- package/bin/exiftool_files/lib/TAP/Parser.pm +1931 -0
- package/bin/exiftool_files/lib/Test/Builder/Formatter.pm +107 -0
- package/bin/exiftool_files/lib/Test/Builder/IO/Scalar.pm +659 -0
- package/bin/exiftool_files/lib/Test/Builder/Module.pm +182 -0
- package/bin/exiftool_files/lib/Test/Builder/Tester/Color.pm +51 -0
- package/bin/exiftool_files/lib/Test/Builder/Tester.pm +675 -0
- package/bin/exiftool_files/lib/Test/Builder/TodoDiag.pm +68 -0
- package/bin/exiftool_files/lib/Test/Builder.pm +2653 -0
- package/bin/exiftool_files/lib/Test/Harness.pm +618 -0
- package/bin/exiftool_files/lib/Test/More.pm +1997 -0
- package/bin/exiftool_files/lib/Test/Simple.pm +220 -0
- package/bin/exiftool_files/lib/Test/Tester/Capture.pm +241 -0
- package/bin/exiftool_files/lib/Test/Tester/CaptureRunner.pm +79 -0
- package/bin/exiftool_files/lib/Test/Tester/Delegate.pm +45 -0
- package/bin/exiftool_files/lib/Test/Tester.pm +695 -0
- package/bin/exiftool_files/lib/Test/Tutorial.pod +618 -0
- package/bin/exiftool_files/lib/Test/use/ok.pm +64 -0
- package/bin/exiftool_files/lib/Text/ParseWords.pm +303 -0
- package/bin/exiftool_files/lib/Tie/StdHandle.pm +2 -2
- package/bin/exiftool_files/lib/Time/HiRes.pm +73 -68
- package/bin/exiftool_files/lib/Time/Local.pm +82 -35
- package/bin/exiftool_files/lib/Time/Piece.pm +19 -4
- package/bin/exiftool_files/lib/Time/Seconds.pm +1 -1
- package/bin/exiftool_files/lib/UNIVERSAL.pm +203 -0
- package/bin/exiftool_files/lib/Unicode/GCString.pm +60 -0
- package/bin/exiftool_files/lib/Unicode/LineBreak/Constants.pm +68 -0
- package/bin/exiftool_files/lib/Unicode/LineBreak.pm +248 -0
- package/bin/exiftool_files/lib/Win32/API/Struct.pm +1 -177
- package/bin/exiftool_files/lib/Win32/API/Type.pm +1 -100
- package/bin/exiftool_files/lib/Win32/API.pm +1 -830
- package/bin/exiftool_files/lib/Win32/FindFile.pm +2 -123
- package/bin/exiftool_files/lib/Win32.pm +213 -89
- package/bin/exiftool_files/lib/Win32API/File.pm +1 -1
- package/bin/exiftool_files/lib/auto/B/B.xs.dll +0 -0
- package/bin/exiftool_files/lib/auto/Compress/Raw/Bzip2/Bzip2.xs.dll +0 -0
- package/bin/exiftool_files/lib/auto/Compress/Raw/Lzma/Lzma.xs.dll +0 -0
- package/bin/exiftool_files/lib/auto/Compress/Raw/Lzma/autosplit.ix +3 -0
- package/bin/exiftool_files/lib/auto/Compress/Raw/Zlib/Zlib.xs.dll +0 -0
- package/bin/exiftool_files/lib/auto/CryptX/CryptX.xs.dll +0 -0
- package/bin/exiftool_files/lib/auto/Cwd/Cwd.xs.dll +0 -0
- package/bin/exiftool_files/lib/auto/Data/Dumper/Dumper.xs.dll +0 -0
- package/bin/exiftool_files/lib/auto/Digest/MD5/MD5.xs.dll +0 -0
- package/bin/exiftool_files/lib/auto/Digest/SHA/SHA.xs.dll +0 -0
- package/bin/exiftool_files/lib/auto/Encode/Encode.xs.dll +0 -0
- package/bin/exiftool_files/lib/auto/Fcntl/Fcntl.xs.dll +0 -0
- package/bin/exiftool_files/lib/auto/File/Glob/Glob.xs.dll +0 -0
- package/bin/exiftool_files/lib/auto/IO/Compress/Brotli/Brotli.xs.dll +0 -0
- package/bin/exiftool_files/lib/auto/IO/IO.xs.dll +0 -0
- package/bin/exiftool_files/lib/auto/List/Util/Util.xs.dll +0 -0
- package/bin/exiftool_files/lib/auto/MIME/Base64/Base64.xs.dll +0 -0
- package/bin/exiftool_files/lib/auto/Math/BigInt/FastCalc/FastCalc.xs.dll +0 -0
- package/bin/exiftool_files/lib/auto/Math/BigInt/GMP/GMP.xs.dll +0 -0
- package/bin/exiftool_files/lib/auto/POSIX/POSIX.xs.dll +0 -0
- package/bin/exiftool_files/lib/auto/PerlIO/scalar/scalar.xs.dll +0 -0
- package/bin/exiftool_files/lib/auto/Socket/Socket.xs.dll +0 -0
- package/bin/exiftool_files/lib/auto/Storable/Storable.xs.dll +0 -0
- package/bin/exiftool_files/lib/auto/Time/HiRes/HiRes.xs.dll +0 -0
- package/bin/exiftool_files/lib/auto/Time/Piece/Piece.xs.dll +0 -0
- package/bin/exiftool_files/lib/auto/Unicode/LineBreak/LineBreak.xs.dll +0 -0
- package/bin/exiftool_files/lib/auto/Win32/API/API.xs.dll +0 -0
- package/bin/exiftool_files/lib/auto/Win32/FindFile/FindFile.xs.dll +0 -0
- package/bin/exiftool_files/lib/auto/Win32/Win32.xs.dll +0 -0
- package/bin/exiftool_files/lib/auto/Win32API/File/File.xs.dll +0 -0
- package/bin/exiftool_files/lib/auto/mro/mro.xs.dll +0 -0
- package/bin/exiftool_files/lib/auto/re/re.xs.dll +0 -0
- package/bin/exiftool_files/lib/feature.pm +49 -17
- package/bin/exiftool_files/lib/mro.pm +4 -20
- package/bin/exiftool_files/lib/overload.pm +15 -15
- package/bin/exiftool_files/lib/parent.pm +10 -2
- package/bin/exiftool_files/lib/re.pm +91 -33
- package/bin/exiftool_files/lib/warnings.pm +17 -6
- package/bin/exiftool_files/libgcc_s_seh-1.dll +0 -0
- package/bin/exiftool_files/liblzma-5__.dll +0 -0
- package/bin/exiftool_files/libstdc++-6.dll +0 -0
- package/bin/exiftool_files/libwinpthread-1.dll +0 -0
- package/bin/exiftool_files/perl.exe +0 -0
- package/bin/exiftool_files/perl532.dll +0 -0
- package/package.json +7 -5
- package/bin/exiftool_files/libgcc_s_dw2-1.dll +0 -0
- package/bin/exiftool_files/perl530.dll +0 -0
|
@@ -7,7 +7,7 @@ use warnings;
|
|
|
7
7
|
use Carp qw< carp croak >;
|
|
8
8
|
use Math::BigInt::Lib;
|
|
9
9
|
|
|
10
|
-
our $VERSION = '1.
|
|
10
|
+
our $VERSION = '1.999818';
|
|
11
11
|
|
|
12
12
|
our @ISA = ('Math::BigInt::Lib');
|
|
13
13
|
|
|
@@ -35,9 +35,6 @@ our @ISA = ('Math::BigInt::Lib');
|
|
|
35
35
|
##############################################################################
|
|
36
36
|
# global constants, flags and accessory
|
|
37
37
|
|
|
38
|
-
# announce that we are compatible with MBI v1.83 and up
|
|
39
|
-
sub api_version () { 2; }
|
|
40
|
-
|
|
41
38
|
# constants for easier life
|
|
42
39
|
my ($BASE, $BASE_LEN, $RBASE, $MAX_VAL);
|
|
43
40
|
my ($AND_BITS, $XOR_BITS, $OR_BITS);
|
|
@@ -50,9 +47,7 @@ sub _base_len {
|
|
|
50
47
|
|
|
51
48
|
my ($class, $b, $int) = @_;
|
|
52
49
|
if (defined $b) {
|
|
53
|
-
|
|
54
|
-
undef &_mul;
|
|
55
|
-
undef &_div;
|
|
50
|
+
no warnings "redefine";
|
|
56
51
|
|
|
57
52
|
if ($] >= 5.008 && $int && $b > 7) {
|
|
58
53
|
$BASE_LEN = $b;
|
|
@@ -403,13 +398,14 @@ sub _mul_use_mul {
|
|
|
403
398
|
my ($c, $xv, $yv) = @_;
|
|
404
399
|
|
|
405
400
|
if (@$yv == 1) {
|
|
406
|
-
# shortcut for two very short numbers (improved by Nathan Zook)
|
|
407
|
-
#
|
|
401
|
+
# shortcut for two very short numbers (improved by Nathan Zook) works
|
|
402
|
+
# also if xv and yv are the same reference, and handles also $x == 0
|
|
408
403
|
if (@$xv == 1) {
|
|
409
404
|
if (($xv->[0] *= $yv->[0]) >= $BASE) {
|
|
410
|
-
|
|
405
|
+
my $rem = $xv->[0] % $BASE;
|
|
406
|
+
$xv->[1] = ($xv->[0] - $rem) * $RBASE;
|
|
407
|
+
$xv->[0] = $rem;
|
|
411
408
|
}
|
|
412
|
-
;
|
|
413
409
|
return $xv;
|
|
414
410
|
}
|
|
415
411
|
# $x * 0 => 0
|
|
@@ -417,56 +413,44 @@ sub _mul_use_mul {
|
|
|
417
413
|
@$xv = (0);
|
|
418
414
|
return $xv;
|
|
419
415
|
}
|
|
416
|
+
|
|
420
417
|
# multiply a large number a by a single element one, so speed up
|
|
421
418
|
my $y = $yv->[0];
|
|
422
419
|
my $car = 0;
|
|
420
|
+
my $rem;
|
|
423
421
|
foreach my $i (@$xv) {
|
|
424
422
|
$i = $i * $y + $car;
|
|
425
|
-
$
|
|
426
|
-
$i
|
|
423
|
+
$rem = $i % $BASE;
|
|
424
|
+
$car = ($i - $rem) * $RBASE;
|
|
425
|
+
$i = $rem;
|
|
427
426
|
}
|
|
428
427
|
push @$xv, $car if $car != 0;
|
|
429
428
|
return $xv;
|
|
430
429
|
}
|
|
430
|
+
|
|
431
431
|
# shortcut for result $x == 0 => result = 0
|
|
432
432
|
return $xv if @$xv == 1 && $xv->[0] == 0;
|
|
433
433
|
|
|
434
434
|
# since multiplying $x with $x fails, make copy in this case
|
|
435
|
-
$yv =
|
|
435
|
+
$yv = $c->_copy($xv) if $xv == $yv; # same references?
|
|
436
436
|
|
|
437
437
|
my @prod = ();
|
|
438
|
-
my ($prod, $car, $cty, $xi, $yi);
|
|
439
|
-
|
|
438
|
+
my ($prod, $rem, $car, $cty, $xi, $yi);
|
|
440
439
|
for $xi (@$xv) {
|
|
441
440
|
$car = 0;
|
|
442
441
|
$cty = 0;
|
|
443
|
-
|
|
444
|
-
# slow variant
|
|
445
|
-
# for $yi (@$yv)
|
|
446
|
-
# {
|
|
447
|
-
# $prod = $xi * $yi + ($prod[$cty] || 0) + $car;
|
|
448
|
-
# $prod[$cty++] =
|
|
449
|
-
# $prod - ($car = int($prod * RBASE)) * $BASE; # see USE_MUL
|
|
450
|
-
# }
|
|
451
|
-
# $prod[$cty] += $car if $car; # need really to check for 0?
|
|
452
|
-
# $xi = shift @prod;
|
|
453
|
-
|
|
454
|
-
# faster variant
|
|
455
442
|
# looping through this if $xi == 0 is silly - so optimize it away!
|
|
456
|
-
$xi = (shift
|
|
443
|
+
$xi = (shift(@prod) || 0), next if $xi == 0;
|
|
457
444
|
for $yi (@$yv) {
|
|
458
445
|
$prod = $xi * $yi + ($prod[$cty] || 0) + $car;
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
$prod[$cty++] =
|
|
462
|
-
$prod - ($car = int($prod * $RBASE)) * $BASE; # see USE_MUL
|
|
446
|
+
$rem = $prod % $BASE;
|
|
447
|
+
$car = int(($prod - $rem) * $RBASE);
|
|
448
|
+
$prod[$cty++] = $rem;
|
|
463
449
|
}
|
|
464
|
-
$prod[$cty] += $car if $car;
|
|
465
|
-
$xi = shift
|
|
450
|
+
$prod[$cty] += $car if $car; # need really to check for 0?
|
|
451
|
+
$xi = shift(@prod) || 0; # || 0 makes v5.005_3 happy
|
|
466
452
|
}
|
|
467
453
|
push @$xv, @prod;
|
|
468
|
-
# can't have leading zeros
|
|
469
|
-
# __strip_zeros($xv);
|
|
470
454
|
$xv;
|
|
471
455
|
}
|
|
472
456
|
|
|
@@ -478,11 +462,11 @@ sub _mul_use_div_64 {
|
|
|
478
462
|
my ($c, $xv, $yv) = @_;
|
|
479
463
|
|
|
480
464
|
use integer;
|
|
465
|
+
|
|
481
466
|
if (@$yv == 1) {
|
|
482
|
-
# shortcut for two
|
|
467
|
+
# shortcut for two very short numbers (improved by Nathan Zook) works
|
|
468
|
+
# also if xv and yv are the same reference, and handles also $x == 0
|
|
483
469
|
if (@$xv == 1) {
|
|
484
|
-
# shortcut for two very short numbers (improved by Nathan Zook)
|
|
485
|
-
# works also if xv and yv are the same reference, and handles also $x == 0
|
|
486
470
|
if (($xv->[0] *= $yv->[0]) >= $BASE) {
|
|
487
471
|
$xv->[0] =
|
|
488
472
|
$xv->[0] - ($xv->[1] = $xv->[0] / $BASE) * $BASE;
|
|
@@ -494,6 +478,7 @@ sub _mul_use_div_64 {
|
|
|
494
478
|
@$xv = (0);
|
|
495
479
|
return $xv;
|
|
496
480
|
}
|
|
481
|
+
|
|
497
482
|
# multiply a large number a by a single element one, so speed up
|
|
498
483
|
my $y = $yv->[0];
|
|
499
484
|
my $car = 0;
|
|
@@ -505,11 +490,12 @@ sub _mul_use_div_64 {
|
|
|
505
490
|
push @$xv, $car if $car != 0;
|
|
506
491
|
return $xv;
|
|
507
492
|
}
|
|
493
|
+
|
|
508
494
|
# shortcut for result $x == 0 => result = 0
|
|
509
|
-
return $xv if
|
|
495
|
+
return $xv if @$xv == 1 && $xv->[0] == 0;
|
|
510
496
|
|
|
511
497
|
# since multiplying $x with $x fails, make copy in this case
|
|
512
|
-
$yv = $c->_copy($xv) if $xv == $yv;
|
|
498
|
+
$yv = $c->_copy($xv) if $xv == $yv; # same references?
|
|
513
499
|
|
|
514
500
|
my @prod = ();
|
|
515
501
|
my ($prod, $car, $cty, $xi, $yi);
|
|
@@ -517,13 +503,13 @@ sub _mul_use_div_64 {
|
|
|
517
503
|
$car = 0;
|
|
518
504
|
$cty = 0;
|
|
519
505
|
# looping through this if $xi == 0 is silly - so optimize it away!
|
|
520
|
-
$xi = (shift
|
|
506
|
+
$xi = (shift(@prod) || 0), next if $xi == 0;
|
|
521
507
|
for $yi (@$yv) {
|
|
522
508
|
$prod = $xi * $yi + ($prod[$cty] || 0) + $car;
|
|
523
509
|
$prod[$cty++] = $prod - ($car = $prod / $BASE) * $BASE;
|
|
524
510
|
}
|
|
525
|
-
$prod[$cty] += $car if $car;
|
|
526
|
-
$xi = shift
|
|
511
|
+
$prod[$cty] += $car if $car; # need really to check for 0?
|
|
512
|
+
$xi = shift(@prod) || 0; # || 0 makes v5.005_3 happy
|
|
527
513
|
}
|
|
528
514
|
push @$xv, @prod;
|
|
529
515
|
$xv;
|
|
@@ -536,15 +522,14 @@ sub _mul_use_div {
|
|
|
536
522
|
my ($c, $xv, $yv) = @_;
|
|
537
523
|
|
|
538
524
|
if (@$yv == 1) {
|
|
539
|
-
# shortcut for two
|
|
525
|
+
# shortcut for two very short numbers (improved by Nathan Zook) works
|
|
526
|
+
# also if xv and yv are the same reference, and handles also $x == 0
|
|
540
527
|
if (@$xv == 1) {
|
|
541
|
-
# shortcut for two very short numbers (improved by Nathan Zook)
|
|
542
|
-
# works also if xv and yv are the same reference, and handles also $x == 0
|
|
543
528
|
if (($xv->[0] *= $yv->[0]) >= $BASE) {
|
|
544
|
-
$xv->[0]
|
|
545
|
-
|
|
529
|
+
my $rem = $xv->[0] % $BASE;
|
|
530
|
+
$xv->[1] = ($xv->[0] - $rem) / $BASE;
|
|
531
|
+
$xv->[0] = $rem;
|
|
546
532
|
}
|
|
547
|
-
;
|
|
548
533
|
return $xv;
|
|
549
534
|
}
|
|
550
535
|
# $x * 0 => 0
|
|
@@ -552,42 +537,44 @@ sub _mul_use_div {
|
|
|
552
537
|
@$xv = (0);
|
|
553
538
|
return $xv;
|
|
554
539
|
}
|
|
540
|
+
|
|
555
541
|
# multiply a large number a by a single element one, so speed up
|
|
556
542
|
my $y = $yv->[0];
|
|
557
543
|
my $car = 0;
|
|
544
|
+
my $rem;
|
|
558
545
|
foreach my $i (@$xv) {
|
|
559
546
|
$i = $i * $y + $car;
|
|
560
|
-
$
|
|
561
|
-
$i
|
|
562
|
-
|
|
563
|
-
#$i = $i * $y + $car; $i -= ($car = $i / $BASE) * $BASE;
|
|
547
|
+
$rem = $i % $BASE;
|
|
548
|
+
$car = ($i - $rem) / $BASE;
|
|
549
|
+
$i = $rem;
|
|
564
550
|
}
|
|
565
551
|
push @$xv, $car if $car != 0;
|
|
566
552
|
return $xv;
|
|
567
553
|
}
|
|
554
|
+
|
|
568
555
|
# shortcut for result $x == 0 => result = 0
|
|
569
|
-
return $xv if
|
|
556
|
+
return $xv if @$xv == 1 && $xv->[0] == 0;
|
|
570
557
|
|
|
571
558
|
# since multiplying $x with $x fails, make copy in this case
|
|
572
|
-
$yv = $c->_copy($xv) if $xv == $yv;
|
|
559
|
+
$yv = $c->_copy($xv) if $xv == $yv; # same references?
|
|
573
560
|
|
|
574
561
|
my @prod = ();
|
|
575
|
-
my ($prod, $car, $cty, $xi, $yi);
|
|
562
|
+
my ($prod, $rem, $car, $cty, $xi, $yi);
|
|
576
563
|
for $xi (@$xv) {
|
|
577
564
|
$car = 0;
|
|
578
565
|
$cty = 0;
|
|
579
566
|
# looping through this if $xi == 0 is silly - so optimize it away!
|
|
580
|
-
$xi = (shift
|
|
567
|
+
$xi = (shift(@prod) || 0), next if $xi == 0;
|
|
581
568
|
for $yi (@$yv) {
|
|
582
569
|
$prod = $xi * $yi + ($prod[$cty] || 0) + $car;
|
|
583
|
-
$
|
|
570
|
+
$rem = $prod % $BASE;
|
|
571
|
+
$car = ($prod - $rem) / $BASE;
|
|
572
|
+
$prod[$cty++] = $rem;
|
|
584
573
|
}
|
|
585
|
-
$prod[$cty] += $car if $car;
|
|
586
|
-
$xi = shift
|
|
574
|
+
$prod[$cty] += $car if $car; # need really to check for 0?
|
|
575
|
+
$xi = shift(@prod) || 0; # || 0 makes v5.005_3 happy
|
|
587
576
|
}
|
|
588
577
|
push @$xv, @prod;
|
|
589
|
-
# can't have leading zeros
|
|
590
|
-
# __strip_zeros($xv);
|
|
591
578
|
$xv;
|
|
592
579
|
}
|
|
593
580
|
|
|
@@ -595,28 +582,19 @@ sub _div_use_mul {
|
|
|
595
582
|
# ref to array, ref to array, modify first array and return remainder if
|
|
596
583
|
# in list context
|
|
597
584
|
|
|
598
|
-
# see comments in _div_use_div() for more explanations
|
|
599
|
-
|
|
600
585
|
my ($c, $x, $yorg) = @_;
|
|
601
586
|
|
|
602
587
|
# the general div algorithm here is about O(N*N) and thus quite slow, so
|
|
603
588
|
# we first check for some special cases and use shortcuts to handle them.
|
|
604
589
|
|
|
605
|
-
# This works, because we store the numbers in a chunked format where each
|
|
606
|
-
# element contains 5..7 digits (depending on system).
|
|
607
|
-
|
|
608
590
|
# if both numbers have only one element:
|
|
609
591
|
if (@$x == 1 && @$yorg == 1) {
|
|
610
592
|
# shortcut, $yorg and $x are two small numbers
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
} else {
|
|
617
|
-
$x->[0] = int($x->[0] / $yorg->[0]);
|
|
618
|
-
return $x;
|
|
619
|
-
}
|
|
593
|
+
my $rem = [ $x->[0] % $yorg->[0] ];
|
|
594
|
+
bless $rem, $c;
|
|
595
|
+
$x->[0] = ($x->[0] - $rem->[0]) / $yorg->[0];
|
|
596
|
+
return ($x, $rem) if wantarray;
|
|
597
|
+
return $x;
|
|
620
598
|
}
|
|
621
599
|
|
|
622
600
|
# if x has more than one, but y has only one element:
|
|
@@ -631,120 +609,120 @@ sub _div_use_mul {
|
|
|
631
609
|
my $b;
|
|
632
610
|
while ($j-- > 0) {
|
|
633
611
|
$b = $r * $BASE + $x->[$j];
|
|
634
|
-
$x->[$j] = int($b/$y);
|
|
635
612
|
$r = $b % $y;
|
|
613
|
+
$x->[$j] = ($b - $r) / $y;
|
|
636
614
|
}
|
|
637
|
-
pop
|
|
615
|
+
pop(@$x) if @$x > 1 && $x->[-1] == 0; # remove any trailing zero
|
|
638
616
|
return ($x, $rem) if wantarray;
|
|
639
617
|
return $x;
|
|
640
618
|
}
|
|
641
619
|
|
|
642
620
|
# now x and y have more than one element
|
|
643
621
|
|
|
644
|
-
# check whether y has more elements than x, if
|
|
622
|
+
# check whether y has more elements than x, if so, the result is 0
|
|
645
623
|
if (@$yorg > @$x) {
|
|
646
624
|
my $rem;
|
|
647
|
-
$rem = $c->_copy($x) if wantarray;
|
|
648
|
-
@$x = 0;
|
|
649
|
-
return ($x, $rem) if wantarray;
|
|
650
|
-
return $x;
|
|
625
|
+
$rem = $c->_copy($x) if wantarray; # make copy
|
|
626
|
+
@$x = 0; # set to 0
|
|
627
|
+
return ($x, $rem) if wantarray; # including remainder?
|
|
628
|
+
return $x; # only x, which is [0] now
|
|
651
629
|
}
|
|
630
|
+
|
|
652
631
|
# check whether the numbers have the same number of elements, in that case
|
|
653
632
|
# the result will fit into one element and can be computed efficiently
|
|
654
633
|
if (@$yorg == @$x) {
|
|
634
|
+
my $cmp = 0;
|
|
635
|
+
for (my $j = $#$x ; $j >= 0 ; --$j) {
|
|
636
|
+
last if $cmp = $x->[$j] - $yorg->[$j];
|
|
637
|
+
}
|
|
655
638
|
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
my $rem = $c->_copy($x) if wantarray; # make copy
|
|
660
|
-
@$x = 0; # set to 0
|
|
661
|
-
return ($x, $rem) if wantarray; # including remainder?
|
|
639
|
+
if ($cmp == 0) { # x = y
|
|
640
|
+
@$x = 1;
|
|
641
|
+
return $x, $c->_zero() if wantarray;
|
|
662
642
|
return $x;
|
|
663
643
|
}
|
|
664
|
-
# now calculate $x / $yorg
|
|
665
|
-
if (length(int($yorg->[-1])) == length(int($x->[-1]))) {
|
|
666
|
-
# same length, so make full compare
|
|
667
644
|
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
$j--;
|
|
674
|
-
}
|
|
675
|
-
# $a contains the result of the compare between X and Y
|
|
676
|
-
# a < 0: x < y, a == 0: x == y, a > 0: x > y
|
|
677
|
-
if ($a <= 0) {
|
|
678
|
-
# a = 0 => x == y => rem 0
|
|
679
|
-
# a < 0 => x < y => rem = x
|
|
680
|
-
my $rem = $a == 0 ? $c->_zero() : $c->_copy($x);
|
|
681
|
-
@$x = 0; # if $a < 0
|
|
682
|
-
$x->[0] = 1 if $a == 0; # $x == $y
|
|
683
|
-
return ($x, $rem) if wantarray;
|
|
684
|
-
return $x;
|
|
645
|
+
if ($cmp < 0) { # x < y
|
|
646
|
+
if (wantarray) {
|
|
647
|
+
my $rem = $c->_copy($x);
|
|
648
|
+
@$x = 0;
|
|
649
|
+
return $x, $rem;
|
|
685
650
|
}
|
|
686
|
-
|
|
651
|
+
@$x = 0;
|
|
652
|
+
return $x;
|
|
687
653
|
}
|
|
688
654
|
}
|
|
689
655
|
|
|
690
656
|
# all other cases:
|
|
691
657
|
|
|
692
|
-
my $y = $c->_copy($yorg);
|
|
658
|
+
my $y = $c->_copy($yorg); # always make copy to preserve
|
|
693
659
|
|
|
694
|
-
my
|
|
695
|
-
|
|
696
|
-
$
|
|
697
|
-
if (
|
|
698
|
-
|
|
660
|
+
my $tmp = $y->[-1] + 1;
|
|
661
|
+
my $rem = $BASE % $tmp;
|
|
662
|
+
my $dd = ($BASE - $rem) / $tmp;
|
|
663
|
+
if ($dd != 1) {
|
|
664
|
+
my $car = 0;
|
|
665
|
+
for my $xi (@$x) {
|
|
699
666
|
$xi = $xi * $dd + $car;
|
|
700
|
-
$xi -= ($car = int($xi * $RBASE)) * $BASE;
|
|
667
|
+
$xi -= ($car = int($xi * $RBASE)) * $BASE; # see USE_MUL
|
|
701
668
|
}
|
|
702
669
|
push(@$x, $car);
|
|
703
670
|
$car = 0;
|
|
704
|
-
for $yi (@$y) {
|
|
671
|
+
for my $yi (@$y) {
|
|
705
672
|
$yi = $yi * $dd + $car;
|
|
706
|
-
$yi -= ($car = int($yi * $RBASE)) * $BASE;
|
|
673
|
+
$yi -= ($car = int($yi * $RBASE)) * $BASE; # see USE_MUL
|
|
707
674
|
}
|
|
708
675
|
} else {
|
|
709
676
|
push(@$x, 0);
|
|
710
677
|
}
|
|
711
|
-
|
|
712
|
-
|
|
678
|
+
|
|
679
|
+
# @q will accumulate the final result, $q contains the current computed
|
|
680
|
+
# part of the final result
|
|
681
|
+
|
|
682
|
+
my @q = ();
|
|
683
|
+
my ($v2, $v1) = @$y[-2, -1];
|
|
713
684
|
$v2 = 0 unless $v2;
|
|
714
685
|
while ($#$x > $#$y) {
|
|
715
|
-
($u2, $u1, $u0) = @$x[-3 .. -1];
|
|
686
|
+
my ($u2, $u1, $u0) = @$x[-3 .. -1];
|
|
716
687
|
$u2 = 0 unless $u2;
|
|
717
688
|
#warn "oups v1 is 0, u0: $u0 $y->[-2] $y->[-1] l ",scalar @$y,"\n"
|
|
718
689
|
# if $v1 == 0;
|
|
719
|
-
$
|
|
720
|
-
|
|
690
|
+
my $tmp = $u0 * $BASE + $u1;
|
|
691
|
+
my $rem = $tmp % $v1;
|
|
692
|
+
my $q = $u0 == $v1 ? $MAX_VAL : (($tmp - $rem) / $v1);
|
|
693
|
+
--$q while $v2 * $q > ($u0 * $BASE + $u1 - $q * $v1) * $BASE + $u2;
|
|
721
694
|
if ($q) {
|
|
722
|
-
|
|
723
|
-
|
|
695
|
+
my $prd;
|
|
696
|
+
my ($car, $bar) = (0, 0);
|
|
697
|
+
for (my $yi = 0, my $xi = $#$x - $#$y - 1; $yi <= $#$y; ++$yi, ++$xi) {
|
|
724
698
|
$prd = $q * $y->[$yi] + $car;
|
|
725
|
-
$prd -= ($car = int($prd * $RBASE)) * $BASE;
|
|
726
|
-
$x->[$xi] += $BASE if
|
|
699
|
+
$prd -= ($car = int($prd * $RBASE)) * $BASE; # see USE_MUL
|
|
700
|
+
$x->[$xi] += $BASE if $bar = (($x->[$xi] -= $prd + $bar) < 0);
|
|
727
701
|
}
|
|
728
702
|
if ($x->[-1] < $car + $bar) {
|
|
729
703
|
$car = 0;
|
|
730
704
|
--$q;
|
|
731
|
-
for ($yi = 0, $xi = $#$x - $#$y-1; $yi <= $#$y; ++$yi, ++$xi) {
|
|
705
|
+
for (my $yi = 0, my $xi = $#$x - $#$y - 1; $yi <= $#$y; ++$yi, ++$xi) {
|
|
732
706
|
$x->[$xi] -= $BASE
|
|
733
|
-
if
|
|
707
|
+
if $car = (($x->[$xi] += $y->[$yi] + $car) >= $BASE);
|
|
734
708
|
}
|
|
735
709
|
}
|
|
736
710
|
}
|
|
737
711
|
pop(@$x);
|
|
738
712
|
unshift(@q, $q);
|
|
739
713
|
}
|
|
714
|
+
|
|
740
715
|
if (wantarray) {
|
|
741
716
|
my $d = bless [], $c;
|
|
742
717
|
if ($dd != 1) {
|
|
743
|
-
$car = 0;
|
|
744
|
-
|
|
718
|
+
my $car = 0;
|
|
719
|
+
my ($prd, $rem);
|
|
720
|
+
for my $xi (reverse @$x) {
|
|
745
721
|
$prd = $car * $BASE + $xi;
|
|
746
|
-
$
|
|
747
|
-
|
|
722
|
+
$rem = $prd % $dd;
|
|
723
|
+
$tmp = ($prd - $rem) / $dd;
|
|
724
|
+
$car = $rem;
|
|
725
|
+
unshift @$d, $tmp;
|
|
748
726
|
}
|
|
749
727
|
} else {
|
|
750
728
|
@$d = @$x;
|
|
@@ -762,29 +740,29 @@ sub _div_use_mul {
|
|
|
762
740
|
sub _div_use_div_64 {
|
|
763
741
|
# ref to array, ref to array, modify first array and return remainder if
|
|
764
742
|
# in list context
|
|
765
|
-
# This version works on 64 bit integers
|
|
766
|
-
my ($c, $x, $yorg) = @_;
|
|
767
743
|
|
|
744
|
+
# This version works on integers
|
|
768
745
|
use integer;
|
|
746
|
+
|
|
747
|
+
my ($c, $x, $yorg) = @_;
|
|
748
|
+
|
|
769
749
|
# the general div algorithm here is about O(N*N) and thus quite slow, so
|
|
770
750
|
# we first check for some special cases and use shortcuts to handle them.
|
|
771
751
|
|
|
772
|
-
# This works, because we store the numbers in a chunked format where each
|
|
773
|
-
# element contains 5..7 digits (depending on system).
|
|
774
|
-
|
|
775
752
|
# if both numbers have only one element:
|
|
776
753
|
if (@$x == 1 && @$yorg == 1) {
|
|
777
754
|
# shortcut, $yorg and $x are two small numbers
|
|
778
755
|
if (wantarray) {
|
|
779
756
|
my $rem = [ $x->[0] % $yorg->[0] ];
|
|
780
757
|
bless $rem, $c;
|
|
781
|
-
$x->[0] =
|
|
758
|
+
$x->[0] = $x->[0] / $yorg->[0];
|
|
782
759
|
return ($x, $rem);
|
|
783
760
|
} else {
|
|
784
|
-
$x->[0] =
|
|
761
|
+
$x->[0] = $x->[0] / $yorg->[0];
|
|
785
762
|
return $x;
|
|
786
763
|
}
|
|
787
764
|
}
|
|
765
|
+
|
|
788
766
|
# if x has more than one, but y has only one element:
|
|
789
767
|
if (@$yorg == 1) {
|
|
790
768
|
my $rem;
|
|
@@ -797,78 +775,67 @@ sub _div_use_div_64 {
|
|
|
797
775
|
my $b;
|
|
798
776
|
while ($j-- > 0) {
|
|
799
777
|
$b = $r * $BASE + $x->[$j];
|
|
800
|
-
$x->[$j] = int($b/$y);
|
|
801
778
|
$r = $b % $y;
|
|
779
|
+
$x->[$j] = $b / $y;
|
|
802
780
|
}
|
|
803
|
-
pop
|
|
781
|
+
pop(@$x) if @$x > 1 && $x->[-1] == 0; # remove any trailing zero
|
|
804
782
|
return ($x, $rem) if wantarray;
|
|
805
783
|
return $x;
|
|
806
784
|
}
|
|
785
|
+
|
|
807
786
|
# now x and y have more than one element
|
|
808
787
|
|
|
809
|
-
# check whether y has more elements than x, if
|
|
788
|
+
# check whether y has more elements than x, if so, the result is 0
|
|
810
789
|
if (@$yorg > @$x) {
|
|
811
790
|
my $rem;
|
|
812
|
-
$rem = $c->_copy($x) if wantarray;
|
|
813
|
-
@$x = 0;
|
|
814
|
-
return ($x, $rem) if wantarray;
|
|
815
|
-
return $x;
|
|
791
|
+
$rem = $c->_copy($x) if wantarray; # make copy
|
|
792
|
+
@$x = 0; # set to 0
|
|
793
|
+
return ($x, $rem) if wantarray; # including remainder?
|
|
794
|
+
return $x; # only x, which is [0] now
|
|
816
795
|
}
|
|
796
|
+
|
|
817
797
|
# check whether the numbers have the same number of elements, in that case
|
|
818
798
|
# the result will fit into one element and can be computed efficiently
|
|
819
799
|
if (@$yorg == @$x) {
|
|
820
|
-
my $
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
if (length(int($yorg->[-1])) > length(int($x->[-1]))) {
|
|
824
|
-
$rem = $c->_copy($x) if wantarray; # make copy
|
|
825
|
-
@$x = 0; # set to 0
|
|
826
|
-
return ($x, $rem) if wantarray; # including remainder?
|
|
827
|
-
return $x;
|
|
800
|
+
my $cmp = 0;
|
|
801
|
+
for (my $j = $#$x ; $j >= 0 ; --$j) {
|
|
802
|
+
last if $cmp = $x->[$j] - $yorg->[$j];
|
|
828
803
|
}
|
|
829
|
-
# now calculate $x / $yorg
|
|
830
804
|
|
|
831
|
-
if (
|
|
832
|
-
|
|
805
|
+
if ($cmp == 0) { # x = y
|
|
806
|
+
@$x = 1;
|
|
807
|
+
return $x, $c->_zero() if wantarray;
|
|
808
|
+
return $x;
|
|
809
|
+
}
|
|
833
810
|
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
$j--;
|
|
840
|
-
}
|
|
841
|
-
# $a contains the result of the compare between X and Y
|
|
842
|
-
# a < 0: x < y, a == 0: x == y, a > 0: x > y
|
|
843
|
-
if ($a <= 0) {
|
|
844
|
-
$rem = $c->_zero(); # a = 0 => x == y => rem 0
|
|
845
|
-
$rem = $c->_copy($x) if $a != 0; # a < 0 => x < y => rem = x
|
|
846
|
-
@$x = 0; # if $a < 0
|
|
847
|
-
$x->[0] = 1 if $a == 0; # $x == $y
|
|
848
|
-
return ($x, $rem) if wantarray; # including remainder?
|
|
849
|
-
return $x;
|
|
811
|
+
if ($cmp < 0) { # x < y
|
|
812
|
+
if (wantarray) {
|
|
813
|
+
my $rem = $c->_copy($x);
|
|
814
|
+
@$x = 0;
|
|
815
|
+
return $x, $rem;
|
|
850
816
|
}
|
|
851
|
-
|
|
817
|
+
@$x = 0;
|
|
818
|
+
return $x;
|
|
852
819
|
}
|
|
853
820
|
}
|
|
854
821
|
|
|
855
822
|
# all other cases:
|
|
856
823
|
|
|
857
|
-
my $y = $c->_copy($yorg);
|
|
858
|
-
|
|
859
|
-
my ($car, $bar, $prd, $dd, $xi, $yi, @q, $v2, $v1, $tmp, $q, $u2, $u1, $u0);
|
|
824
|
+
my $y = $c->_copy($yorg); # always make copy to preserve
|
|
860
825
|
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
826
|
+
my $tmp;
|
|
827
|
+
my $dd = $BASE / ($y->[-1] + 1);
|
|
828
|
+
if ($dd != 1) {
|
|
829
|
+
my $car = 0;
|
|
830
|
+
for my $xi (@$x) {
|
|
864
831
|
$xi = $xi * $dd + $car;
|
|
865
|
-
$xi -= ($car =
|
|
832
|
+
$xi -= ($car = $xi / $BASE) * $BASE;
|
|
866
833
|
}
|
|
867
834
|
push(@$x, $car);
|
|
868
835
|
$car = 0;
|
|
869
|
-
for $yi (@$y) {
|
|
836
|
+
for my $yi (@$y) {
|
|
870
837
|
$yi = $yi * $dd + $car;
|
|
871
|
-
$yi -= ($car =
|
|
838
|
+
$yi -= ($car = $yi / $BASE) * $BASE;
|
|
872
839
|
}
|
|
873
840
|
} else {
|
|
874
841
|
push(@$x, 0);
|
|
@@ -877,43 +844,48 @@ sub _div_use_div_64 {
|
|
|
877
844
|
# @q will accumulate the final result, $q contains the current computed
|
|
878
845
|
# part of the final result
|
|
879
846
|
|
|
880
|
-
@q = ();
|
|
881
|
-
($v2, $v1) = @$y[-2, -1];
|
|
847
|
+
my @q = ();
|
|
848
|
+
my ($v2, $v1) = @$y[-2, -1];
|
|
882
849
|
$v2 = 0 unless $v2;
|
|
883
850
|
while ($#$x > $#$y) {
|
|
884
|
-
($u2, $u1, $u0) = @$x[-3
|
|
851
|
+
my ($u2, $u1, $u0) = @$x[-3 .. -1];
|
|
885
852
|
$u2 = 0 unless $u2;
|
|
886
853
|
#warn "oups v1 is 0, u0: $u0 $y->[-2] $y->[-1] l ",scalar @$y,"\n"
|
|
887
854
|
# if $v1 == 0;
|
|
888
|
-
$
|
|
889
|
-
|
|
855
|
+
my $tmp = $u0 * $BASE + $u1;
|
|
856
|
+
my $rem = $tmp % $v1;
|
|
857
|
+
my $q = $u0 == $v1 ? $MAX_VAL : (($tmp - $rem) / $v1);
|
|
858
|
+
--$q while $v2 * $q > ($u0 * $BASE + $u1 - $q * $v1) * $BASE + $u2;
|
|
890
859
|
if ($q) {
|
|
891
|
-
|
|
892
|
-
|
|
860
|
+
my $prd;
|
|
861
|
+
my ($car, $bar) = (0, 0);
|
|
862
|
+
for (my $yi = 0, my $xi = $#$x - $#$y - 1; $yi <= $#$y; ++$yi, ++$xi) {
|
|
893
863
|
$prd = $q * $y->[$yi] + $car;
|
|
894
864
|
$prd -= ($car = int($prd / $BASE)) * $BASE;
|
|
895
|
-
$x->[$xi] += $BASE if
|
|
865
|
+
$x->[$xi] += $BASE if $bar = (($x->[$xi] -= $prd + $bar) < 0);
|
|
896
866
|
}
|
|
897
867
|
if ($x->[-1] < $car + $bar) {
|
|
898
868
|
$car = 0;
|
|
899
869
|
--$q;
|
|
900
|
-
for ($yi = 0, $xi = $#$x - $#$y - 1; $yi <= $#$y; ++$yi, ++$xi) {
|
|
870
|
+
for (my $yi = 0, my $xi = $#$x - $#$y - 1; $yi <= $#$y; ++$yi, ++$xi) {
|
|
901
871
|
$x->[$xi] -= $BASE
|
|
902
|
-
if
|
|
872
|
+
if $car = (($x->[$xi] += $y->[$yi] + $car) >= $BASE);
|
|
903
873
|
}
|
|
904
874
|
}
|
|
905
875
|
}
|
|
906
876
|
pop(@$x);
|
|
907
877
|
unshift(@q, $q);
|
|
908
878
|
}
|
|
879
|
+
|
|
909
880
|
if (wantarray) {
|
|
910
881
|
my $d = bless [], $c;
|
|
911
882
|
if ($dd != 1) {
|
|
912
|
-
$car = 0;
|
|
913
|
-
|
|
883
|
+
my $car = 0;
|
|
884
|
+
my $prd;
|
|
885
|
+
for my $xi (reverse @$x) {
|
|
914
886
|
$prd = $car * $BASE + $xi;
|
|
915
|
-
$car = $prd - ($tmp =
|
|
916
|
-
unshift
|
|
887
|
+
$car = $prd - ($tmp = $prd / $dd) * $dd;
|
|
888
|
+
unshift @$d, $tmp;
|
|
917
889
|
}
|
|
918
890
|
} else {
|
|
919
891
|
@$d = @$x;
|
|
@@ -931,27 +903,22 @@ sub _div_use_div_64 {
|
|
|
931
903
|
sub _div_use_div {
|
|
932
904
|
# ref to array, ref to array, modify first array and return remainder if
|
|
933
905
|
# in list context
|
|
906
|
+
|
|
934
907
|
my ($c, $x, $yorg) = @_;
|
|
935
908
|
|
|
936
909
|
# the general div algorithm here is about O(N*N) and thus quite slow, so
|
|
937
910
|
# we first check for some special cases and use shortcuts to handle them.
|
|
938
911
|
|
|
939
|
-
# This works, because we store the numbers in a chunked format where each
|
|
940
|
-
# element contains 5..7 digits (depending on system).
|
|
941
|
-
|
|
942
912
|
# if both numbers have only one element:
|
|
943
913
|
if (@$x == 1 && @$yorg == 1) {
|
|
944
914
|
# shortcut, $yorg and $x are two small numbers
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
} else {
|
|
951
|
-
$x->[0] = int($x->[0] / $yorg->[0]);
|
|
952
|
-
return $x;
|
|
953
|
-
}
|
|
915
|
+
my $rem = [ $x->[0] % $yorg->[0] ];
|
|
916
|
+
bless $rem, $c;
|
|
917
|
+
$x->[0] = ($x->[0] - $rem->[0]) / $yorg->[0];
|
|
918
|
+
return ($x, $rem) if wantarray;
|
|
919
|
+
return $x;
|
|
954
920
|
}
|
|
921
|
+
|
|
955
922
|
# if x has more than one, but y has only one element:
|
|
956
923
|
if (@$yorg == 1) {
|
|
957
924
|
my $rem;
|
|
@@ -964,80 +931,72 @@ sub _div_use_div {
|
|
|
964
931
|
my $b;
|
|
965
932
|
while ($j-- > 0) {
|
|
966
933
|
$b = $r * $BASE + $x->[$j];
|
|
967
|
-
$x->[$j] = int($b/$y);
|
|
968
934
|
$r = $b % $y;
|
|
935
|
+
$x->[$j] = ($b - $r) / $y;
|
|
969
936
|
}
|
|
970
|
-
pop
|
|
937
|
+
pop(@$x) if @$x > 1 && $x->[-1] == 0; # remove any trailing zero
|
|
971
938
|
return ($x, $rem) if wantarray;
|
|
972
939
|
return $x;
|
|
973
940
|
}
|
|
941
|
+
|
|
974
942
|
# now x and y have more than one element
|
|
975
943
|
|
|
976
|
-
# check whether y has more elements than x, if
|
|
944
|
+
# check whether y has more elements than x, if so, the result is 0
|
|
977
945
|
if (@$yorg > @$x) {
|
|
978
946
|
my $rem;
|
|
979
|
-
$rem = $c->_copy($x) if wantarray;
|
|
980
|
-
@$x = 0;
|
|
981
|
-
return ($x, $rem) if wantarray;
|
|
982
|
-
return $x;
|
|
947
|
+
$rem = $c->_copy($x) if wantarray; # make copy
|
|
948
|
+
@$x = 0; # set to 0
|
|
949
|
+
return ($x, $rem) if wantarray; # including remainder?
|
|
950
|
+
return $x; # only x, which is [0] now
|
|
983
951
|
}
|
|
952
|
+
|
|
984
953
|
# check whether the numbers have the same number of elements, in that case
|
|
985
954
|
# the result will fit into one element and can be computed efficiently
|
|
986
955
|
if (@$yorg == @$x) {
|
|
987
|
-
my $
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
if (length(int($yorg->[-1])) > length(int($x->[-1]))) {
|
|
991
|
-
$rem = $c->_copy($x) if wantarray; # make copy
|
|
992
|
-
@$x = 0; # set to 0
|
|
993
|
-
return ($x, $rem) if wantarray; # including remainder?
|
|
994
|
-
return $x;
|
|
956
|
+
my $cmp = 0;
|
|
957
|
+
for (my $j = $#$x ; $j >= 0 ; --$j) {
|
|
958
|
+
last if $cmp = $x->[$j] - $yorg->[$j];
|
|
995
959
|
}
|
|
996
|
-
# now calculate $x / $yorg
|
|
997
960
|
|
|
998
|
-
if (
|
|
999
|
-
|
|
961
|
+
if ($cmp == 0) { # x = y
|
|
962
|
+
@$x = 1;
|
|
963
|
+
return $x, $c->_zero() if wantarray;
|
|
964
|
+
return $x;
|
|
965
|
+
}
|
|
1000
966
|
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
while ($j >= 0) {
|
|
1005
|
-
last if ($a = $x->[$j] - $yorg->[$j]);
|
|
1006
|
-
$j--;
|
|
1007
|
-
}
|
|
1008
|
-
# $a contains the result of the compare between X and Y
|
|
1009
|
-
# a < 0: x < y, a == 0: x == y, a > 0: x > y
|
|
1010
|
-
if ($a <= 0) {
|
|
1011
|
-
$rem = $c->_zero(); # a = 0 => x == y => rem 0
|
|
1012
|
-
$rem = $c->_copy($x) if $a != 0; # a < 0 => x < y => rem = x
|
|
967
|
+
if ($cmp < 0) { # x < y
|
|
968
|
+
if (wantarray) {
|
|
969
|
+
my $rem = $c->_copy($x);
|
|
1013
970
|
@$x = 0;
|
|
1014
|
-
$x
|
|
1015
|
-
$x->[0] = 1 if $a == 0; # $x == $y
|
|
1016
|
-
return ($x, $rem) if wantarray; # including remainder?
|
|
1017
|
-
return $x;
|
|
971
|
+
return $x, $rem;
|
|
1018
972
|
}
|
|
1019
|
-
|
|
1020
|
-
|
|
973
|
+
@$x = 0;
|
|
974
|
+
return $x;
|
|
1021
975
|
}
|
|
1022
976
|
}
|
|
1023
977
|
|
|
1024
978
|
# all other cases:
|
|
1025
979
|
|
|
1026
|
-
my $y = $c->_copy($yorg);
|
|
1027
|
-
|
|
1028
|
-
my ($car, $bar, $prd, $dd, $xi, $yi, @q, $v2, $v1, @d, $tmp, $q, $u2, $u1, $u0);
|
|
980
|
+
my $y = $c->_copy($yorg); # always make copy to preserve
|
|
1029
981
|
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
982
|
+
my $tmp = $y->[-1] + 1;
|
|
983
|
+
my $rem = $BASE % $tmp;
|
|
984
|
+
my $dd = ($BASE - $rem) / $tmp;
|
|
985
|
+
if ($dd != 1) {
|
|
986
|
+
my $car = 0;
|
|
987
|
+
for my $xi (@$x) {
|
|
1033
988
|
$xi = $xi * $dd + $car;
|
|
1034
|
-
$
|
|
989
|
+
$rem = $xi % $BASE;
|
|
990
|
+
$car = ($xi - $rem) / $BASE;
|
|
991
|
+
$xi = $rem;
|
|
1035
992
|
}
|
|
1036
993
|
push(@$x, $car);
|
|
1037
994
|
$car = 0;
|
|
1038
|
-
for $yi (@$y) {
|
|
995
|
+
for my $yi (@$y) {
|
|
1039
996
|
$yi = $yi * $dd + $car;
|
|
1040
|
-
$
|
|
997
|
+
$rem = $yi % $BASE;
|
|
998
|
+
$car = ($yi - $rem) / $BASE;
|
|
999
|
+
$yi = $rem;
|
|
1041
1000
|
}
|
|
1042
1001
|
} else {
|
|
1043
1002
|
push(@$x, 0);
|
|
@@ -1046,43 +1005,52 @@ sub _div_use_div {
|
|
|
1046
1005
|
# @q will accumulate the final result, $q contains the current computed
|
|
1047
1006
|
# part of the final result
|
|
1048
1007
|
|
|
1049
|
-
@q = ();
|
|
1050
|
-
($v2, $v1) = @$y[-2, -1];
|
|
1008
|
+
my @q = ();
|
|
1009
|
+
my ($v2, $v1) = @$y[-2, -1];
|
|
1051
1010
|
$v2 = 0 unless $v2;
|
|
1052
1011
|
while ($#$x > $#$y) {
|
|
1053
|
-
($u2, $u1, $u0) = @$x[-3
|
|
1012
|
+
my ($u2, $u1, $u0) = @$x[-3 .. -1];
|
|
1054
1013
|
$u2 = 0 unless $u2;
|
|
1055
1014
|
#warn "oups v1 is 0, u0: $u0 $y->[-2] $y->[-1] l ",scalar @$y,"\n"
|
|
1056
1015
|
# if $v1 == 0;
|
|
1057
|
-
$
|
|
1058
|
-
|
|
1016
|
+
my $tmp = $u0 * $BASE + $u1;
|
|
1017
|
+
my $rem = $tmp % $v1;
|
|
1018
|
+
my $q = $u0 == $v1 ? $MAX_VAL : (($tmp - $rem) / $v1);
|
|
1019
|
+
--$q while $v2 * $q > ($u0 * $BASE + $u1 - $q * $v1) * $BASE + $u2;
|
|
1059
1020
|
if ($q) {
|
|
1060
|
-
|
|
1061
|
-
|
|
1021
|
+
my $prd;
|
|
1022
|
+
my ($car, $bar) = (0, 0);
|
|
1023
|
+
for (my $yi = 0, my $xi = $#$x - $#$y - 1; $yi <= $#$y; ++$yi, ++$xi) {
|
|
1062
1024
|
$prd = $q * $y->[$yi] + $car;
|
|
1063
|
-
$
|
|
1064
|
-
$
|
|
1025
|
+
$rem = $prd % $BASE;
|
|
1026
|
+
$car = ($prd - $rem) / $BASE;
|
|
1027
|
+
$prd -= $car * $BASE;
|
|
1028
|
+
$x->[$xi] += $BASE if $bar = (($x->[$xi] -= $prd + $bar) < 0);
|
|
1065
1029
|
}
|
|
1066
1030
|
if ($x->[-1] < $car + $bar) {
|
|
1067
1031
|
$car = 0;
|
|
1068
1032
|
--$q;
|
|
1069
|
-
for ($yi = 0, $xi = $#$x - $#$y - 1; $yi <= $#$y; ++$yi, ++$xi) {
|
|
1033
|
+
for (my $yi = 0, my $xi = $#$x - $#$y - 1; $yi <= $#$y; ++$yi, ++$xi) {
|
|
1070
1034
|
$x->[$xi] -= $BASE
|
|
1071
|
-
if
|
|
1035
|
+
if $car = (($x->[$xi] += $y->[$yi] + $car) >= $BASE);
|
|
1072
1036
|
}
|
|
1073
1037
|
}
|
|
1074
1038
|
}
|
|
1075
1039
|
pop(@$x);
|
|
1076
1040
|
unshift(@q, $q);
|
|
1077
1041
|
}
|
|
1042
|
+
|
|
1078
1043
|
if (wantarray) {
|
|
1079
1044
|
my $d = bless [], $c;
|
|
1080
1045
|
if ($dd != 1) {
|
|
1081
|
-
$car = 0;
|
|
1082
|
-
|
|
1046
|
+
my $car = 0;
|
|
1047
|
+
my ($prd, $rem);
|
|
1048
|
+
for my $xi (reverse @$x) {
|
|
1083
1049
|
$prd = $car * $BASE + $xi;
|
|
1084
|
-
$
|
|
1085
|
-
|
|
1050
|
+
$rem = $prd % $dd;
|
|
1051
|
+
$tmp = ($prd - $rem) / $dd;
|
|
1052
|
+
$car = $rem;
|
|
1053
|
+
unshift @$d, $tmp;
|
|
1086
1054
|
}
|
|
1087
1055
|
} else {
|
|
1088
1056
|
@$d = @$x;
|
|
@@ -1385,7 +1353,7 @@ sub _rsft {
|
|
|
1385
1353
|
$dst++;
|
|
1386
1354
|
}
|
|
1387
1355
|
splice(@$x, $dst) if $dst > 0; # kill left-over array elems
|
|
1388
|
-
pop
|
|
1356
|
+
pop(@$x) if $x->[-1] == 0 && @$x > 1; # kill last element if 0
|
|
1389
1357
|
} # else rem == 0
|
|
1390
1358
|
$x;
|
|
1391
1359
|
}
|
|
@@ -1393,49 +1361,64 @@ sub _rsft {
|
|
|
1393
1361
|
sub _lsft {
|
|
1394
1362
|
my ($c, $x, $n, $b) = @_;
|
|
1395
1363
|
|
|
1396
|
-
return $x if $c->_is_zero($x);
|
|
1397
|
-
|
|
1398
|
-
#
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
#
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
my $
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
$
|
|
1364
|
+
return $x if $c->_is_zero($x) || $c->_is_zero($n);
|
|
1365
|
+
|
|
1366
|
+
# For backwards compatibility, allow the base $b to be a scalar.
|
|
1367
|
+
|
|
1368
|
+
$b = $c->_new($b) unless ref $b;
|
|
1369
|
+
|
|
1370
|
+
# If the base is a power of 10, use shifting, since the internal
|
|
1371
|
+
# representation is in base 10eX.
|
|
1372
|
+
|
|
1373
|
+
my $bstr = $c->_str($b);
|
|
1374
|
+
if ($bstr =~ /^1(0+)\z/) {
|
|
1375
|
+
|
|
1376
|
+
# Adjust $n so that we're shifting in base 10. Do this by multiplying
|
|
1377
|
+
# $n by the base 10 logarithm of $b: $b ** $n = 10 ** (log10($b) * $n).
|
|
1378
|
+
|
|
1379
|
+
my $log10b = length($1);
|
|
1380
|
+
$n = $c->_mul($c->_new($log10b), $n);
|
|
1381
|
+
$n = $c->_num($n); # shift-len as normal int
|
|
1382
|
+
|
|
1383
|
+
# $q is the number of places to shift the elements within the array,
|
|
1384
|
+
# and $r is the number of places to shift the values within the
|
|
1385
|
+
# elements.
|
|
1386
|
+
|
|
1387
|
+
my $r = $n % $BASE_LEN;
|
|
1388
|
+
my $q = ($n - $r) / $BASE_LEN;
|
|
1389
|
+
|
|
1390
|
+
# If we must shift the values within the elements ...
|
|
1391
|
+
|
|
1392
|
+
if ($r) {
|
|
1393
|
+
my $i = @$x; # index
|
|
1394
|
+
$x->[$i] = 0; # initialize most significant element
|
|
1395
|
+
my $z = '0' x $BASE_LEN;
|
|
1396
|
+
my $vd;
|
|
1397
|
+
while ($i >= 0) {
|
|
1398
|
+
$vd = $x->[$i];
|
|
1399
|
+
$vd = $z . $vd;
|
|
1400
|
+
$vd = substr($vd, $r - $BASE_LEN, $BASE_LEN - $r);
|
|
1401
|
+
$vd .= $i > 0 ? substr($z . $x->[$i - 1], -$BASE_LEN, $r)
|
|
1402
|
+
: '0' x $r;
|
|
1403
|
+
$vd = substr($vd, -$BASE_LEN, $BASE_LEN) if length($vd) > $BASE_LEN;
|
|
1404
|
+
$x->[$i] = int($vd); # e.g., "0...048" -> 48 etc.
|
|
1405
|
+
$i--;
|
|
1406
|
+
}
|
|
1407
|
+
|
|
1408
|
+
pop(@$x) if $x->[-1] == 0; # if most significant element is zero
|
|
1426
1409
|
}
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1410
|
+
|
|
1411
|
+
# If we must shift the elements within the array ...
|
|
1412
|
+
|
|
1413
|
+
if ($q) {
|
|
1414
|
+
unshift @$x, (0) x $q;
|
|
1430
1415
|
}
|
|
1431
|
-
|
|
1432
|
-
splice @$x, -1 if $x->[-1] == 0;
|
|
1433
|
-
return $x;
|
|
1416
|
+
|
|
1434
1417
|
} else {
|
|
1435
|
-
$
|
|
1436
|
-
#print $c->_str($b);
|
|
1437
|
-
return $c->_mul($x, $c->_pow($b, $n));
|
|
1418
|
+
$x = $c->_mul($x, $c->_pow($b, $n));
|
|
1438
1419
|
}
|
|
1420
|
+
|
|
1421
|
+
return $x;
|
|
1439
1422
|
}
|
|
1440
1423
|
|
|
1441
1424
|
sub _pow {
|