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.
Files changed (253) hide show
  1. package/README.md +6 -0
  2. package/bin/exiftool.exe +0 -0
  3. package/bin/exiftool_files/Changes +44 -0
  4. package/bin/exiftool_files/Licenses_Strawberry_Perl.zip +0 -0
  5. package/bin/exiftool_files/README +3 -2
  6. package/bin/exiftool_files/exiftool.pl +36 -14
  7. package/bin/exiftool_files/lib/Archive/Zip/Archive.pm +399 -65
  8. package/bin/exiftool_files/lib/Archive/Zip/DirectoryMember.pm +1 -1
  9. package/bin/exiftool_files/lib/Archive/Zip/FileMember.pm +1 -1
  10. package/bin/exiftool_files/lib/Archive/Zip/Member.pm +499 -195
  11. package/bin/exiftool_files/lib/Archive/Zip/NewFileMember.pm +1 -1
  12. package/bin/exiftool_files/lib/Archive/Zip/StringMember.pm +2 -2
  13. package/bin/exiftool_files/lib/Archive/Zip/ZipFileMember.pm +79 -20
  14. package/bin/exiftool_files/lib/Archive/Zip.pm +179 -29
  15. package/bin/exiftool_files/lib/AutoLoader.pm +453 -0
  16. package/bin/exiftool_files/lib/B/Deparse.pm +209 -137
  17. package/bin/exiftool_files/lib/B.pm +1 -1
  18. package/bin/exiftool_files/lib/Benchmark.pm +1123 -0
  19. package/bin/exiftool_files/lib/Class/Struct.pm +2 -2
  20. package/bin/exiftool_files/lib/Compress/Raw/Bzip2.pm +14 -9
  21. package/bin/exiftool_files/lib/Compress/Raw/Lzma.pm +982 -0
  22. package/bin/exiftool_files/lib/Compress/Raw/Zlib.pm +91 -86
  23. package/bin/exiftool_files/lib/Compress/Zlib.pm +105 -100
  24. package/bin/exiftool_files/lib/Config.pm +9 -9
  25. package/bin/exiftool_files/lib/Config_heavy.pl +36 -33
  26. package/bin/exiftool_files/lib/CryptX.pm +2 -82
  27. package/bin/exiftool_files/lib/Data/Dumper.pm +2 -2
  28. package/bin/exiftool_files/lib/Digest/MD5.pm +12 -9
  29. package/bin/exiftool_files/lib/Digest/Perl/MD5.pm +1 -191
  30. package/bin/exiftool_files/lib/Digest/base.pm +26 -20
  31. package/bin/exiftool_files/lib/DynaLoader.pm +7 -4
  32. package/bin/exiftool_files/lib/Encode.pm +3 -3
  33. package/bin/exiftool_files/lib/Errno.pm +13 -13
  34. package/bin/exiftool_files/lib/Exporter/Heavy.pm +2 -2
  35. package/bin/exiftool_files/lib/Exporter.pm +1 -1
  36. package/bin/exiftool_files/lib/ExtUtils/Command/MM.pm +323 -0
  37. package/bin/exiftool_files/lib/ExtUtils/Command.pm +382 -0
  38. package/bin/exiftool_files/lib/File/Find.pm +1 -1
  39. package/bin/exiftool_files/lib/File/Glob.pm +1 -8
  40. package/bin/exiftool_files/lib/File/GlobMapper.pm +2 -2
  41. package/bin/exiftool_files/lib/File/HomeDir/Darwin/Carbon.pm +2 -40
  42. package/bin/exiftool_files/lib/File/HomeDir/Darwin/Cocoa.pm +2 -34
  43. package/bin/exiftool_files/lib/File/HomeDir/Darwin.pm +2 -28
  44. package/bin/exiftool_files/lib/File/HomeDir/Driver.pm +2 -35
  45. package/bin/exiftool_files/lib/File/HomeDir/FreeDesktop.pm +2 -62
  46. package/bin/exiftool_files/lib/File/HomeDir/MacOS9.pm +2 -53
  47. package/bin/exiftool_files/lib/File/HomeDir/Test.pm +2 -43
  48. package/bin/exiftool_files/lib/File/HomeDir/Unix.pm +2 -53
  49. package/bin/exiftool_files/lib/File/HomeDir/Windows.pm +2 -69
  50. package/bin/exiftool_files/lib/File/HomeDir.pm +5 -416
  51. package/bin/exiftool_files/lib/File/Path.pm +3 -3
  52. package/bin/exiftool_files/lib/File/Spec/Win32.pm +2 -2
  53. package/bin/exiftool_files/lib/File/Temp.pm +70 -35
  54. package/bin/exiftool_files/lib/File/Which.pm +1 -240
  55. package/bin/exiftool_files/lib/File/stat.pm +3 -2
  56. package/bin/exiftool_files/lib/IO/Compress/Adapter/Bzip2.pm +16 -17
  57. package/bin/exiftool_files/lib/IO/Compress/Adapter/Deflate.pm +19 -20
  58. package/bin/exiftool_files/lib/IO/Compress/Base/Common.pm +5 -5
  59. package/bin/exiftool_files/lib/IO/Compress/Base.pm +35 -26
  60. package/bin/exiftool_files/lib/IO/Compress/Brotli.pm +159 -0
  61. package/bin/exiftool_files/lib/IO/Compress/Bzip2.pm +50 -25
  62. package/bin/exiftool_files/lib/IO/Compress/Gzip/Constants.pm +6 -6
  63. package/bin/exiftool_files/lib/IO/Compress/Gzip.pm +58 -32
  64. package/bin/exiftool_files/lib/IO/Compress/RawDeflate.pm +63 -38
  65. package/bin/exiftool_files/lib/IO/Compress/Zlib/Extra.pm +20 -20
  66. package/bin/exiftool_files/lib/IO/Dir.pm +1 -1
  67. package/bin/exiftool_files/lib/IO/File.pm +1 -1
  68. package/bin/exiftool_files/lib/IO/Handle.pm +1 -21
  69. package/bin/exiftool_files/lib/IO/Pipe.pm +1 -1
  70. package/bin/exiftool_files/lib/IO/Seekable.pm +1 -1
  71. package/bin/exiftool_files/lib/IO/Select.pm +16 -2
  72. package/bin/exiftool_files/lib/IO/Socket/INET.pm +14 -9
  73. package/bin/exiftool_files/lib/IO/Socket/UNIX.pm +17 -1
  74. package/bin/exiftool_files/lib/IO/Socket.pm +474 -126
  75. package/bin/exiftool_files/lib/IO/String.pm +425 -0
  76. package/bin/exiftool_files/lib/IO/Uncompress/Adapter/Inflate.pm +13 -14
  77. package/bin/exiftool_files/lib/IO/Uncompress/Base.pm +142 -132
  78. package/bin/exiftool_files/lib/IO/Uncompress/Brotli.pm +119 -0
  79. package/bin/exiftool_files/lib/IO/Uncompress/Gunzip.pm +43 -37
  80. package/bin/exiftool_files/lib/IO/Uncompress/RawInflate.pm +49 -43
  81. package/bin/exiftool_files/lib/IO.pm +2 -2
  82. package/bin/exiftool_files/lib/Image/ExifTool/BuildTagLookup.pm +44 -31
  83. package/bin/exiftool_files/lib/Image/ExifTool/CanonVRD.pm +2 -2
  84. package/bin/exiftool_files/lib/Image/ExifTool/FujiFilm.pm +20 -7
  85. package/bin/exiftool_files/lib/Image/ExifTool/GM.pm +543 -0
  86. package/bin/exiftool_files/lib/Image/ExifTool/Geolocation.pm +332 -149
  87. package/bin/exiftool_files/lib/Image/ExifTool/Geotag.pm +9 -4
  88. package/bin/exiftool_files/lib/Image/ExifTool/M2TS.pm +32 -4
  89. package/bin/exiftool_files/lib/Image/ExifTool/MakerNotes.pm +2 -2
  90. package/bin/exiftool_files/lib/Image/ExifTool/Microsoft.pm +1 -1
  91. package/bin/exiftool_files/lib/Image/ExifTool/Nikon.pm +331 -22
  92. package/bin/exiftool_files/lib/Image/ExifTool/NikonCustom.pm +55 -1
  93. package/bin/exiftool_files/lib/Image/ExifTool/Olympus.pm +1 -0
  94. package/bin/exiftool_files/lib/Image/ExifTool/OpenEXR.pm +21 -3
  95. package/bin/exiftool_files/lib/Image/ExifTool/PNG.pm +3 -3
  96. package/bin/exiftool_files/lib/Image/ExifTool/QuickTime.pm +40 -24
  97. package/bin/exiftool_files/lib/Image/ExifTool/QuickTimeStream.pl +61 -30
  98. package/bin/exiftool_files/lib/Image/ExifTool/README +2 -0
  99. package/bin/exiftool_files/lib/Image/ExifTool/Sony.pm +1 -1
  100. package/bin/exiftool_files/lib/Image/ExifTool/TagLookup.pm +4815 -4775
  101. package/bin/exiftool_files/lib/Image/ExifTool/TagNames.pod +931 -617
  102. package/bin/exiftool_files/lib/Image/ExifTool/WriteQuickTime.pl +30 -8
  103. package/bin/exiftool_files/lib/Image/ExifTool/Writer.pl +10 -4
  104. package/bin/exiftool_files/lib/Image/ExifTool/XMP.pm +4 -2
  105. package/bin/exiftool_files/lib/Image/ExifTool.pm +77 -41
  106. package/bin/exiftool_files/lib/Image/ExifTool.pod +24 -11
  107. package/bin/exiftool_files/lib/List/Util.pm +97 -8
  108. package/bin/exiftool_files/lib/MIME/Base64.pm +5 -5
  109. package/bin/exiftool_files/lib/MIME/Charset/_Compat.pm +106 -0
  110. package/bin/exiftool_files/lib/MIME/Charset.pm +1303 -0
  111. package/bin/exiftool_files/lib/Math/BigFloat.pm +444 -27
  112. package/bin/exiftool_files/lib/Math/BigInt/Calc.pm +296 -313
  113. package/bin/exiftool_files/lib/Math/BigInt/FastCalc.pm +1 -1
  114. package/bin/exiftool_files/lib/Math/BigInt/GMP.pm +2 -115
  115. package/bin/exiftool_files/lib/Math/BigInt/LTM.pm +2 -24
  116. package/bin/exiftool_files/lib/Math/BigInt/Lib.pm +61 -32
  117. package/bin/exiftool_files/lib/Math/BigInt.pm +292 -107
  118. package/bin/exiftool_files/lib/POSIX.pm +1 -1
  119. package/bin/exiftool_files/lib/PerlIO/scalar.pm +41 -0
  120. package/bin/exiftool_files/lib/PerlIO.pm +397 -0
  121. package/bin/exiftool_files/lib/Portable/CPAN.pm +94 -94
  122. package/bin/exiftool_files/lib/Portable/Config.pm +94 -94
  123. package/bin/exiftool_files/lib/Portable/FileSpec.pm +180 -180
  124. package/bin/exiftool_files/lib/Portable/HomeDir.pm +110 -110
  125. package/bin/exiftool_files/lib/Portable/LoadYaml.pm +430 -430
  126. package/bin/exiftool_files/lib/Portable/minicpan.pm +55 -55
  127. package/bin/exiftool_files/lib/Portable.pm +246 -320
  128. package/bin/exiftool_files/lib/Scalar/Util.pm +9 -4
  129. package/bin/exiftool_files/lib/Socket.pm +16 -12
  130. package/bin/exiftool_files/lib/Storable.pm +1444 -1441
  131. package/bin/exiftool_files/lib/TAP/Base.pm +133 -0
  132. package/bin/exiftool_files/lib/TAP/Formatter/Base.pm +467 -0
  133. package/bin/exiftool_files/lib/TAP/Formatter/Color.pm +116 -0
  134. package/bin/exiftool_files/lib/TAP/Formatter/Console/ParallelSession.pm +201 -0
  135. package/bin/exiftool_files/lib/TAP/Formatter/Console/Session.pm +205 -0
  136. package/bin/exiftool_files/lib/TAP/Formatter/Console.pm +100 -0
  137. package/bin/exiftool_files/lib/TAP/Formatter/File/Session.pm +95 -0
  138. package/bin/exiftool_files/lib/TAP/Formatter/File.pm +56 -0
  139. package/bin/exiftool_files/lib/TAP/Formatter/Session.pm +220 -0
  140. package/bin/exiftool_files/lib/TAP/Harness/Beyond.pod +426 -0
  141. package/bin/exiftool_files/lib/TAP/Harness/Env.pm +215 -0
  142. package/bin/exiftool_files/lib/TAP/Harness.pm +1054 -0
  143. package/bin/exiftool_files/lib/TAP/Object.pm +155 -0
  144. package/bin/exiftool_files/lib/TAP/Parser/Aggregator.pm +414 -0
  145. package/bin/exiftool_files/lib/TAP/Parser/Grammar.pm +584 -0
  146. package/bin/exiftool_files/lib/TAP/Parser/Iterator/Array.pm +100 -0
  147. package/bin/exiftool_files/lib/TAP/Parser/Iterator/Process.pm +378 -0
  148. package/bin/exiftool_files/lib/TAP/Parser/Iterator/Stream.pm +116 -0
  149. package/bin/exiftool_files/lib/TAP/Parser/Iterator.pm +162 -0
  150. package/bin/exiftool_files/lib/TAP/Parser/IteratorFactory.pm +339 -0
  151. package/bin/exiftool_files/lib/TAP/Parser/Multiplexer.pm +194 -0
  152. package/bin/exiftool_files/lib/TAP/Parser/Result/Bailout.pm +62 -0
  153. package/bin/exiftool_files/lib/TAP/Parser/Result/Comment.pm +60 -0
  154. package/bin/exiftool_files/lib/TAP/Parser/Result/Plan.pm +119 -0
  155. package/bin/exiftool_files/lib/TAP/Parser/Result/Pragma.pm +62 -0
  156. package/bin/exiftool_files/lib/TAP/Parser/Result/Test.pm +271 -0
  157. package/bin/exiftool_files/lib/TAP/Parser/Result/Unknown.pm +48 -0
  158. package/bin/exiftool_files/lib/TAP/Parser/Result/Version.pm +62 -0
  159. package/bin/exiftool_files/lib/TAP/Parser/Result/YAML.pm +61 -0
  160. package/bin/exiftool_files/lib/TAP/Parser/Result.pm +297 -0
  161. package/bin/exiftool_files/lib/TAP/Parser/ResultFactory.pm +183 -0
  162. package/bin/exiftool_files/lib/TAP/Parser/Scheduler/Job.pm +127 -0
  163. package/bin/exiftool_files/lib/TAP/Parser/Scheduler/Spinner.pm +61 -0
  164. package/bin/exiftool_files/lib/TAP/Parser/Scheduler.pm +448 -0
  165. package/bin/exiftool_files/lib/TAP/Parser/Source.pm +381 -0
  166. package/bin/exiftool_files/lib/TAP/Parser/SourceHandler/Executable.pm +184 -0
  167. package/bin/exiftool_files/lib/TAP/Parser/SourceHandler/File.pm +136 -0
  168. package/bin/exiftool_files/lib/TAP/Parser/SourceHandler/Handle.pm +124 -0
  169. package/bin/exiftool_files/lib/TAP/Parser/SourceHandler/Perl.pm +370 -0
  170. package/bin/exiftool_files/lib/TAP/Parser/SourceHandler/RawTAP.pm +130 -0
  171. package/bin/exiftool_files/lib/TAP/Parser/SourceHandler.pm +191 -0
  172. package/bin/exiftool_files/lib/TAP/Parser/YAMLish/Reader.pm +332 -0
  173. package/bin/exiftool_files/lib/TAP/Parser/YAMLish/Writer.pm +254 -0
  174. package/bin/exiftool_files/lib/TAP/Parser.pm +1931 -0
  175. package/bin/exiftool_files/lib/Test/Builder/Formatter.pm +107 -0
  176. package/bin/exiftool_files/lib/Test/Builder/IO/Scalar.pm +659 -0
  177. package/bin/exiftool_files/lib/Test/Builder/Module.pm +182 -0
  178. package/bin/exiftool_files/lib/Test/Builder/Tester/Color.pm +51 -0
  179. package/bin/exiftool_files/lib/Test/Builder/Tester.pm +675 -0
  180. package/bin/exiftool_files/lib/Test/Builder/TodoDiag.pm +68 -0
  181. package/bin/exiftool_files/lib/Test/Builder.pm +2653 -0
  182. package/bin/exiftool_files/lib/Test/Harness.pm +618 -0
  183. package/bin/exiftool_files/lib/Test/More.pm +1997 -0
  184. package/bin/exiftool_files/lib/Test/Simple.pm +220 -0
  185. package/bin/exiftool_files/lib/Test/Tester/Capture.pm +241 -0
  186. package/bin/exiftool_files/lib/Test/Tester/CaptureRunner.pm +79 -0
  187. package/bin/exiftool_files/lib/Test/Tester/Delegate.pm +45 -0
  188. package/bin/exiftool_files/lib/Test/Tester.pm +695 -0
  189. package/bin/exiftool_files/lib/Test/Tutorial.pod +618 -0
  190. package/bin/exiftool_files/lib/Test/use/ok.pm +64 -0
  191. package/bin/exiftool_files/lib/Text/ParseWords.pm +303 -0
  192. package/bin/exiftool_files/lib/Tie/StdHandle.pm +2 -2
  193. package/bin/exiftool_files/lib/Time/HiRes.pm +73 -68
  194. package/bin/exiftool_files/lib/Time/Local.pm +82 -35
  195. package/bin/exiftool_files/lib/Time/Piece.pm +19 -4
  196. package/bin/exiftool_files/lib/Time/Seconds.pm +1 -1
  197. package/bin/exiftool_files/lib/UNIVERSAL.pm +203 -0
  198. package/bin/exiftool_files/lib/Unicode/GCString.pm +60 -0
  199. package/bin/exiftool_files/lib/Unicode/LineBreak/Constants.pm +68 -0
  200. package/bin/exiftool_files/lib/Unicode/LineBreak.pm +248 -0
  201. package/bin/exiftool_files/lib/Win32/API/Struct.pm +1 -177
  202. package/bin/exiftool_files/lib/Win32/API/Type.pm +1 -100
  203. package/bin/exiftool_files/lib/Win32/API.pm +1 -830
  204. package/bin/exiftool_files/lib/Win32/FindFile.pm +2 -123
  205. package/bin/exiftool_files/lib/Win32.pm +213 -89
  206. package/bin/exiftool_files/lib/Win32API/File.pm +1 -1
  207. package/bin/exiftool_files/lib/auto/B/B.xs.dll +0 -0
  208. package/bin/exiftool_files/lib/auto/Compress/Raw/Bzip2/Bzip2.xs.dll +0 -0
  209. package/bin/exiftool_files/lib/auto/Compress/Raw/Lzma/Lzma.xs.dll +0 -0
  210. package/bin/exiftool_files/lib/auto/Compress/Raw/Lzma/autosplit.ix +3 -0
  211. package/bin/exiftool_files/lib/auto/Compress/Raw/Zlib/Zlib.xs.dll +0 -0
  212. package/bin/exiftool_files/lib/auto/CryptX/CryptX.xs.dll +0 -0
  213. package/bin/exiftool_files/lib/auto/Cwd/Cwd.xs.dll +0 -0
  214. package/bin/exiftool_files/lib/auto/Data/Dumper/Dumper.xs.dll +0 -0
  215. package/bin/exiftool_files/lib/auto/Digest/MD5/MD5.xs.dll +0 -0
  216. package/bin/exiftool_files/lib/auto/Digest/SHA/SHA.xs.dll +0 -0
  217. package/bin/exiftool_files/lib/auto/Encode/Encode.xs.dll +0 -0
  218. package/bin/exiftool_files/lib/auto/Fcntl/Fcntl.xs.dll +0 -0
  219. package/bin/exiftool_files/lib/auto/File/Glob/Glob.xs.dll +0 -0
  220. package/bin/exiftool_files/lib/auto/IO/Compress/Brotli/Brotli.xs.dll +0 -0
  221. package/bin/exiftool_files/lib/auto/IO/IO.xs.dll +0 -0
  222. package/bin/exiftool_files/lib/auto/List/Util/Util.xs.dll +0 -0
  223. package/bin/exiftool_files/lib/auto/MIME/Base64/Base64.xs.dll +0 -0
  224. package/bin/exiftool_files/lib/auto/Math/BigInt/FastCalc/FastCalc.xs.dll +0 -0
  225. package/bin/exiftool_files/lib/auto/Math/BigInt/GMP/GMP.xs.dll +0 -0
  226. package/bin/exiftool_files/lib/auto/POSIX/POSIX.xs.dll +0 -0
  227. package/bin/exiftool_files/lib/auto/PerlIO/scalar/scalar.xs.dll +0 -0
  228. package/bin/exiftool_files/lib/auto/Socket/Socket.xs.dll +0 -0
  229. package/bin/exiftool_files/lib/auto/Storable/Storable.xs.dll +0 -0
  230. package/bin/exiftool_files/lib/auto/Time/HiRes/HiRes.xs.dll +0 -0
  231. package/bin/exiftool_files/lib/auto/Time/Piece/Piece.xs.dll +0 -0
  232. package/bin/exiftool_files/lib/auto/Unicode/LineBreak/LineBreak.xs.dll +0 -0
  233. package/bin/exiftool_files/lib/auto/Win32/API/API.xs.dll +0 -0
  234. package/bin/exiftool_files/lib/auto/Win32/FindFile/FindFile.xs.dll +0 -0
  235. package/bin/exiftool_files/lib/auto/Win32/Win32.xs.dll +0 -0
  236. package/bin/exiftool_files/lib/auto/Win32API/File/File.xs.dll +0 -0
  237. package/bin/exiftool_files/lib/auto/mro/mro.xs.dll +0 -0
  238. package/bin/exiftool_files/lib/auto/re/re.xs.dll +0 -0
  239. package/bin/exiftool_files/lib/feature.pm +49 -17
  240. package/bin/exiftool_files/lib/mro.pm +4 -20
  241. package/bin/exiftool_files/lib/overload.pm +15 -15
  242. package/bin/exiftool_files/lib/parent.pm +10 -2
  243. package/bin/exiftool_files/lib/re.pm +91 -33
  244. package/bin/exiftool_files/lib/warnings.pm +17 -6
  245. package/bin/exiftool_files/libgcc_s_seh-1.dll +0 -0
  246. package/bin/exiftool_files/liblzma-5__.dll +0 -0
  247. package/bin/exiftool_files/libstdc++-6.dll +0 -0
  248. package/bin/exiftool_files/libwinpthread-1.dll +0 -0
  249. package/bin/exiftool_files/perl.exe +0 -0
  250. package/bin/exiftool_files/perl532.dll +0 -0
  251. package/package.json +7 -5
  252. package/bin/exiftool_files/libgcc_s_dw2-1.dll +0 -0
  253. 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.999816';
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
- # avoid redefinitions
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
- # works also if xv and yv are the same reference, and handles also $x == 0
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
- $xv->[0] = $xv->[0] - ($xv->[1] = int($xv->[0] * $RBASE)) * $BASE;
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
- $car = int($i * $RBASE);
426
- $i -= $car * $BASE;
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 = [ @$xv ] if $xv == $yv; # same references?
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 @prod || 0), next if $xi == 0;
443
+ $xi = (shift(@prod) || 0), next if $xi == 0;
457
444
  for $yi (@$yv) {
458
445
  $prod = $xi * $yi + ($prod[$cty] || 0) + $car;
459
- ## this is actually a tad slower
460
- ## $prod = $prod[$cty]; $prod += ($car + $xi * $yi); # no ||0 here
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; # need really to check for 0?
465
- $xi = shift @prod || 0; # || 0 makes v5.005_3 happy
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 small numbers, also handles $x == 0
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 ( ((@$xv == 1) && ($xv->[0] == 0)) );
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; # same references?
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 @prod || 0), next if $xi == 0;
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; # need really to check for 0?
526
- $xi = shift @prod || 0; # || 0 makes v5.005_3 happy
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 small numbers, also handles $x == 0
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
- $xv->[0] - ($xv->[1] = int($xv->[0] / $BASE)) * $BASE;
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
- $car = int($i / $BASE);
561
- $i -= $car * $BASE;
562
- # This (together with use integer;) does not work on 32-bit Perls
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 ( ((@$xv == 1) && ($xv->[0] == 0)) );
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; # same references?
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 @prod || 0), next if $xi == 0;
567
+ $xi = (shift(@prod) || 0), next if $xi == 0;
581
568
  for $yi (@$yv) {
582
569
  $prod = $xi * $yi + ($prod[$cty] || 0) + $car;
583
- $prod[$cty++] = $prod - ($car = int($prod / $BASE)) * $BASE;
570
+ $rem = $prod % $BASE;
571
+ $car = ($prod - $rem) / $BASE;
572
+ $prod[$cty++] = $rem;
584
573
  }
585
- $prod[$cty] += $car if $car; # need really to check for 0?
586
- $xi = shift @prod || 0; # || 0 makes v5.005_3 happy
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
- if (wantarray) {
612
- my $rem = [ $x->[0] % $yorg->[0] ];
613
- bless $rem, $c;
614
- $x->[0] = int($x->[0] / $yorg->[0]);
615
- return ($x, $rem);
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 @$x if @$x > 1 && $x->[-1] == 0; # splice up a leading zero
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 yet, the result will be 0
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; # make copy
648
- @$x = 0; # set to 0
649
- return ($x, $rem) if wantarray; # including remainder?
650
- return $x; # only x, which is [0] now
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
- # if $yorg has more digits than $x (it's leading element is longer than
657
- # the one from $x), the result will also be 0:
658
- if (length(int($yorg->[-1])) > length(int($x->[-1]))) {
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
- my $a = 0;
669
- my $j = @$x - 1;
670
- # manual way (abort if unequal, good for early ne)
671
- while ($j >= 0) {
672
- last if ($a = $x->[$j] - $yorg->[$j]);
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
- # $x >= $y, so proceed normally
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); # always make copy to preserve
658
+ my $y = $c->_copy($yorg); # always make copy to preserve
693
659
 
694
- my ($car, $bar, $prd, $dd, $xi, $yi, @q, $v2, $v1, $tmp, $q, $u2, $u1, $u0);
695
-
696
- $car = $bar = $prd = 0;
697
- if (($dd = int($BASE / ($y->[-1] + 1))) != 1) {
698
- for $xi (@$x) {
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; # see USE_MUL
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; # see USE_MUL
673
+ $yi -= ($car = int($yi * $RBASE)) * $BASE; # see USE_MUL
707
674
  }
708
675
  } else {
709
676
  push(@$x, 0);
710
677
  }
711
- @q = ();
712
- ($v2, $v1) = @$y[-2, -1];
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
- $q = (($u0 == $v1) ? $MAX_VAL : int(($u0 * $BASE + $u1) / $v1));
720
- --$q while ($v2 * $q > ($u0 * $BASE + $u1 - $q * $v1) * $BASE + $u2);
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
- ($car, $bar) = (0, 0);
723
- for ($yi = 0, $xi = $#$x - $#$y-1; $yi <= $#$y; ++$yi, ++$xi) {
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; # see USE_MUL
726
- $x->[$xi] += $BASE if ($bar = (($x->[$xi] -= $prd + $bar) < 0));
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 ($car = (($x->[$xi] += $y->[$yi] + $car) >= $BASE));
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
- for $xi (reverse @$x) {
718
+ my $car = 0;
719
+ my ($prd, $rem);
720
+ for my $xi (reverse @$x) {
745
721
  $prd = $car * $BASE + $xi;
746
- $car = $prd - ($tmp = int($prd / $dd)) * $dd; # see USE_MUL
747
- unshift(@$d, $tmp);
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] = int($x->[0] / $yorg->[0]);
758
+ $x->[0] = $x->[0] / $yorg->[0];
782
759
  return ($x, $rem);
783
760
  } else {
784
- $x->[0] = int($x->[0] / $yorg->[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 @$x if @$x > 1 && $x->[-1] == 0; # splice up a leading zero
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 yet, the result will be 0
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; # make copy
813
- @$x = 0; # set to 0
814
- return ($x, $rem) if wantarray; # including remainder?
815
- return $x; # only x, which is [0] now
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 $rem;
821
- # if $yorg has more digits than $x (it's leading element is longer than
822
- # the one from $x), the result will also be 0:
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 (length(int($yorg->[-1])) == length(int($x->[-1]))) {
832
- # same length, so make full compare
805
+ if ($cmp == 0) { # x = y
806
+ @$x = 1;
807
+ return $x, $c->_zero() if wantarray;
808
+ return $x;
809
+ }
833
810
 
834
- my $a = 0;
835
- my $j = @$x - 1;
836
- # manual way (abort if unequal, good for early ne)
837
- while ($j >= 0) {
838
- last if ($a = $x->[$j] - $yorg->[$j]);
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
- # $x >= $y, so proceed normally
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); # always make copy to preserve
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
- $car = $bar = $prd = 0;
862
- if (($dd = int($BASE / ($y->[-1] + 1))) != 1) {
863
- for $xi (@$x) {
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 = int($xi / $BASE)) * $BASE;
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 = int($yi / $BASE)) * $BASE;
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..-1];
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
- $q = (($u0 == $v1) ? $MAX_VAL : int(($u0 * $BASE + $u1) / $v1));
889
- --$q while ($v2 * $q > ($u0 * $BASE +$ u1- $q*$v1) * $BASE + $u2);
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
- ($car, $bar) = (0, 0);
892
- for ($yi = 0, $xi = $#$x - $#$y - 1; $yi <= $#$y; ++$yi, ++$xi) {
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 ($bar = (($x->[$xi] -= $prd + $bar) < 0));
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 ($car = (($x->[$xi] += $y->[$yi] + $car) >= $BASE));
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
- for $xi (reverse @$x) {
883
+ my $car = 0;
884
+ my $prd;
885
+ for my $xi (reverse @$x) {
914
886
  $prd = $car * $BASE + $xi;
915
- $car = $prd - ($tmp = int($prd / $dd)) * $dd;
916
- unshift(@$d, $tmp);
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
- if (wantarray) {
946
- my $rem = [ $x->[0] % $yorg->[0] ];
947
- bless $rem, $c;
948
- $x->[0] = int($x->[0] / $yorg->[0]);
949
- return ($x, $rem);
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 @$x if @$x > 1 && $x->[-1] == 0; # splice up a leading zero
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 yet, the result will be 0
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; # make copy
980
- @$x = 0; # set to 0
981
- return ($x, $rem) if wantarray; # including remainder?
982
- return $x; # only x, which is [0] now
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 $rem;
988
- # if $yorg has more digits than $x (it's leading element is longer than
989
- # the one from $x), the result will also be 0:
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 (length(int($yorg->[-1])) == length(int($x->[-1]))) {
999
- # same length, so make full compare
961
+ if ($cmp == 0) { # x = y
962
+ @$x = 1;
963
+ return $x, $c->_zero() if wantarray;
964
+ return $x;
965
+ }
1000
966
 
1001
- my $a = 0;
1002
- my $j = @$x - 1;
1003
- # manual way (abort if unequal, good for early ne)
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->[0] = 0; # if $a < 0
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
- # $x >= $y, so proceed normally
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); # always make copy to preserve
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
- $car = $bar = $prd = 0;
1031
- if (($dd = int($BASE / ($y->[-1] + 1))) != 1) {
1032
- for $xi (@$x) {
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
- $xi -= ($car = int($xi / $BASE)) * $BASE;
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
- $yi -= ($car = int($yi / $BASE)) * $BASE;
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..-1];
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
- $q = (($u0 == $v1) ? $MAX_VAL : int(($u0 * $BASE + $u1) / $v1));
1058
- --$q while ($v2 * $q > ($u0 * $BASE + $u1 - $q * $v1) * $BASE + $u2);
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
- ($car, $bar) = (0, 0);
1061
- for ($yi = 0, $xi = $#$x - $#$y - 1; $yi <= $#$y; ++$yi, ++$xi) {
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
- $prd -= ($car = int($prd / $BASE)) * $BASE;
1064
- $x->[$xi] += $BASE if ($bar = (($x->[$xi] -= $prd + $bar) < 0));
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 ($car = (($x->[$xi] += $y->[$yi] + $car) >= $BASE));
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
- for $xi (reverse @$x) {
1046
+ my $car = 0;
1047
+ my ($prd, $rem);
1048
+ for my $xi (reverse @$x) {
1083
1049
  $prd = $car * $BASE + $xi;
1084
- $car = $prd - ($tmp = int($prd / $dd)) * $dd;
1085
- unshift(@$d, $tmp);
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 @$x if $x->[-1] == 0 && @$x > 1; # kill last element if 0
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
- # Handle the special case when the base is a power of 10. Don't check
1399
- # whether log($b)/log(10) is an integer, because log(1000)/log(10) is not
1400
- # exactly 3.
1401
-
1402
- my $log10 = sprintf "%.0f", log($b) / log(10);
1403
- if ($b == 10 ** $log10) {
1404
- $b = 10;
1405
- $n = $c->_mul($n, $c->_new($log10));
1406
-
1407
- # shortcut (faster) for shifting by 10) since we are in base 10eX
1408
- # multiples of $BASE_LEN:
1409
- my $src = @$x; # source
1410
- my $len = $c->_num($n); # shift-len as normal int
1411
- my $rem = $len % $BASE_LEN; # remainder to shift
1412
- my $dst = $src + int($len / $BASE_LEN); # destination
1413
- my $vd; # further speedup
1414
- $x->[$src] = 0; # avoid first ||0 for speed
1415
- my $z = '0' x $BASE_LEN;
1416
- while ($src >= 0) {
1417
- $vd = $x->[$src];
1418
- $vd = $z . $vd;
1419
- $vd = substr($vd, -$BASE_LEN + $rem, $BASE_LEN - $rem);
1420
- $vd .= $src > 0 ? substr($z . $x->[$src - 1], -$BASE_LEN, $rem)
1421
- : '0' x $rem;
1422
- $vd = substr($vd, -$BASE_LEN, $BASE_LEN) if length($vd) > $BASE_LEN;
1423
- $x->[$dst] = int($vd);
1424
- $dst--;
1425
- $src--;
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
- # set lowest parts to 0
1428
- while ($dst >= 0) {
1429
- $x->[$dst--] = 0;
1410
+
1411
+ # If we must shift the elements within the array ...
1412
+
1413
+ if ($q) {
1414
+ unshift @$x, (0) x $q;
1430
1415
  }
1431
- # fix spurious last zero element
1432
- splice @$x, -1 if $x->[-1] == 0;
1433
- return $x;
1416
+
1434
1417
  } else {
1435
- $b = $c->_new($b);
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 {