<?php
declare(strict_types=1);
namespace BCMathExtended\Tests\Unit;
use BCMathExtended\BC;
use InvalidArgumentException;
use PHPUnit\Framework\TestCase;
class BCTest extends TestCase
{
protected function setUp(): void
{
BC::setScale(2);
}
public function scientificNotationProvider(): array
{
return [
['0', '-0'],
['0', ''],
['666', '666'],
['-666', '-666'],
[
'99999999999999999999999999999999999.000000000000000000000',
'99999999999999999999999999999999999.000000000000000000000',
],
[
'99999999999999999999999999999999999.999999999999999999999',
'99999999999999999999999999999999999.999999999999999999999',
],
['1000000000000000000000000000000', '1.0E+30'],
['-1540000000000000', '-1.54E+15'],
['1540000000000000', '1.54E+15'],
['602200000000000000000000', '6.022E+23'],
['602200000000000000000000', '6.022e+23'],
['-602200000000000000000000', '-6.022e+23'],
['-602200000000000000000000', '-6.022E+23'],
['1999.99', '19.9999E+2'],
['0.00000000001', '1.0E-11'],
['0.0000051', '5.1E-6'],
['-0.00051', '-5.1E-4'],
['0.02', '2E-2'],
['0.0021', '2.1E-3'],
['0.00000003', '3E-8'],
['0.000000657', '6.57E-7'],
['5', '5e+0'],
['-5', '-5e+0'],
['5.254', '5.254e+0'],
['8853.6719', '8.8536719e+3'],
['0.00000000001', '0.00000000001'],
['-0.00116000', '-0.00116000'],
['-26.2912940386', '-2.62912940386e+1'],
['2.6', '2.6e+0'],
['1734825599220.52', '1.73482559922052e+12'],
['-57170562.129942072027205098329198887303', '-5.7170562129942072027205098329198887303e+7'],
['0.000021', '2.1e-5'],
['0.7811084054', '7.811084054e-1'],
['0', '0e+0'],
['-1.1', '-1.1e+0'],
['-4.182', '-4.182e+0'],
['23.07', '2.307e+1'],
['-2349', '-2.349e+3'],
['-230807.1307795', '-2.308071307795e+5'],
['-887126.1', '-8.871261e+5'],
[
'-0.40559318155029357183161762311247760893712676112986144952',
'-4.0559318155029357183161762311247760893712676112986144952e-1',
],
[
'-749168762.7771507445838618797279002344648652959333491',
'-7.491687627771507445838618797279002344648652959333491e+8',
],
['1.3333', '0.13333e+01'],
['100', '1e+2'],
// some rubbish..
['23', '23.1.23.0e+0..3123131'], //hmm
['345600000000', '3.456e11'],
['345600000000', '3.456e11'],
['-345600000000', '-3.456e11'],
['-345600000000', '-3.456e11'],
];
}
/**
* @dataProvider scientificNotationProvider
*/
public function testConvertScientificNotationToString(string $expected, string $number): void
{
self::assertSame($expected, BC::convertScientificNotationToString($number));
}
public function ceilProvider(): array
{
return [
['0', '-0'],
['-1', '-1'],
['-1', '-1.5'],
['-1', '-1.8'],
['-2', '-2.7'],
['0', '0'],
['1', '0.5'],
['1', '1'],
['2', '1.5'],
['2', '1.8'],
['3', '2.7'],
['0', '-0'],
['0', ''],
['0', 'null'],
['20000', '2/0000'],
['-60000', '-6/0000'],
['1000000000000000000000000000000', '+1/000000000000000000000000000000'],
['99999999999999999999999999999999999', '99999999999999999999999999999999999.000000000000000000000'],
['100000000000000000000000000000000000', '99999999999999999999999999999999999.999999999999999999999'],
['0', '0-'],
['100000000000000000000000000000000000', '1.0E+35'],
['-100000000000000000000000000000000000', '-1.0E+35'],
['1', '3E-8'],
['1', '1.0E-11'],
];
}
/**
* @dataProvider ceilProvider
*/
public function testCeil(string $expected, string $number): void
{
self::assertSame($expected, BC::ceil($number));
}
public function floorProvider(): array
{
return [
['0', '-0'],
['-1', '-0.5'],
['-1', '-1'],
['-2', '-1.5'],
['-2', '-1.8'],
['-3', '-2.7'],
['0', '0'],
['0', '0.5'],
['1', '1'],
['1', '1.5'],
['1', '1.8'],
['2', '2.7'],
['0', '-0'],
['0', ''],
['0', 'null'],
['20000', '2/0000'],
['-60000', '-6/0000'],
['1000000000000000000000000000000', '+1/000000000000000000000000000000'],
[
'99999999999999999999999999999999999',
'99999999999999999999999999999999999.000000000000000000000',
],
[
'99999999999999999999999999999999999',
'99999999999999999999999999999999999.999999999999999999999',
],
['0', '0-'],
['100000000000000000000000000000000000', '1.0E+35'],
['-100000000000000000000000000000000000', '-1.0E+35'],
['0', '3E-8'],
['0', '1.0E-11'],
];
}
/**
* @dataProvider floorProvider
*/
public function testFloor(string $expected, string $number): void
{
self::assertSame($expected, BC::floor($number));
}
public function absProvider(): array
{
return [
['1', '-1'],
['1.5', '-1.5'],
['1', '-1'],
['1.5', '-1.5'],
[
'9999999999999999999999999999999999999999999999999999999',
'-9999999999999999999999999999999999999999999999999999999',
],
['0', '-0'],
['0', ''],
['0', 'null'],
['20000', '2/0000'],
['60000', '-6/0000'],
['1000000000000000000000000000000', '+1/000000000000000000000000000000'],
['0', '0-'],
['100000000000000000000000000000000000', '1.0E+35'],
['100000000000000000000000000000000000', '-1.0E+35'],
['0.0000051', '-5.1E-6'],
];
}
/**
* @dataProvider absProvider
*/
public function testAbs(string $expected, string $number): void
{
self::assertSame($expected, BC::abs($number));
}
public function roundProvider(): array
{
return [
['3', '3.4'],
['4', '3.5'],
['4', '3.6'],
['2', '1.95583'],
['2', '1.95583'],
['1.96', '1.95583', 2],
['1.956', '1.95583', 3],
['1.9558', '1.95583', 4],
['1.95583', '1.95583', 5],
['1241757', '1241757'],
['1241757', '1241757', 5],
['-3', '-3.4'],
['-4', '-3.5'],
['-4', '-3.6'],
['123456.745671', '123456.7456713', 6],
['1', '1.11'],
['1.11', '1.11', 2],
['0.1666666666667', '0.1666666666666665', 13],
['0', '0.1666666666666665', 0],
['10', '9.999'],
['10', '9.999', 2],
['0.01', '0.005', 2],
['0.02', '0.015', 2],
['0.03', '0.025', 2],
['0.04', '0.035', 2],
['0.05', '0.045', 2],
['0.06', '0.055', 2],
['0.07', '0.065', 2],
['0.08', '0.075', 2],
['0.09', '0.085', 2],
['77777777777777777777777777777', '77777777777777777777777777777.1'],
[
'100000000000000000000000000000000000',
'99999999999999999999999999999999999.99999999999999999999999999999999991',
],
[
'99999999999999999999999999999999999',
'99999999999999999999999999999999999.00000000000000000000000000000000001',
],
['99999999999999999999999999999999999', '99999999999999999999999999999999999.000000000000000000000'],
['0', '-0'],
['0', ''],
['0', 'null'],
['20000', '2/0000'],
['-60000', '-6/0000'],
['1000000000000000000000000000000', '+1/000000000000000000000000000000'],
['0', '0-'],
['100000000000000000000000000000000000', '1.0E+35'],
['-100000000000000000000000000000000000', '-1.0E+35'],
['0', '3E-8'],
['0', '1.0E-11'],
['-0.0006', '-5.6E-4', 4],
['0.000000001', '9.9999E-10', 10],
];
}
/**
* @dataProvider roundProvider
*/
public function testRound(string $expected, string $number, int $precision = 0): void
{
self::assertSame($expected, BC::round($number, $precision));
}
public function roundHalfEvenProvider(): array
{
return [
['2', '1.8'],
['2', '1.5'],
['1', '1.2'],
['1', '0.8'],
['0', '0.5'],
['0', '0.2'],
['0', '-0.2'],
['0', '-0.5'],
['-1', '-0.8'],
['-1', '-1.2'],
['-2', '-1.5'],
['-2', '-1.8'],
['-2.35', '-2.35', 2],
['-2.4', '-2.35', 1],
['2.4', '2.35', 1],
['0', '0.005', 2],
['0.02', '0.015', 2],
['0.02', '0.025', 2],
['0.04', '0.035', 2],
['0.04', '0.045', 2],
['0.06', '0.055', 2],
['0.06', '0.065', 2],
['0.08', '0.075', 2],
['0.08', '0.085', 2],
['1.13', '1.1259', 2],
['100', '100', 0],
];
}
/**
* @dataProvider roundHalfEvenProvider
*/
public function testRoundHalfEven(string $expected, string $number, int $precision = 0): void
{
self::assertSame($expected, BC::roundHalfEven($number, $precision));
}
public function randProvider(): array
{
return [
['1', '3'],
['432423432423423423423423432432423423423', '999999999999999999999999999999999999999999'],
];
}
/**
* @dataProvider randProvider
*/
public function testRand(string $left, string $right): void
{
$rand = BC::rand($left, $right);
self::assertTrue($rand >= $left);
self::assertTrue($rand <= $right);
}
public function testMax(): void
{
self::assertSame('3', BC::max(1, 2, 3));
self::assertSame('6', BC::max(6, 3, 2));
self::assertSame('999', BC::max(100, 999, 5));
self::assertSame('677', BC::max([3, 5, 677]));
self::assertSame('-3', BC::max([-3, -5, -677]));
self::assertSame(
'999999999999999999999999999999999999999999',
BC::max(
'432423432423423423423423432432423423423',
'999999999999999999999999999999999999999999',
'321312312423435657'
)
);
self::assertSame('0.00000000099999', BC::max(9.9999E-10, -5.6E-4));
}
public function testMin(): void
{
self::assertSame('7.20', BC::min('7.30', '7.20'));
self::assertSame('3', BC::min([3, 5, 677]));
self::assertSame('-677', BC::min([-3, -5, -677]));
self::assertSame(
'321312312423435657',
BC::min(
'432423432423423423423423432432423423423',
'999999999999999999999999999999999999999999',
'321312312423435657'
)
);
self::assertSame('-0.00056', BC::min(9.9999E-10, -5.6E-4));
}
public function setScaleProvider(): array
{
return [
[50, '3', '1', '2'],
[0, '3', '1', '2'],
[13, '3', '1', '2'],
];
}
/**
* @dataProvider setScaleProvider
*/
public function testSetScale(int $scale, string $expected, string $left, string $right): void
{
BC::setScale($scale);
self::assertSame($expected, BC::add($left, $right));
}
public function roundUpProvider(): array
{
return [
['663', '662.79'],
['662.8', '662.79', 1],
['60', '54.1', -1],
['60', '55.1', -1],
['-23.6', '-23.62', 1],
['4', '3.2'],
['77', '76.9'],
['3.142', '3.14159', 3],
['-3.1', '-3.14159', 1],
['31500', '31415.92654', -2],
['31420', '31415.92654', -1],
['0.0119', '0.0119', 4],
['0', '-0'],
['0', ''],
['0', 'null'],
['0', '0-'],
['1', '9.9999E-10'],
];
}
/**
* @dataProvider roundUpProvider
*/
public function testRoundUp(string $expected, string $number, int $precision = 0): void
{
self::assertSame($expected, BC::roundUp($number, $precision));
}
public function roundDownProvider(): array
{
return [
['662', '662.79'],
['662.7', '662.79', 1],
['50', '54.1', -1],
['50', '55.1', -1],
['-23.7', '-23.62', 1],
['3', '3.2'],
['76', '76.9'],
['3.141', '3.14159', 3],
['-3.2', '-3.14159', 1],
['31400', '31415.92654', -2],
['31410', '31415.92654', -1],
['0.0119', '0.0119', 4],
['0', '-0'],
['0', ''],
['0', 'null'],
['0', '0-'],
['0', '9.9999E-10'],
['1.12', '1.1259', 2],
];
}
/**
* @dataProvider roundDownProvider
*/
public function testRoundDown(string $expected, string $number, int $precision = 0): void
{
self::assertSame($expected, BC::roundDown($number, $precision));
}
public function addProvider(): array
{
return [
['3', '1', '2'],
['2', '1', '1'],
['15', '10', '5'],
['2.05', '1', '1.05', 2],
['4', '-1', '5', 4],
['8728932003911564969352217864684', '1928372132132819737213', '8728932001983192837219398127471', 2],
['-0.00055999', '9.9999E-10', '-5.6E-4', 8],
['15.000000000000311', '3.11e-13', '15', 15],
['3110000015', '3.11e9', '15', 0],
];
}
/**
* @dataProvider addProvider
*/
public function testAdd(string $expected, string $left, string $right, ?int $scale = 0): void
{
self::assertSame($expected, BC::add($left, $right, $scale));
}
public function testAddUsingGlobalScale(): void
{
BC::setScale(0);
self::assertSame('2', BC::add('1', '1.05'));
self::assertSame('2.05', BC::add('1', '1.05', 2));
BC::setScale(2);
self::assertSame('2', BC::add('1', '1.05', 0));
self::assertSame('2.05', BC::add('1', '1.05'));
}
public function testSubUsingGlobalScale(): void
{
BC::setScale(0);
self::assertSame('-1', BC::sub('1', '2.5'));
self::assertSame('-1.5', BC::sub('1', '2.5', 2));
BC::setScale(2);
self::assertSame('-1', BC::sub('1', '2.5', 0));
self::assertSame('-1.5', BC::sub('1', '2.5'));
}
public function subProvider(): array
{
return [
['-1', '1', '2'],
['0', '1', '1'],
['5', '10', '5'],
['-1.5', '1', '2.5', 2],
['-6', '-1', '5', 4],
['8728932000054820705086578390258', '8728932001983192837219398127471', '1928372132132819737213', 2],
['0.00056', '9.9999E-10', '-5.6E-4', 8],
];
}
/**
* @dataProvider subProvider
*/
public function testSub(string $expected, string $left, string $right, ?int $scale = 0): void
{
self::assertSame($expected, BC::sub($left, $right, $scale));
}
public function compProvider(): array
{
return [
['-1', '5', BC::COMPARE_RIGHT_GRATER, 4],
['1928372132132819737213', '8728932001983192837219398127471', BC::COMPARE_RIGHT_GRATER, 1],
['1.00000000000000000001', '2', BC::COMPARE_RIGHT_GRATER, 1],
['97321', '1', BC::COMPARE_LEFT_GRATER, 2],
['1', '0', BC::COMPARE_LEFT_GRATER, 0],
['1', '1', BC::COMPARE_EQUAL, 0],
['0', '1', BC::COMPARE_RIGHT_GRATER, 0],
['1', '0', BC::COMPARE_LEFT_GRATER, 0],
['1', '1', BC::COMPARE_EQUAL, 0],
['0', '1', BC::COMPARE_RIGHT_GRATER, 0],
['1', '0.0005', BC::COMPARE_LEFT_GRATER, 4],
['1', '0.000000000000000000000000005', BC::COMPARE_LEFT_GRATER, 2],
];
}
/**
* @dataProvider compProvider
*/
public function testComp(string $left, string $right, int $expected, int $scale): void
{
self::assertSame($expected, BC::comp($left, $right, $scale));
}
public function getScaleProvider(): array
{
return [
[10],
[25],
[0],
];
}
/**
* @dataProvider getScaleProvider
*/
public function testGetScale(int $expected): void
{
BC::setScale($expected);
self::assertSame($expected, BC::getScale());
}
public function divProvider(): array
{
return [
['0.5', '1', '2', 2],
['-0.2', '-1', '5', 4],
['4526580661.75', '8728932001983192837219398127471', '1928372132132819737213', 2],
['0.000000000099999', '9.9999E-10', '10', 15],
];
}
/**
* @dataProvider divProvider
*/
public function testDiv(string $expected, string $left, string $right, ?int $scale): void
{
self::assertSame($expected, BC::div($left, $right, $scale));
}
public function testThrowDivByZero(): void
{
$this->expectExceptionMessage('Division by zero');
$this->expectException(InvalidArgumentException::class);
BC::div('1', '0');
}
public function testDivUsingGlobalScale(): void
{
BC::setScale(0);
self::assertSame('0', BC::div('1', '2'));
self::assertSame('0.5', BC::div('1', '2', 2));
BC::setScale(2);
self::assertSame('0', BC::div('1', '2', 0));
self::assertSame('0.5', BC::div('1', '2'));
}
public function modProvider(): array
{
return [
['1', '11', '2', 0],
['-1', '-1', '5', 0],
['1459434331351930289678', '8728932001983192837219398127471', '1928372132132819737213', 0],
['0', '9.9999E-10', '1', 0],
['0.5', '10.5', '2.5', 2],
['0.5', '10.5', '2.5', 2],
['0.8', '10', '9.2', 1],
['0', '20', '4.0', 1],
['0', '10.5', '3.5', 1],
['0.3', '10.2', '3.3', 1],
['-0.000559999', '9.9999E-10', '-5.6E-4', 9],
];
}
/**
* @dataProvider modProvider
*/
public function testMod(string $expected, string $left, string $right, int $scale): void
{
self::assertSame($expected, BC::mod($left, $right, $scale));
}
public function mulProvider(): array
{
return [
['1', '1.5', '1.5', 1],
['10', '1.2500', '12.5', 2],
['100', '0.29', '29', 0],
['100', '0.029', '2.9', 1],
['100', '0.0029', '0.29', 2],
['1000', '0.29', '290', 0],
['1000', '0.029', '29', 0],
['1000', '0.0029', '2.9', 1],
['2000', '0.0029', '5.8', 1],
['1', '2', '2', 2],
['-3', '5', '-15', 2],
['1234567890', '9876543210', '12193263111263526900', 2],
['2.5', '1.5', '3.75', 2],
['2.555', '1.555', '3.97', 2],
['9.9999E-2', '-5.6E-2', '-0.005599944', 9],
];
}
/**
* @dataProvider mulProvider
*/
public function testMul(string $leftOperand, string $rightOperand, string $expected, ?int $scale): void
{
self::assertSame($expected, BC::mul($leftOperand, $rightOperand, $scale));
}
public function powProvider(): array
{
return [
['256', '2', '8', 0],
['74.08', '4.2', '3', 2],
['-32', '-2', '5', 4],
['18446744073709551616', '2', '64', 0],
['-108.88', '-2.555', '5', 2],
['63998080023999840000.5999988', '19.9999E+2', '6', 9],
[
'1229984803535237425357460579824952453848609953896821302286319065669207712270213276022808840210306942692366529569453244416',
'66',
'66',
0,
],
['1', '0', '0', 0],
['0.1', '10', '-1', 1],
['1.0837983867343681398392334849264865554733', '5', '0.05', 40],
['59.3839', '8', '1.964', 4],
['1', '10', '0.0000001', 0],
['1', '10', '0.0000001', 2],
['36.029', '5.1', '2.2', 3],
['0.5492944034820568190269179209773099881437', '1.005', '-120.12345678', 40],
];
}
/**
* @dataProvider powProvider
*/
public function testPow(string $expected, string $left, string $right, ?int $scale = 0): void
{
self::assertSame($expected, BC::pow($left, $right, $scale));
}
public function logProvider(): array
{
return [
[
'0.6931471805599453094172321214581765680755001343602552541206800094933936219696947156058633269964186879',
'2',
],
[
'2.3025850929940456840179914546843642076011014886287729760333279009675726096773524802359972050895982985',
'10',
],
[
'-INF',
'0',
],
[
'0',
'1',
],
[
'NAN',
'-1',
],
];
}
/**
* @dataProvider logProvider
*/
public function testLog(string $expected, string $value): void
{
self::assertSame($expected, BC::log($value));
}
public function expProvider(): array
{
return [
[
'298.8674009670602326720280305552958844792720557285859930698483175291494073935732314440167229005529804941',
'5.7',
],
[
'5009718959.9179776145898629945755344777367448017822374820837617183949259570367010764387804812833108859845756998',
'22.334645654645',
],
[
'0.3678794411714423215955237701614608674458111310317678345078368016974614957448998033571472743459196437',
'-1',
],
[
'1',
'0',
],
[
'1021450427617659.4094516982518620090788645038742627301331924304676748729927177787220453326541582910229003291582467933',
'3.456e1',
],
];
}
/**
* @dataProvider expProvider
*/
public function testExp(string $expected, string $arg): void
{
self::assertSame($expected, BC::exp($arg));
}
public function factProvider(): array
{
return [
['1', 'FOO'],
['6', '3'],
['24', '4'],
['120', '5'],
['12696403353658275925965100847566516959580321051449436762275840000000000000', '55'],
[
'1352120101970733773067011614274819697122599483131811908183737047628177265994034132291368713461649497349302589856143133435229510116396294837506877692006315661432915834997174910826068673360566341497288989997209954743556681697531481588638027960571240359783423531512393979498023752359924002706644565826435712121847113827344984006487098528182570814184286177369204400602363840908701270850750232905962380555370342454089529954739412757066091123167095526161838186578820110955607100824438507032320782992357615916749432532447527368676631859661521238760870735527498653795183539783564690884483063180835764379492982520378977182244324512341018150509625525378905237230283986134834548153407352954715849859625768547943765161546418930836848064948451279093982894200819727754989070021704775797730750238107994872656828695516417881633934002199666960973645243375443246651301541333655652238296995689775354768542007545075142984211576541365557119557540627643329393683436387728118677828867857740757132233113516693527211814574739338293271460885570441349231351752383433352765975545204375912432594596113332741119354939353014503322387908651048263510102330371491105379688834342735823028755445146907083524895708398217607871080941341652914407671398367518509530325036889967085438794341130203490432090168747436904916918651173414472969992936827322290441286162500190109938519460450826861557230028805295622910014088032828346719679517421247715020534537700965849660883032302717019644562433150024635604762052002534028696629046990072858757588435951741887858588348113453649702435529712275328734772200798824647783552298277793615161059963699445498256000077540527301059550783529092098564446519833883557504895944421503363619527476998068362404201929345421647714763941354568414779882124491156177862842542815506817685490004739467429347446618659579953462063079757736600753871877067083965237845213240010848581504831053975434425143171746631341762195342736634638129582085373475793944488694512602143694792948257271921140153640603343096248881341215081509400288581408435215549715915260473296819413135019859948374962046712488759726342119726826901506105396218407578855410289091823224308767092452169221737093493587297758858417573680905241101368865449581132523234774846630787586927672276856400694036146591236722557130579954111692826164834542054936860327798863571665477779826251029086223483796906779089487784145495378256136425915177355034898173950147490682126470336438593281560487283159506304621370530261708627129060553915509003975468090346375866276033394920320678432457143507723107122487195374519128978668296580081062332375853436617376879980116152400514000392596929419052997064108467277989862501470384743645675198143314964216720733011237794071202653538264770997343051525931760263574123279062668951096284013681437574586191015603626739281515733205332994849968660671183273822108848740739542594997209308985543929302889180711874734873521273053528846156754996593353832701400704122512249925895034727323372449016472717793021639824951160265330662841601481925693783522925057812098900177609172565210004384736787468976183572374389866970896876729283713848904742983177352243630752419854642087694908122374322997951504415719963497682903859528697835977460808683230919315768931320321515572756803021410702219574222854791625348206167001024307602312292274062783656313069811273748388957231168299593456124069326155054222350440615253925773104703909512962614769075725229805737146418789996836311534187921166588053060653570084646462567237637902199048768915146311997127035919225466123766967732669086045035741874988471283181730605371604597281737626169543071041569095277933284149606769679089217424933371700178273937138278648458324132426529709883371763283712076074348683393641921474293431751961856826381800033652192885044485408096653004376245673073573167133545715282194839672509402656047674960172191002707776969993708883002946569483638775035028406280030045680099965963352967687712780415844194344897034867035649238735417907284480143800715923875226999988182837399775375032771365049990944279400177666169025474822560599277998078660375551951259606461334237444393907826059364572995077012696500217571481359989544121387805436811766656562426437674715462409672464285545179178656627209567861141385839660668523900041470576453589931144057302653030962570219302927462587782634610438021502841017584951874606688047253850643655244112919192792819462728160774912708068851493794723457166187479660457072589244982411564768691660373121926807493884960044548017084897020763855207653681096759142002538226845404372799721685705572634438220271114429420133733951367785285045015242008542653557707317451857972154654382589317549090816442222028837987889474372606419089374814467969896617039883595672111439205446056522484144835457023481497028559622902200558019868118246599782160047265704558098918522653452115528498393826050243781982164817504322506948067517212641792764493495897458412764877555887954848260359825696806281379301363345037981603241039149654502867961958451074927305138707709064067972599358554012791947848815290502895895860449670062560156040554849129569699278138934666508929878995893935747162189359711443358863173891265526226063435539120837625829638607194040524668720159344401629952773505778079352490821105274251986635668955237486825386746806409531711107991700074469550018959692530976626932834845278877276910533814229212661693460909241564118904928212460243057459003602392795914829610139931664352827606322648351888396817703519638140804131058812545855808475244859924876181478011379330289041290637623990235765095562678716591049279750452157666526740287900476731608369483988928999686707572922693981700802433912039899996007955549400467969054090810822620301958626526282042169285939649535367207857745108450969447098437807317727774253678971042666633565535058826907799225976904526915064162232477244522769483279502195056391311845087471891767935107410797095722827132957212481902147148757254626945121374919137154163065062186579710977767318846783049909516922471026817599405710343608499199244540993787974291529714016949175605461772769321738528529439505603179052626064457271898086735983761791376964239234728566142708083390935543815061352142697561148552832340249191226591947656969923293812987346346579553020648796718123999227633510804333685665336946322035397517106771942515502711510070956498459423946691815638510496076491288834098753445908737263754155130880000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000',
'2.349e+3',
],
];
}
/**
* @dataProvider factProvider
*/
public function testFact(string $expected, string $fact): void
{
self::assertSame($expected, BC::fact($fact));
}
public function testFactThrowErrorOnFloat(): void
{
$this->expectExceptionMessage('Number has to be an integer');
$this->expectException(InvalidArgumentException::class);
BC::fact('1.1');
}
public function testFactThrowErrorOnNegative(): void
{
$this->expectExceptionMessage('Number has to be greater than or equal to 0');
$this->expectException(InvalidArgumentException::class);
BC::fact('-1');
}
public function testPowUsingGlobalScale(): void
{
BC::setScale(0);
self::assertSame('74', BC::pow('4.2', '3'));
self::assertSame('74.08', BC::pow('4.2', '3', 2));
BC::setScale(2);
self::assertSame('74', BC::pow('4.2', '3', 0));
self::assertSame('74.08', BC::pow('4.2', '3'));
}
public function powModProvider(): array
{
return [
['4', '5', '2', '7', 0],
['4', '5', '2', '7', null],
['-4', '-2', '5', '7', 0],
['790', '10', '2147483648', '2047', 0],
['790', '1E+1', '2E+8', '2047', 0],
['4', '5', '2', '7', 2],
['3.7', '5', '2', '7.1', 2],
['3.7', '5', '2', '7.1', 2],
['1', '4', '4', '3', 2],
['0.52', '5.1', '2.2', '7.1', 2],
['0.52', '5.1', '2.2', '7.1', null],
];
}
/**
* @dataProvider powModProvider
*/
public function testPowMod(string $expected, string $left, string $right, string $modulus, ?int $scale): void
{
self::assertSame($expected, BC::powMod($left, $right, $modulus, $scale));
}
public function sqrtProvider(): array
{
return [
['3', '9', 0],
['3.07', '9.444', 2],
['43913234134.28826', '1928372132132819737213', 5],
['0.31', '9.9999E-2', 2],
];
}
/**
* @dataProvider sqrtProvider
*/
public function testSqrt(string $expected, string $operand, int $scale): void
{
self::assertSame($expected, BC::sqrt($operand, $scale));
}
public function testSqrtUsingGlobalScale(): void
{
BC::setScale(0);
self::assertSame('3', BC::sqrt('9.444'));
self::assertSame('3.07', BC::sqrt('9.444', 2));
BC::setScale(2);
self::assertSame('3', BC::sqrt('9.444', 0));
self::assertSame('3.07', BC::sqrt('9.444'));
}
public function hexdecProvider(): array
{
return [
['123', '7b'],
['1234567890', '499602d2'],
['12345678901234567890', 'ab54a98ceb1f0ad2'],
['123456789012345678901234567890', '18ee90ff6c373e0ee4e3f0ad2'],
['1234567890123456789012345678901234567890', '3a0c92075c0dbf3b8acbc5f96ce3f0ad2'],
['1234567890123456789012345678901234567890', '3a0c92075c0dbf3b8acbc5f96ce3f0ad2'],
[
'21711016733383976335769713789619838426107890367109022384973563144062439196678',
'0x300000000d2c12440c4310c20c2428c20c8330cc0ca318ca0cc330cc0c230806',
],
];
}
/**
* @dataProvider hexdecProvider
*/
public function testHexdec(string $expected, string $operand): void
{
self::assertSame($expected, BC::hexdec($operand));
}
public function dechexProvider(): array
{
return [
['7b', '123'],
['ffffffff', '4294967295'],
['200000000', '8589934592'],
['7fffffffffffffff', '9223372036854775807'],
['10000000000000000', '18446744073709551616'],
['18ee90ff6c373e0ee4e3f0ad2', '123456789012345678901234567890'],
];
}
/**
* @dataProvider dechexProvider
*/
public function testDechex(string $expected, string $operand): void
{
self::assertSame($expected, BC::dechex($operand));
}
/**
* @dataProvider bitAddProvider
*/
public function testBitAdd(string $expected, string $left, string $right): void
{
self::assertSame($expected, BC::bitAnd($left, $right));
}
public function bitAddProvider(): array
{
return [
[
'2972225677459078825024027220918272',
'1000000000865464564564564567867867867800000',
'5000788676546456456458678760000000',
],
['610237752474644548', '543543543534543534543534543 ', '4213434324324234324'],
['0', '0', '0'],
['0', '0', '5'],
['1', '1', '5'],
['0', '2', '5'],
['4', '4', '5'],
['4', '-4', '5'],
['0', '4', '-5'],
['0', '8', '5'],
];
}
/**
* @dataProvider bitOrProvider
*/
public function testBitOr(string $expected, string $left, string $right): void
{
self::assertSame($expected, BC::bitOr($left, $right));
}
public function bitOrProvider(): array
{
return [
[
'1000000002894027563651942199302519406881728',
'1000000000865464564564564567867867867800000',
'5000788676546456456458678760000000',
],
['543543547137740106393124319', '543543543534543534543534543 ', '4213434324324234324'],
['0', '0', '0'],
['5', '0', '5'],
['5', '1', '5'],
['7', '2', '5'],
['5', '4', '5'],
['-3', '-4', '5'],
['-1', '4', '-5'],
['13', '8', '5'],
['-853289843298817', '-3213123123123123', '-999696956946954'],
['-113449967538441782579763', '-677868678631231237867786867', '-123213213123123123123123'],
];
}
/**
* @dataProvider bitXorProvider
*/
public function testBitXor(string $expected, string $left, string $right): void
{
self::assertSame($expected, BC::bitXor($left, $right));
}
public function bitXorProvider(): array
{
return [
['7', '2', '5'],
['-8', '3', '-5'],
['-6', '-4', '6'],
['15', '-8', '-9'],
['32111810161015317381218', '21312831290381290382198', '10912839021839123211028'],
['-2', '999999999999999999999999999999999', '-999999999999999999999999999999999'],
['0', '999999999999999999999999999999999', '999999999999999999999999999999999'],
['-2', '-999999999999999999999999999999999', '999999999999999999999999999999999'],
];
}
public function testThrowErrorOnFloatXorLeftOperator(): void
{
$this->expectExceptionMessage('Left operator has to be an integer');
$this->expectException(InvalidArgumentException::class);
BC::bitXor('0.001', '1');
}
public function testThrowErrorOnNegativeModPowExponent(): void
{
$this->expectExceptionMessage('Exponent can\'t be negative');
$this->expectException(InvalidArgumentException::class);
BC::powMod('10000.123', '-1', '2');
}
public function testThrowErrorOnZeroModPowModulus(): void
{
$this->expectExceptionMessage('Modulus can\'t be zero');
$this->expectException(InvalidArgumentException::class);
BC::powMod('10000.123', '1', '0');
}
public function testThrowErrorOnFloatOrLeftOperator(): void
{
$this->expectExceptionMessage('Left operator has to be an integer');
$this->expectException(InvalidArgumentException::class);
BC::bitOr('0.001', '1');
}
public function testThrowErrorOnFloatAndLeftOperator(): void
{
$this->expectException(InvalidArgumentException::class);
$this->expectExceptionMessage('Left operator has to be an integer');
BC::bitAnd('0.001', '1');
}
public function testThrowErrorOnFloatXorRightOperator(): void
{
$this->expectExceptionMessage('Right operator has to be an integer');
$this->expectException(InvalidArgumentException::class);
BC::bitXor('1', '0.001');
}
public function testThrowErrorOnFloatOrRightOperator(): void
{
$this->expectExceptionMessage('Right operator has to be an integer');
$this->expectException(InvalidArgumentException::class);
BC::bitOr('1', '0.001');
}
public function testThrowErrorOnFloatAndRightOperator(): void
{
$this->expectException(InvalidArgumentException::class);
$this->expectExceptionMessage('Right operator has to be an integer');
BC::bitAnd('1', '0.001');
}
/**
* @dataProvider convertBinaryProvider
*/
public function testConvertBinary(string $expected, string $base64binary): void
{
$decoded = (string)base64_decode($base64binary, true);
self::assertSame($expected, BC::bin2dec($decoded));
self::assertSame($decoded, BC::dec2bin($expected));
}
public function convertBinaryProvider(): array
{
return [
['1000000000865464564564564567867867867800000', 'C3q8Ypr74y+H5r28hvnkbmHA'],
['5000788676546456456458678760000000', '9o7TsLbE7mZg8DmCSgA'],
['543543543534543534543534543', 'AcGb0ol63k727vnP'],
['2', 'Ag=='],
['48', 'MA=='],
];
}
public function testThrowErrorOnIncorrectBaseInBin2Dec(): void
{
$this->expectExceptionMessage('Invalid Base: 300');
$this->expectException(InvalidArgumentException::class);
BC::bin2dec('', 300);
}
public function testThrowErrorOnIncorrectBaseInDec2Bin(): void
{
$this->expectException(InvalidArgumentException::class);
$this->expectExceptionMessage('Invalid Base: 600');
BC::dec2bin('1', 600);
}
public function testCorrectFormatTrailingZeros(): void
{
BC::setTrimTrailingZeroes(false);
self::assertSame('64.0000000000', BC::pow('8', '2', 10));
self::assertSame('2.0000', BC::sqrt('4', 4));
self::assertSame('14444.2230000000', BC::add('10000.123', '4444.1', 10));
self::assertSame('19.524770142330000', BC::mul('9.123767', '2.13999', 15));
self::assertSame('2.00', BC::div('4.000', '2.0', 2));
self::assertSame('5556.0230000000', BC::sub('10000.123', '4444.1', 10));
self::assertSame('1.35', BC::powMod('10000.123', '4444.1', '2'));
self::assertSame('1111.9230000000', BC::mod('10000.123', '4444.1', 10));
self::assertSame('-50000000000.0000000000', BC::convertScientificNotationToString('-5e+10'));
self::assertSame('10000.123000', BC::round('10000.123', 6));
BC::setTrimTrailingZeroes(true);
self::assertSame('64', BC::pow('8', '2', 10));
self::assertSame('2', BC::sqrt('4', 4));
self::assertSame('14444.223', BC::add('10000.123', '4444.1', 10));
self::assertSame('19.52477014233', BC::mul('9.123767', '2.13999', 15));
self::assertSame('2', BC::div('4.000', '2.0', 2));
self::assertSame('5556.023', BC::sub('10000.123', '4444.1', 10));
self::assertSame('1.35', BC::powMod('10000.123', '4444.1', '2'));
self::assertSame('1111.923', BC::mod('10000.123', '4444.1', 10));
self::assertSame('-50000000000', BC::convertScientificNotationToString('-5e+10'));
self::assertSame('10000.123', BC::round('10000.123', 6));
}
}
|