YA Perl Advent Calendar 2005-12-08

173_766_203_193_809_456_599_982_445_949_435_627_061_939_786_100_117_250_547_
173_286_503_262_376_022_458_008_465_094_333_630_120_854_338_003_194_362_163_
007_597_987_225_472_483_598_640_843_335_685_441_710_193_966_274_131_338_557_
192_586_399_006_789_292_714_554_767_500_194_796_127_964_596_906_605_976_605_
873_665_859_580_600_161_998_556_511_368_530_960_400_907_199_253_450_604_168_
622_770_350_228_527_124_626_728_538_626_805_418_833_470_107_651_091_641_919_
900_725_415_994_689_920_112_219_170_907_023_561_354_484_047_025_713_734_651_
608_777_544_579_846_111_001_059_482_132_180_956_689_444_108_315_785_401_642_
188_044_178_788_629_853_592_228_467_331_730_519_810_763_559_577_944_882_016_
286_493_908_631_503_101_121_166_109_571_682_295_769_470_379_514_531_105_239_
965_209_245_314_082_665_518_579_335_511_291_525_230_373_316_486_697_786_532_
335_206_274_149_240_813_489_201_828_773_854_353_041_855_598_709_390_675_430_
960_381_072_270_432_383_913_542_702_130_202_430_186_637_321_862_331_068_861_
776_780_211_082_856_984_506_050_024_895_394_320_139_435_868_484_643_843_368_
002_496_089_956_046_419_964_019_877_586_845_530_207_748_994_394_501_505_588_
146_979_082_629_871_366_088_121_763_790_555_364_513_243_984_244_004_147_636_
040_219_136_443_410_377_798_011_608_722_717_131_323_621_700_159_335_786_445_
601_947_601_694_025_107_888_293_017_058_178_562_647_175_461_026_384_343_438_
874_861_406_516_767_158_373_279_032_321_096_262_126_551_620_255_666_605_185_
789_463_207_944_391_905_756_886_829_667_520_553_014_724_372_245_300_878_786_
091_700_563_444_079_107_099_009_003_380_230_356_461_989_260_377_273_986_023_
281_444_076_082_783_406_824_471_703_499_844_642_915_587_790_146_384_758_051_
663_547_775_336_021_829_171_033_411_043_796_977_042_190_519_657_861_762_804_
226_147_480_755_555_085_278_062_866_268_677_842_432_851_421_790_544_407_006_
581_148_631_979_148_571_299_417_963_950_579_210_719_961_422_405_768_071_335_
213_324_842_709_316_205_032_078_384_168_750_091_017_964_584_060_285_240_107_
161_561_019_930_505_687_950_233_196_051_962_261_970_932_008_838_279_760_834_
318_101_044_311_710_769_457_048_672_103_958_655_016_388_894_770_892_065_267_
451_228_938_951_370_237_422_841_366_052_736_174_160_431_593_023_473_217_066_
764_172_949_768_821_843_606_479_073_866_252_864_377_064_398_085_101_223_216_
558_344_281_956_767_163_876_579_889_759_124_956_035_672_317_578_122_141_070_
933_058_555_310_274_598_884_089_982_879_647_974_020_264_495_921_703_064_439_
532_898_207_943_134_374_576_254_840_272_047_075_633_856_749_514_044_298_135_
927_611_328_433_323_640_657_533_550_512_376_900_773_273_703_275_329_924_651_
465_759_145_114_579_174_356_770_593_439_987_135_755_889_403_613_364_529_029_
604_049_868_233_807_295_134_382_284_730_745_937_309_910_703_657_676_103_447_
124_097_631_074_153_287_120_040_247_837_143_656_624_045_055_614_076_111_832_
245_239_612_708_339_272_798_262_887_437_416_818_440_064_925_049_838_443_370_
805_645_609_424_314_780_108_030_016_683_461_562_597_569_371_539_974_003_402_
697_903_023_830_108_053_034_645_133_078_208_043_917_492_087_248_958_344_081_
026_378_788_915_528_519_967_248_989_338_592_027_124_423_914_083_391_771_884_
524_464_968_645_052_058_218_151_010_508_471_258_285_907_685_355_807_229_880_
747_677_634_789_376

On the 8E00000000 day of Advent my True Language gave to me.... a really big number. Math::BigInt has been featured in a previous calendar, soon after it had been moved into the core distribution. However an overlooked addition of the perl 5.8.0 release was today's feature, the bignum pragma. But first, let's bring everyone up to speed: Math::Big* is set of modules that all share the purpose of providing large arbitrary/fixed precision/accuracy math. Basically, when using them you don't have to worry about overflows or rounding errors.

The joy that is bignum means that through the magic of overloading *every* number becomes a Big number and consequently everything just DWIMs swimmingly. There are a few caveats of course, in particular the POD mentions that typically "short" values like loop counters incurring performance penalties from their new-found largesse. A more subtle issue is demonstrated in the code listing, Big numbers don't play well with printf. Despite this, I've used bignum combined with Math::Matrix for higher precision math than is available in PDL, albeit more slowly and without access to a lot of other whiz-bang features, but I digress.

There are two final points I'd like to leave you with concerning bignum:

  1. The pragma ought to work wherever the underlying modules will, I can use v.11 from perl 5.8.0 with perl 5.6.0 no problem. And the source says: require 5.005;
  2. Big means "lots of bits" and not necessarily "Microsoft's advertising budget". Avagadro's number is Big but so is Planck's constant.
Enjoy!

mod8.pl


   1 use bignum;
   2 use Interpolation commify=>commify;
   3 
   4 print "Straight up\n";
   5 print 4**4000, "\n";
   6 #=Lotsa numbers
   7 
   8 print "\nNow slightly more legible\n";
   9 {
  10   $_ = $commify{4**4000};
  11   y/,/_/;
  12   print $_, "\n";
  13   #=Inf
  14 }
  15 
  16 #Doh!
  17 {
  18   print "\nNow slightly more legible\n";
  19   $_ = 4**4000;
  20 
  21   #Body of Interpolation::commify
  22   1 while s/^(-?\d+)(\d{3})/$1,$2/;
  23 
  24   y/,/_/;	    
  25   print $_, "\n";
  26   #=The beginning of this page
  27 }