01-number.t 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501
  1. #!perl -T
  2. ###############################################################################
  3. use strict;
  4. use warnings;
  5. use Test::More tests => 166;
  6. use Sidef;
  7. sub re($) {
  8. qr/^\Q$_[0]\E\z/;
  9. }
  10. ###############################################################################
  11. # general tests
  12. my $o = 'Sidef::Types::Number::Number';
  13. {
  14. my $x = $o->new(1234);
  15. is("$x", "1234");
  16. $x = $o->new("1234/1");
  17. is("$x", "1234");
  18. $x = $o->new("1234/2");
  19. is("$x", "617");
  20. #$x = $o->new("100/1.0");
  21. #is("$x", "100");
  22. #$x = $o->new("10.0/1.0");
  23. #is("$x", "10");
  24. #$x = $o->new("0.1/10");
  25. #is("$x", "0.01");
  26. #$x = $o->new("0.1/0.1");
  27. #is("$x", "1");
  28. #$x = $o->new("1e2/10");
  29. #is("$x", "10");
  30. #$x = $o->new("5/1e2");
  31. #is("$x", "0.05");
  32. #$x = $o->new("1e2/1e1");
  33. #is("$x", "10");
  34. $x = $o->new("1 / 3");
  35. like($x->as_rat, re '1/3');
  36. $x = $o->new("-1 / 3");
  37. like($x->as_rat, re '-1/3');
  38. $x = $o->new("1 / -3");
  39. like($x->as_rat, re '-1/3');
  40. $x = $o->new("abc");
  41. is("$x", "NaN");
  42. $x = $o->new("inf");
  43. is("$x", "Inf");
  44. $x = $o->new("-inf");
  45. is("$x", "-Inf");
  46. $x = $o->new("1/");
  47. is("$x", "NaN");
  48. $x = $o->new("1/+");
  49. is("$x", "NaN");
  50. $x = $o->new("1/-");
  51. is("$x", "NaN");
  52. $x = $o->new("1/_");
  53. is("$x", "NaN");
  54. $x = $o->new("+");
  55. is("$x", "NaN");
  56. $x = $o->new("-");
  57. is("$x", "NaN");
  58. $x = $o->new("_");
  59. is("$x", "NaN");
  60. $x = $o->new("1_000_000");
  61. is("$x", "1000000");
  62. #$x = $o->new("1/2/3/4/5/6"); # is parsed as: (1 / (2 / (3 / (4 / (5 / 6)))))
  63. #like($x->as_rat, re '5/16');
  64. #$x = $o->new("1/0");
  65. #is("$x", "Inf");
  66. #$x = $o->new("-1/0");
  67. #is("$x", "-Inf");
  68. #$x = $o->new("-h5/0", 36);
  69. #is("$x", "-Inf");
  70. $x = $o->new("ff/f", 16);
  71. is("$x", "17");
  72. $x = $o->new("7e", 16);
  73. is("$x", "126");
  74. $x = $o->new("inf", 36);
  75. is("$x", "24171");
  76. $x = $o->new("-Inf", 36);
  77. is("$x", "-24171");
  78. $x = $o->new("nan", 36);
  79. is("$x", "30191");
  80. # fraction in base 10
  81. $x = $o->new('123/45');
  82. like($x->as_rat, re '41/15');
  83. # fraction in base 36
  84. $x = $o->new("h5/1e", 36);
  85. like($x->as_float, re "12.34");
  86. $x = $o->new("14/1e", 36);
  87. like($x->as_rat, re "4/5");
  88. # base-10 number, converted to another base
  89. $x = $o->new($o->new("1211"), 3);
  90. is("$x", "49");
  91. #$x = $o->new("1/1.2");
  92. #like($x->as_rat, re "5/6");
  93. #$x = $o->new("1.3/1.2");
  94. #like($x->as_rat, re "13/12");
  95. #$x = $o->new("1.2/1");
  96. #like($x->as_rat, re "6/5");
  97. }
  98. ###############################################################################
  99. # general tests
  100. {
  101. like($o->new(2)->sqrt, qr/^1\.414213562/);
  102. like($o->new(100)->log, qr/^4\.605170185/);
  103. like($o->new(10)->exp, qr/^22026\.46579/);
  104. like($o->new(-4.5)->abs, qr/^4.5\z/);
  105. like($o->new(10)->abs, qr/^10\z/);
  106. like($o->new(2.9)->floor, qr/^2\z/);
  107. like($o->new(2.5)->floor, qr/^2\z/);
  108. like($o->new(2.1)->floor, qr/^2\z/);
  109. like($o->new(2)->floor, qr/^2\z/);
  110. like($o->new(2.9)->ceil, qr/^3\z/);
  111. like($o->new(2.5)->ceil, qr/^3\z/);
  112. like($o->new(2.1)->ceil, qr/^3\z/);
  113. like($o->new(2)->ceil, qr/^2\z/);
  114. like($o->new(2.3)->pow($o->new(5.4)), qr/^89.811/);
  115. like($o->new(1040)->ilog($o->new(2)), qr/^10\z/);
  116. like($o->new(2834)->ilog, qr/^7\z/);
  117. my $x = $o->new(1227);
  118. my $pow = $o->new(42);
  119. my $bint = $x->ipow($pow);
  120. my $zero = $o->new(0);
  121. my $one = $o->new(1);
  122. my $mone = $o->new(-1);
  123. ok($mone->is_pow($o->new(3)));
  124. ok(!($mone->is_pow($o->new(2))));
  125. ok($mone->is_pow($o->new(-3)));
  126. ok(!($mone->is_pow($o->new(-2))));
  127. ok($bint->is_pow($pow));
  128. ok($o->new(-27)->is_pow($o->new(3)));
  129. ok(!($o->new(-25)->is_pow($o->new(2))));
  130. ok(!($o->new(-27)->is_pow($o->new(-3))));
  131. ok($one->is_pow($o->new(3)));
  132. ok($one->is_pow($o->new(-2)));
  133. ok($zero->is_pow($one));
  134. ok($zero->is_pow($o->new(3)));
  135. ok(!($zero->is_pow($zero)));
  136. ok(!($zero->is_pow($o->new(-3))));
  137. ok(!($zero->is_pow($o->new(-4))));
  138. ok(!($zero->is_pow($o->new(-2))));
  139. ok(!($zero->is_pow($zero)));
  140. ok($bint->is_pow($o->new(2)));
  141. ok($bint->is_pow($o->new(3)));
  142. ok(!$bint->is_pow($o->new(4)));
  143. ok(!$bint->is_pow($o->new(5)));
  144. }
  145. ##############################################################################
  146. # Bernoulli numbers
  147. {
  148. my %results = qw(
  149. 0 1
  150. 1 1/2
  151. 2 1/6
  152. 3 0
  153. 4 -1/30
  154. 5 0
  155. 6 1/42
  156. 10 5/66
  157. 12 -691/2730
  158. 20 -174611/330
  159. 22 854513/138
  160. );
  161. #
  162. ## bernfrac()
  163. #
  164. foreach my $i (keys %results) {
  165. my $bn = $o->new($i)->bernfrac->as_rat;
  166. is("$bn", $results{$i});
  167. }
  168. is("${\($o->new(-2)->bernfrac)}", 'NaN'); # make sure we check for even correctly
  169. is($o->new(52)->bernfrac->as_frac->get_value, '-801165718135489957347924991853/1590');
  170. is($o->new(106)->bernfrac->as_frac->get_value,
  171. '36373903172617414408151820151593427169231298640581690038930816378281879873386202346572901/642');
  172. #
  173. ## bernreal()
  174. #
  175. my $r = $o->new(10);
  176. is("${\($o->new(-2)->bernreal)}", "NaN"); # check negative values
  177. is($o->new(1)->bernreal->get_value, 0.5);
  178. is($o->new(0)->bernreal->get_value, 1);
  179. is($o->new(3)->bernreal->get_value, 0);
  180. is($o->new(2)->bernreal->as_float($r)->get_value, '0.1666666667');
  181. is($o->new(52)->bernreal->as_float($r)->get_value, '-5.038778101e26');
  182. }
  183. ##############################################################################
  184. my ($x, $y, $z);
  185. $x = $o->new('1/4');
  186. $y = $o->new('1/3');
  187. like(($x->add($y))->as_rat, qr'^7/12\z');
  188. like(($x->mul($y))->as_rat, qr'^1/12\z');
  189. like(($x->div($y))->as_rat, qr'^3/4\z');
  190. $x = $o->new('2/3');
  191. $y = $o->new('3/2');
  192. ok(!($x->gt($y)));
  193. ok($x->lt($y));
  194. ok(!($x->eq($y)));
  195. $x = $o->new('-2/3');
  196. $y = $o->new('3/2');
  197. ok(!($x->gt($y)));
  198. ok($x->lt($y));
  199. ok(!($x->eq($y)));
  200. $x = $o->new('-2/3');
  201. $y = $o->new('-2/3');
  202. ok(!($x->gt($y)));
  203. ok(!($x->lt($y)));
  204. ok($x->eq($y));
  205. $x = $o->new('-2/3');
  206. $y = $o->new('-1/3');
  207. ok(!($x->gt($y)));
  208. ok($x->lt($y));
  209. ok(!($x->eq($y)));
  210. #$x = $o->new('-124');
  211. #$y = $o->new('-122');
  212. #is($x->acmp($y), $o->new(1));
  213. $x = $o->new('-124');
  214. $y = $o->new('-122');
  215. is($x->cmp($y), $o->new(-1));
  216. $x = $o->new('3/7');
  217. $y = $o->new('5/7');
  218. like(($x->add($y))->as_rat, re '8/7');
  219. $x = $o->new('3/7');
  220. $y = $o->new('5/7');
  221. like(($x->mul($y))->as_rat, re '15/49');
  222. $x = $o->new('3/5');
  223. $y = $o->new('5/7');
  224. like(($x->mul($y))->as_rat, re '3/7');
  225. $x = $o->new('3/5');
  226. $y = $o->new('5/7');
  227. like(($x->div($y))->as_rat, re '21/25');
  228. $x = $o->new('7/4');
  229. $y = $o->new('1');
  230. like(($x->mod($y))->as_rat, re '3/4');
  231. $x = $o->new('7/4');
  232. $y = $o->new('5/13');
  233. like(($x->mod($y))->as_rat, re '11/52');
  234. $x = $o->new('7/4');
  235. $y = $o->new('5/9');
  236. like(($x->mod($y))->as_rat, re '1/12');
  237. $x = $o->new('-144/9')->sqrt();
  238. is("$x", '4i');
  239. $x = $o->new('144/9')->sqrt();
  240. is("$x", '4');
  241. $x = $o->new('3/4');
  242. my $n = 'numerator';
  243. my $d = 'denominator';
  244. my $num = $x->$n;
  245. my $den = $x->$d;
  246. is("$num", 3);
  247. is("$den", 4);
  248. ##############################################################################
  249. # mixed arguments
  250. like($o->new('3/7')->add($o->new(1))->as_rat, re '10/7');
  251. like($o->new('3/10')->add($o->new(1.1))->as_rat, re '7/5');
  252. like($o->new('3/7')->sub($o->new(1))->as_rat, re '-4/7');
  253. like($o->new('3/10')->sub($o->new('1.1'))->as_rat, re '-4/5');
  254. like($o->new('3/7')->mul($o->new(1))->as_rat, re '3/7');
  255. like($o->new('3/10')->mul($o->new('1.1'))->as_rat, re '33/100');
  256. like($o->new('3/7')->div($o->new(1))->as_rat, re '3/7');
  257. like($o->new('3/10')->div($o->new('1.1'))->as_rat, re '3/11');
  258. ##############################################################################
  259. # pow
  260. $x = $o->new('2/1')->pow($o->new('3'));
  261. is("$x", '8');
  262. $x = $o->new('1/2')->pow($o->new('3'));
  263. is($x->as_frac->get_value, '1/8');
  264. is("$x", '0.125');
  265. $x = $o->new('1/3')->pow($o->new('4'));
  266. is($x->as_frac->get_value, '1/81');
  267. like("$x", qr/^0\.0123456790123456790123456790123456790123456790\d*\z/);
  268. $x = $o->new('2/3')->pow($o->new(4));
  269. is($x->as_frac->get_value, '16/81');
  270. like("$x", qr/^0\.197530864197530864197530864197530864197530864\d*\z/);
  271. $x = $o->new('2/3')->pow($o->new('5/3'));
  272. like("$x", qr/^0\.50876188557925/);
  273. ##############################################################################
  274. # fac
  275. $x = $o->new('1');
  276. $x->fac();
  277. is("$x", '1');
  278. my @fac = qw(1 1 2 6 24 120);
  279. for (my $i = 0 ; $i < 6 ; $i++) {
  280. $x = $o->new("$i/1")->fac();
  281. like($x, re $fac[$i]);
  282. }
  283. # test for $self->bnan() vs. $x->bnan();
  284. $x = $o->new('-1')->fac;
  285. is("$x", 'NaN');
  286. ##############################################################################
  287. # inc/dec
  288. $x = $o->new('3/2');
  289. like($x->inc()->as_rat, re '5/2');
  290. $x = $o->new('15/6');
  291. like($x->dec()->as_rat, re '3/2');
  292. ##############################################################################
  293. # bsqrt
  294. $x = $o->new('144');
  295. like($x->sqrt(), re '12');
  296. $x = $o->new('144/16');
  297. like($x->sqrt(), re '3');
  298. ##############################################################################
  299. # floor/ceil
  300. $x = $o->new('-7/7');
  301. like($x->$n(), re '-1');
  302. like($x->$d(), re '1');
  303. $x = $o->new('-7/7')->floor();
  304. like($x->$n(), re '-1');
  305. like($x->$d(), re '1');
  306. $x = $o->new('49/4');
  307. like($x->floor(), re '12');
  308. $x = $o->new('49/4');
  309. like($x->ceil(), re '13');
  310. ##############################################################################
  311. # root(), log(), modpow() and modinv()
  312. $x = $o->new(2)->pow($o->new(32));
  313. $y = $o->new(4);
  314. $z = $o->new(3);
  315. like($x->root($y), re '256');
  316. is(ref($x->root($y)), $o);
  317. like($x->modpow($y, $z), re '1');
  318. is(ref($x->modpow($y, $z)), $o);
  319. $x = $o->new(8);
  320. $y = $o->new(5033);
  321. $z = $o->new(4404);
  322. is($x->modinv($y), $z);
  323. is(ref($x->modinv($y)), $o);
  324. # square root with exact result
  325. $x = $o->new('1.44');
  326. like($x->root($o->new(2)), re "1.2");
  327. # log with exact result
  328. $x = $o->new('256.1');
  329. like($x->log($o->new(2)), qr/^8.0005634/);
  330. $x = $o->new(144);
  331. like($x->root($o->new('2')), re '12');
  332. $x = $o->new(12 * 12 * 12);
  333. like($x->root($o->new('3')), re '12');
  334. ##############################################################################
  335. # as_float()
  336. $x = $o->new('1/2');
  337. my $f = $x->as_float();
  338. like($x->as_rat, re '1/2');
  339. like($f, re '0.5');
  340. $x = $o->new('2/3');
  341. $f = $x->as_float($o->new(5));
  342. like($x->as_rat, re '2/3');
  343. like($f, re '0.66667');
  344. ##############################################################################
  345. # int()
  346. $x = $o->new('5/2');
  347. is(int($x), '2', '5/2 converted to integer');
  348. $x = $o->new('-1/2');
  349. is(int($x), '0', '-1/2 converted to integer');
  350. ##############################################################################
  351. # as_hex(), as_bin(), as_oct()
  352. $x = $o->new('8/8');
  353. like($x->as_hex(), re '1');
  354. like($x->as_bin(), re '1');
  355. like($x->as_oct(), re '1');
  356. $x = $o->new('80/8');
  357. like($x->as_hex(), re 'a');
  358. like($x->as_bin(), re '1010');
  359. like($x->as_oct(), re '12');
  360. ##############################################################################
  361. # done
  362. 1;