1eac174f2Safresh1# -*- mode: perl; -*- 2b8851fccSafresh1 3b8851fccSafresh1# Test blog function (and bpow, since it uses blog), as well as bexp(). 4b8851fccSafresh1 5b8851fccSafresh1# It is too slow to be simple included in bigfltpm.inc, where it would get 6b8851fccSafresh1# executed 3 times. One time would be under Math::BigInt::BareCalc, which 7b46d8ef2Safresh1# shouldn't make any difference since there is no $LIB->_log() function, and 8b8851fccSafresh1# one time under a subclass, which *should* work. 9b8851fccSafresh1 10b8851fccSafresh1# But it is better to test the numerical functionality, instead of not testing 11b8851fccSafresh1# it at all (which did lead to wrong answers for 0 < $x < 1 in blog() in 12b8851fccSafresh1# versions up to v1.63, and for bsqrt($x) when $x << 1 for instance). 13b8851fccSafresh1 14b8851fccSafresh1use strict; 15b8851fccSafresh1use warnings; 16b8851fccSafresh1 17b8851fccSafresh1use Test::More tests => 73; 18b8851fccSafresh1 199f11ffb7Safresh1use Math::BigFloat only => 'Calc'; 20b8851fccSafresh1use Math::BigInt; 21b8851fccSafresh1 22b8851fccSafresh1my $class = "Math::BigInt"; 23b8851fccSafresh1 24b8851fccSafresh1############################################################################### 25b8851fccSafresh1# test $n->blog() in Math::BigInt (broken until 1.80) 26b8851fccSafresh1 27b8851fccSafresh1is($class->new(2)->blog(), '0', "$class->new(2)->blog()"); 28b8851fccSafresh1is($class->new(288)->blog(), '5', "$class->new(288)->blog()"); 29b8851fccSafresh1is($class->new(2000)->blog(), '7', "$class->new(2000)->blog()"); 30b8851fccSafresh1 31b8851fccSafresh1############################################################################### 32b8851fccSafresh1# test $n->bexp() in Math::BigInt 33b8851fccSafresh1 34b8851fccSafresh1is($class->new(1)->bexp(), '2', "$class->new(1)->bexp()"); 35b8851fccSafresh1is($class->new(2)->bexp(), '7', "$class->new(2)->bexp()"); 36b8851fccSafresh1is($class->new(3)->bexp(), '20', "$class->new(3)->bexp()"); 37b8851fccSafresh1 38b8851fccSafresh1############################################################################### 39b8851fccSafresh1# Math::BigFloat tests 40b8851fccSafresh1 41b8851fccSafresh1############################################################################### 42b8851fccSafresh1# test $n->blog(undef, N) where N > 67 (broken until 1.82) 43b8851fccSafresh1 44b8851fccSafresh1$class = "Math::BigFloat"; 45b8851fccSafresh1 46b8851fccSafresh1# These tests can take quite a while, but are necessary. Maybe protect them 47b8851fccSafresh1# with some alarm()? 48b8851fccSafresh1 49b8851fccSafresh1# this triggers the calculation and caching of ln(2): 50b8851fccSafresh1is($class->new(5)->blog(undef, 71), 51b8851fccSafresh1 '1.6094379124341003746007593332261876395256013542685177219126478914741790', 52b8851fccSafresh1 "$class->new(5)->blog(undef, 71)"); 53b8851fccSafresh1 54b8851fccSafresh1# if the cache was correct, we should get this result, fast: 55b8851fccSafresh1is($class->new(2)->blog(undef, 71), 56b8851fccSafresh1 '0.69314718055994530941723212145817656807550013436025525412068000949339362', 57b8851fccSafresh1 "$class->new(2)->blog(undef, 71)"); 58b8851fccSafresh1 59b8851fccSafresh1is($class->new(11)->blog(undef, 71), 60b8851fccSafresh1 '2.3978952727983705440619435779651292998217068539374171752185677091305736', 61b8851fccSafresh1 "$class->new(11)->blog(undef, 71)"); 62b8851fccSafresh1 63b8851fccSafresh1is($class->new(21)->blog(undef, 71), 64b8851fccSafresh1 '3.0445224377234229965005979803657054342845752874046106401940844835750742', 65b8851fccSafresh1 "$class->new(21)->blog(undef, 71)"); 66b8851fccSafresh1 67b8851fccSafresh1############################################################################### 68b8851fccSafresh1 69b8851fccSafresh1# These tests are now really fast, since they collapse to blog(10), basically 70b8851fccSafresh1# Don't attempt to run them with older versions. You are warned. 71b8851fccSafresh1 72b8851fccSafresh1# $x < 0 => NaN 73b8851fccSafresh1is($class->new(-2)->blog(), 'NaN', "$class->new(-2)->blog()"); 74b8851fccSafresh1is($class->new(-1)->blog(), 'NaN', "$class->new(-1)->blog()"); 75b8851fccSafresh1is($class->new(-10)->blog(), 'NaN', "$class->new(-10)->blog()"); 76b8851fccSafresh1is($class->new(-2, 2)->blog(), 'NaN', "$class->new(-2, 2)->blog()"); 77b8851fccSafresh1 78b8851fccSafresh1my $ten = $class->new(10)->blog(); 79b8851fccSafresh1 80b8851fccSafresh1# 10 is cached (up to 75 digits) 81b8851fccSafresh1is($class->new(10)->blog(), 82b8851fccSafresh1 '2.302585092994045684017991454684364207601', 83b8851fccSafresh1 qq|$class->new(10)->blog()|); 84b8851fccSafresh1 85b8851fccSafresh1# 0.1 is using the cached value for log(10), too 86b8851fccSafresh1 87b8851fccSafresh1is($class->new("0.1")->blog(), -$ten, 88b8851fccSafresh1 qq|$class->new("0.1")->blog()|); 89b8851fccSafresh1is($class->new("0.01")->blog(), -$ten * 2, 90b8851fccSafresh1 qq|$class->new("0.01")->blog()|); 91b8851fccSafresh1is($class->new("0.001")->blog(), -$ten * 3, 92b8851fccSafresh1 qq|$class->new("0.001")->blog()|); 93b8851fccSafresh1is($class->new("0.0001")->blog(), -$ten * 4, 94b8851fccSafresh1 qq|$class->new("0.0001")->blog()|); 95b8851fccSafresh1 96b8851fccSafresh1# also cached 97b8851fccSafresh1is($class->new(2)->blog(), 98b8851fccSafresh1 '0.6931471805599453094172321214581765680755', 99b8851fccSafresh1 qq|$class->new(2)->blog()|); 100b8851fccSafresh1is($class->new(4)->blog(), $class->new(2)->blog * 2, 101b8851fccSafresh1 qq|$class->new(4)->blog()|); 102b8851fccSafresh1 103b8851fccSafresh1# These are still slow, so do them only to 10 digits 104b8851fccSafresh1 105b8851fccSafresh1is($class->new("0.2")->blog(undef, 10), "-1.609437912", 106b8851fccSafresh1 qq|$class->new("0.2")->blog(undef, 10)|); 107b8851fccSafresh1is($class->new("0.3")->blog(undef, 10), "-1.203972804", 108b8851fccSafresh1 qq|$class->new("0.3")->blog(undef, 10)|); 109b8851fccSafresh1is($class->new("0.4")->blog(undef, 10), "-0.9162907319", 110b8851fccSafresh1 qq|$class->new("0.4")->blog(undef, 10)|); 111b8851fccSafresh1is($class->new("0.5")->blog(undef, 10), "-0.6931471806", 112b8851fccSafresh1 qq|$class->new("0.5")->blog(undef, 10)|); 113b8851fccSafresh1is($class->new("0.6")->blog(undef, 10), "-0.5108256238", 114b8851fccSafresh1 qq|$class->new("0.6")->blog(undef, 10)|); 115b8851fccSafresh1is($class->new("0.7")->blog(undef, 10), "-0.3566749439", 116b8851fccSafresh1 qq|$class->new("0.7")->blog(undef, 10)|); 117b8851fccSafresh1is($class->new("0.8")->blog(undef, 10), "-0.2231435513", 118b8851fccSafresh1 qq|$class->new("0.8")->blog(undef, 10)|); 119b8851fccSafresh1is($class->new("0.9")->blog(undef, 10), "-0.1053605157", 120b8851fccSafresh1 qq|$class->new("0.9")->blog(undef, 10)|); 121b8851fccSafresh1 122b8851fccSafresh1is($class->new("9")->blog(undef, 10), "2.197224577", 123b8851fccSafresh1 qq|$class->new("9")->blog(undef, 10)|); 124b8851fccSafresh1 125b8851fccSafresh1is($class->new("10")->blog(10, 10), "1.000000000", 126b8851fccSafresh1 qq|$class->new("10")->blog(10, 10)|); 127b8851fccSafresh1is($class->new("20")->blog(20, 10), "1.000000000", 128b8851fccSafresh1 qq|$class->new("20")->blog(20, 10)|); 129b8851fccSafresh1is($class->new("100")->blog(100, 10), "1.000000000", 130b8851fccSafresh1 qq|$class->new("100")->blog(100, 10)|); 131b8851fccSafresh1 132b8851fccSafresh1is($class->new("100")->blog(10, 10), "2.000000000", # 10 ** 2 == 100 133b8851fccSafresh1 qq|$class->new("100")->blog(10, 10)|); 134b8851fccSafresh1is($class->new("400")->blog(20, 10), "2.000000000", # 20 ** 2 == 400 135b8851fccSafresh1 qq|$class->new("400")->blog(20, 10)|); 136b8851fccSafresh1 137b8851fccSafresh1is($class->new("4")->blog(2, 10), "2.000000000", # 2 ** 2 == 4 138b8851fccSafresh1 qq|$class->new("4")->blog(2, 10)|); 139b8851fccSafresh1is($class->new("16")->blog(2, 10), "4.000000000", # 2 ** 4 == 16 140b8851fccSafresh1 qq|$class->new("16")->blog(2, 10)|); 141b8851fccSafresh1 142b8851fccSafresh1is($class->new("1.2")->bpow("0.3", 10), "1.056219968", 143b8851fccSafresh1 qq|$class->new("1.2")->bpow("0.3", 10)|); 144b8851fccSafresh1is($class->new("10")->bpow("0.6", 10), "3.981071706", 145b8851fccSafresh1 qq|$class->new("10")->bpow("0.6", 10)|); 146b8851fccSafresh1 147b8851fccSafresh1# blog should handle bigint input 148*e0680481Safresh1is(Math::BigFloat->blog(Math::BigInt->new(100), 10), 2, "blog(100)"); 149b8851fccSafresh1 150b8851fccSafresh1############################################################################### 151b8851fccSafresh1# some integer results 152b8851fccSafresh1is($class->new(2)->bpow(32)->blog(2), "32", "2 ** 32"); 153b8851fccSafresh1is($class->new(3)->bpow(32)->blog(3), "32", "3 ** 32"); 154b8851fccSafresh1is($class->new(2)->bpow(65)->blog(2), "65", "2 ** 65"); 155b8851fccSafresh1 156b8851fccSafresh1my $x = Math::BigInt->new('777') ** 256; 157b8851fccSafresh1my $base = Math::BigInt->new('12345678901234'); 158b8851fccSafresh1is($x->copy()->blog($base), 56, 'blog(777**256, 12345678901234)'); 159b8851fccSafresh1 160b8851fccSafresh1$x = Math::BigInt->new('777') ** 777; 161b8851fccSafresh1$base = Math::BigInt->new('777'); 162b8851fccSafresh1is($x->copy()->blog($base), 777, 'blog(777**777, 777)'); 163b8851fccSafresh1 164b8851fccSafresh1############################################################################### 165b8851fccSafresh1# test for bug in bsqrt() not taking negative _e into account 166b8851fccSafresh1test_bpow('200', '0.5', 10, '14.14213562'); 167b8851fccSafresh1test_bpow('20', '0.5', 10, '4.472135955'); 168b8851fccSafresh1test_bpow('2', '0.5', 10, '1.414213562'); 169b8851fccSafresh1test_bpow('0.2', '0.5', 10, '0.4472135955'); 170b8851fccSafresh1test_bpow('0.02', '0.5', 10, '0.1414213562'); 171b8851fccSafresh1test_bpow('0.49', '0.5', undef, '0.7'); 172b8851fccSafresh1test_bpow('0.49', '0.5', 10, '0.7000000000'); 173b8851fccSafresh1test_bpow('0.002', '0.5', 10, '0.04472135955'); 174b8851fccSafresh1test_bpow('0.0002', '0.5', 10, '0.01414213562'); 175b8851fccSafresh1test_bpow('0.0049', '0.5', undef, '0.07'); 176b8851fccSafresh1test_bpow('0.0049', '0.5', 10, '0.07000000000'); 177b8851fccSafresh1test_bpow('0.000002', '0.5', 10, '0.001414213562'); 178b8851fccSafresh1test_bpow('0.021', '0.5', 10, '0.1449137675'); 179b8851fccSafresh1test_bpow('1.2', '0.5', 10, '1.095445115'); 180b8851fccSafresh1test_bpow('1.23', '0.5', 10, '1.109053651'); 181b8851fccSafresh1test_bpow('12.3', '0.5', 10, '3.507135583'); 182b8851fccSafresh1 183b8851fccSafresh1test_bpow('9.9', '0.5', 10, '3.146426545'); 184b8851fccSafresh1test_bpow('9.86902225', '0.5', 10, '3.141500000'); 185b8851fccSafresh1test_bpow('9.86902225', '0.5', undef, '3.1415'); 186b8851fccSafresh1 187b8851fccSafresh1############################################################################### 188b8851fccSafresh1# other tests for bpow() 189b8851fccSafresh1 190b8851fccSafresh1test_bpow('0.2', '0.41', 10, '0.5169187652'); 191b8851fccSafresh1 192*e0680481Safresh1is($class->new("0.1")->bpow("28.4", 40)->bsstr(), 193*e0680481Safresh1 '3981071705534972507702523050877520434877e-68', 194*e0680481Safresh1 qq|$class->new("0.1")->bpow("28.4", 40)->bsstr()|); 195b8851fccSafresh1 196b8851fccSafresh1# The following test takes too long. 197b8851fccSafresh1#is($class->new("2")->bpow("-1034.5", 40)->bsstr(), 198b8851fccSafresh1# '3841222690408590466868250378242558090957e-351', 199b8851fccSafresh1# qq|$class->new("2")->bpow("-1034.5", 40)|); 200b8851fccSafresh1 201b8851fccSafresh1############################################################################### 202b8851fccSafresh1# test bexp() with cached results 203b8851fccSafresh1 204b8851fccSafresh1is($class->new(1)->bexp(), '2.718281828459045235360287471352662497757', 205b8851fccSafresh1 'bexp(1)'); 206b8851fccSafresh1is($class->new(2)->bexp(40), $class->new(1)->bexp(45)->bpow(2, 40), 207b8851fccSafresh1 'bexp(2)'); 208b8851fccSafresh1 209b8851fccSafresh1is($class->new("12.5")->bexp(61), $class->new(1)->bexp(65)->bpow(12.5, 61), 210b8851fccSafresh1 'bexp(12.5)'); 211b8851fccSafresh1 212b8851fccSafresh1############################################################################### 213b8851fccSafresh1# test bexp() with big values (non-cached) 214b8851fccSafresh1 215b8851fccSafresh1is($class->new(1)->bexp(100), 216b8851fccSafresh1 '2.7182818284590452353602874713526624977572470936999' 217b8851fccSafresh1 . '59574966967627724076630353547594571382178525166427', 218b8851fccSafresh1 qq|$class->new(1)->bexp(100)|); 219b8851fccSafresh1 220b8851fccSafresh1is($class->new("12.5")->bexp(91), $class->new(1)->bexp(95)->bpow(12.5, 91), 221b8851fccSafresh1 qq|$class->new("12.5")->bexp(91)|); 222b8851fccSafresh1 223b8851fccSafresh1is($class->new("-118.5")->bexp(20)->bsstr(), 224b8851fccSafresh1 '34364014567198602057e-71', 225b8851fccSafresh1 qq|$class->new("-118.5")->bexp(20)->bsstr()|); 226b8851fccSafresh1 227b8851fccSafresh1is($class->new("-394.84010945715266885")->bexp(20)->bsstr(), 228b8851fccSafresh1 '33351796227864913873e-191', 229b8851fccSafresh1 qq|$class->new("-118.5")->bexp(20)->bsstr()|); 230b8851fccSafresh1 231b8851fccSafresh1# all done 232b8851fccSafresh1 233b8851fccSafresh1############################################################################### 234b8851fccSafresh1 235b8851fccSafresh1sub test_bpow { 236b8851fccSafresh1 my ($x, $y, $scale, $result) = @_; 237b8851fccSafresh1 is($class->new($x)->bpow($y, $scale), $result, 238b8851fccSafresh1 qq|$class->new($x)->bpow($y, | 239b8851fccSafresh1 . (defined($scale) ? $scale : 'undef') 240b8851fccSafresh1 . qq|)|); 241b8851fccSafresh1} 242