Jump to content

Control calculator expression logic


keenlearner

Recommended Posts

Hello I am building a PHP scientific calculator, users can perform calculation by just typing like normal mathematical expressions, e.g "(2+3-4^6)/33.3* 4!" so the result will be calculated accordingly, but I have a problem that, when malicious users try to put a mathematical expressions that is very long enough and takes a very heavy load of processing which might make my web server down. Such as

 

"9999999999999999999999999999999999999999999999999999999 * 999999999999999999999999999999"

 

So I thought of limiting the expressions that users can input up to 50 characters long, but this is still not a good idea, because heavy calculations does not necessarily depends on the length of the expressions, such as

 

//This does not make my computer load heavily

"1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1"

 

//But this one takes quite long and consume high processing power.

"999999999^99999"

 

So I want to know, is there a logic that can actually determines the result which might consume high processing which can solve my problem ? or is there a good scientific calculator library that you might want to share ? Thanks a lot.

Link to comment
Share on other sites

Thanks, for the reply

When I tried it on my localhost, "9999999^9999999999999999999" it really makes my processors lights on without blinking for quite a few seconds and finally makes my apache hang for 1.83 Ghz Duo core processors with 1.5 GB RAM.

I believe there must be logic, because you can try in Google, type "999^99", it gives you result of calculation, but if you tried "999^103" . Google won't give you the result, because it seems that they will not calculate expression that will give result that exceed around 9.02983468 × 10^305

teng84, I have tried a few nested if, but seems that I still can't get the logic close to perfect yet, can you give me a brief algorithm for that ? Thanks

Link to comment
Share on other sites

what you could do is apply some javascript to it

first don't let the user edit the calculation area (make a javascript onfocus event to blur it)

secondly if someone tries to calculate a ridiculous number like 99^99^99 in the coding do a test if the answer is greater than what max size is for a float. if that is the case tell it to break right away and give an overflow error.  Also make t so they dont' have direct input make buttons like a calculator (you can use hotkeys too to get that feel too).  Also maybe you could use ajaxs to test the output as they are inputting to test for overflows before it goes to that point (i.e 99^99 and they try to enter another ^99 say overflow.)

 

Just a few ideas

Link to comment
Share on other sites

How if expression that has only one operator 99^999 and also its result is too big to be handled. It's important that we need to decide whether the expressions is too be to be handled BEFORE the calculation is made, because if we can only decide whether to calculate the expression or not AFTER the calculation is made our Apache server already hang. I think it goes the same for browser as well, instead of making our Apache hang, it will make the users browser hang.

 

I have tried something out below but still not solving.

Let's say 999^999 will make my apache server hang, let the base and the power be x and y respectively, x ^ y

So if I limit the x and y to be 900 respectively, 900^900. so the the following should be OK

800^400

700^900

2^900

 

since x or y are equal or less than 900

But problem is this line below should be allowed too, because the result still less than 900^900 and does not make heavy load.

2^1000

But since we limit the y to be 900, this will not be calculated, which is a bad idea too. I so eager to solve this, but so far have not get a good solutions, but I believe there is a logic like Google's. Thanks.

Link to comment
Share on other sites

Thanks cooldude832, that is what I did initially but still not solving the problem if

$xmax = 900;
$ymax = 900;

if($_GET['x'] > $xmax && $_GET['y'] > $ ymax) //overflow 

//But we should allowed if 
$_GET['x'] = 2
$_GET['y'] = 1000;
//because this calculation still ok.

 

I think the solutions might be something closed to Barand's, but so still we need to type a lot of threshold number (thousands)

if 2^1000 is OK but 999^1000 is not OK then for each x you need an upper y threshold

 

But I bet there is a formula to determine the heavy calculations, of it.

Link to comment
Share on other sites

Thanks Barand, I am still looking up for solutions until now.

 

It's important that we need to decide whether the expressions is too big to be handled BEFORE the calculation is made, because if we can only decide whether to calculate the expression AFTER the calculation is made, our Apache server will/already hang.

<?php
function safePow($x, $y)
{
    $r = pow($x,$y);
    return $r < 1.79e308 ? $r : 'overflow!';
}

//if we check whether this is safePow
echo safePow(999, 9999999999999); 
//my apache server could already hang before it return the result.
?>

 

I still believe there is a formula.

Link to comment
Share on other sites

Suggest change of server ;)

 

<?php
function safePow($x, $y)
{
    $r = pow($x,$y);
    return $r < 1.79e308 ? $r : 'overflow!';
}

$inputs = array (
           '999^9999999999999',
           '2^9999',
           '99^99',
           '9^9'
        );

echo '<pre>';

printf ("\n%-20s : %25s : %8s\n", 'expression', 'result', 'seconds'); 
printf ("\n%-20s : %25s : %8s\n", '--------------------', '-------------------------', '--------'); 

foreach ($inputs as $expr)
{
    list ($x, $y) = explode('^', $expr);

    $t1 = microtime(1);
    $p = safePow ($x, $y);
    $t2 = microtime(1);
    printf ("\n%-20s : %25s : %0.6f\n", $expr, $p, $t2-$t1); 
}

echo '</pre>';
?>

 

Results -->[pre]

expression          :                    result :  seconds

 

-------------------- : ------------------------- : --------

 

999^9999999999999    :                overflow! : 0.000097

 

2^9999              :                overflow! : 0.000025

 

99^99                :        3.6972963765E+197 : 0.000020

 

9^9                  :                387420489 : 0.000019

 

 

[/pre]

Link to comment
Share on other sites

You cannot use pow function to calculated pow(999,9999999999999); because it does not actually calculate but instead gives you the word "INF", because pow() cannot handle big number.

 

try

<?php
echo pow(999,9999999999999); //gives INF
?>

 

should use bcpow instead, try at your own risk. ;) you will either have execution timeout or slow down your computer

<?php
echo bcpow(999,9999999);
?>

 

That mean, php code itself has the logic that actually determines the number that is too big to be processed, as I just discovered about

pow() will give INF, if the number is too big.

Link to comment
Share on other sites

I was aware of the INF, which is why I was testing against 1.79e308 which is about as big as a float type will store.

 

I changed to bcpow().

 

The one that didn't work (999^9999999999999) took only 0.000089 secs to give a result of 1

 

<?php
function safePow($x, $y)
{
    $r = bcpow($x,$y);
    return $r  ? $r : 'overflow!';
}

$inputs = array (
           '999^9999999999999',
           '9^9999',
           '99^99',
           '9^9'
        );

echo '<table border="1">';

echo  '<tr><td>expression</td><td>result</td><td>seconds</td></tr>'; 

foreach ($inputs as $expr)
{
    list ($x, $y) = explode('^', $expr);

    $t1 = microtime(1);
    $p = safePow ($x, $y);
    $t2 = microtime(1);
    $t = sprintf ("%0.6f", $t2-$t1);
    $p = wordwrap ($p, 50, '<br/>', true); 
    echo  "<tr valign='top'><td>$expr</td><td>$p</td><td>$t</td></tr>"; 

}

echo '</table>';

 

results -->

expression        |  result                                               | seconds
------------------+-------------------------------------------------------+---------
999^9999999999999 |  1                                                    | 0.000089
------------------+-------------------------------------------------------+---------
9^9999            | 29570038080193553244202241247182381904736703321559    | 0.080060
                  | 61671705236976632770045817648617101476387353131190    |
                    07794052755117226772246089286497411108107780037148
                    36325316042186166990796173111553392470503228770292
                    61635989747700682249026677170831101015638735481375
                    95348355198673095302780092160210144684226186834160
                    85201240881900696792962780195582937398604502704630
                    94178175710226111789638385298302727708698135607646
                    65235046072981883231569495823001414324280338228407
                    28160709641694694631974768106968066157416761673042
                    02328890013016792519047059316388947963396365040198
                    96529711440442278951154589236175839216922714879594
                    78105314259597356800173880535562903333968558439558
                    31297121192085529060174977473248308137087153677930
                    71364132861688345782900934182722384808424867747555
                    41216912068813554389615477881034622307250708201099
                    94431060541511605790633487375591189689906388924528
                    93300179055780332398687922375940465628910002345704
                    80466714010999453530847119757231540057030904501661
                    98577327065684255831398416277202011129243988044895
                    73400327530247339138349749900220177647606366946573
                    53730216426495327531084479505061474803804732314821
                    60428310852126756801840282958821614403826580523054
                    77466231671299300660555985531575924896657182021175
                    66661312585309037516052129309448917931270523260917
                    50397294686425312669136438517283705639333635161448
                    63290378253471075494974011148522354778328803663379
                    96240797554262456425498262419217851488935965187810
                    76168138576119458515712650610822442439090441062500
                    44113272115363110880072240671612230416702006619414
                    92645863388106811833930148937860388331508538314380
                    42873005007677566690968712353120167119136011921758
                    75017072784648797925283213179757572118877572888646
                    91395808200589001779854265847570611022274694232573
                    90096799491231413307181862194535751257149330940150
                    66400756969653201492693518526616493922350507786584
                    97673682783702780921253995141030624954339652548192
                    95393213833318985817405494470930042775903862323835
                    29490520380924489826502595909379268407809068495430
                    78295742149516334088901540757903467420116929759740
                    76534000673955772995699451999491338363638017711082
                    30954938187823919329366696142989020412803487266149
                    84850834485233646361804743009899859708625059629383
                    11674479728774599420881723382498918334543508882434
                    64187988269904342984965717714939722354428821288213
                    09527093860441661061595020273963143689053752482859
                    63936980732859377097888547029703382539875128459031
                    46538460377310130411666242532795708504730185811213
                    97059634128992476605199470753609284601349842100514
                    65187947556589536972458224443928196052506806800421
                    27864285303583940764887965608565264532864657900382
                    63980955744560865625661093634746457202552213684457
                    67218182971678242672700204741939223930082354521253
                    00222023701601954453307836514318910917610929735203
                    38839147013827757400238179104442275472661714530715
                    28314286523805302309338757786902507391827366919491
                    12323419677170157645740351158296240212392164022320
                    27147112072565950900550711954318831286711688187370
                    88668110998845593704678268546868364808547287745826
                    21929749433414187800946557466808865967459480128655
                    99992266034667429228735904479455139666557247545538
                    68723083531377146248270232328955912981277312653415
                    10500237430610563506505871436746090865505024769877
                    20690212456531379547297168100561437791860423543993
                    34819778335068866891940081581283566316826139345505
                    75772544811446899008048645133069410065779496114655
                    72940022955061091010981022280645044953998958131993
                    83140362526877321767588200080453523347221876232060
                    20977723735893520294435972552608047662861343949125
                    40998684180555769384208029934015945625879466674973
                    54580034100878934068922362224033987662029301109686
                    37013649286539563686221682799513491103221055267875
                    31670781652750939856398657730408147642156017685352
                    83091418223000778368198758730099085802982576706272
                    02566731856575447925528647565011072736397339253202
                    63530866879991279199727260917164090022389800696661
                    55440666237417330569446556830163261542217640716688
                    15802337723435233341864067753376358066733427906396
                    51806227129252424045577693626753414349694553699940
                    16324900652514820452041020190485994283561308228193
                    83215320896395201817996745130192490082374495742796
                    75032848026951246175575505494642028127562838850097
                    17518969113802602883749049237207848319884198177306
                    75355820044018456957224474538897254521899086006023
                    69908861169419639699252646556010477630410083621544
                    21800362587926918683479296388992290147447918992936
                    71954775292837970632891744369329225665456633647113
                    14940699390542611625491987237864525818027204029745
                    14276170009361596609951352538076687203591054857037
                    37764641160561004153147564890759752968370573145670
                    45244255224443934646752230285478698788583762905771
                    91311423776291450033842693858724965158971637408818
                    74511247861926996949148681631052746012920651998607
                    87757572337838800795758305342602393333453008108349
                    88061753580653973478481713273658376586045220698539
                    87296629979634483265168466126486656674100642477664
                    58362670505426949493400466925584610160801681424204
                    45518526975564707890297819149422961818016010278625
                    61156932177648731060005098555165982301669224850619
                    31568418920421355730198372688770124704040649788955
                    31438401781892885451830820475344582943588328787990
                    89702256206840837057621691373677297639204219764367
                    10390032384197426163185263705519853731224531526467
                    40199270943186176118773393258200652580755961531465
                    70111902415474720111355329099573858820008123215899
                    93409902299047644525884965566791214257881192183555
                    96560699411570242343224891700923733551004601621963
                    50647151185551009590044288630423722631130969833699
                    32095934486594530062522579603482790558852761178379
                    47706284338089146722288401310474129753706851522975
                    93223797168166886418233019849079025095866318576877
                    80589880079652470916876025997575067773343562654605
                    31519379224476760834134234614337155880766653056224
                    59042596271560541842680817113614874580945233962129
                    70850052054571809822955705308460844030980144613065
                    39038751616349875577937971988307916080587220999885
                    67176868301435233796114274654236143073061748492156
                    57378385500916228222233592211545032152971682739774
                    81932928515966598599881575645026192241899644769484
                    81057830334181859083884726990653893257863093033145
                    80466486624134047653822459616014565218780841269642
                    04969082985387993542747443683912121693609129050354
                    63503887221310426401072643059310377211093931497697
                    57313249399911667699014063033275135817872967642187
                    42991943899056501942281109105499183267310842559448
                    40757732465283833087086198490814260532804832246413
                    88400430414079610039997955092964197683584100478829
                    21701088855764446976283613408020402969743563282672
                    89263385534344933206093435043737406363387886774869
                    21840423163922011229387040507612715036528952537556
                    24071018124031544019780278375688474721324500890758
                    42359161812680573314811223726276185013514182917810
                    82016785907223723490432667679470198967192763318889
                    59442231412043052919197727234912153410925696239271
                    32343452090040857932178859516543294751009900505275
                    30887039823706933636042779991779742739205913916892
                    47905034203532233141572086180763614669296885421935
                    68683803813200508192423140834455476453713361942210
                    67383731457128363664501360900423116580376502116706
                    68634091277267329794431602831293750164739290568599
                    39588295163470442481839947092842780139819284350124
                    66404034216317441390796316558933151256466299953910
                    69898305785477084007456923291302412793544098044804
                    80482252229316720937807095113464188594976010910805
                    77947853968788958839298868031998145923655620055867
                    67697088148727353357253406583388718594467716018460
                    03008416768360925124349953243535737817566871351785
                    22370512103461402180355083036748951420840322767530
                    85370707124107923222070048543185429022365548997680
                    12384617201603334228446019920389903628378200620348
                    05625031849942629136028963224763264918594291058132
                    33575483058172466272591950184048879884196880599905
                    83398372192674712625256466264811150057048674429726
                    68051862965551403768012558261258797141909374946256
                    08082074450698191402160459983481261291146898169015
                    93744670125532544675101521226081281185262051430026
                    28567763911205058981484089445063925312227297156574
                    81951581522670526449606018798445937294460915663357
                    46323504396391888420611213053955019492234570426022
                    89040822345435531431410292004367782317582244666934
                    73423046999208799648215179733581316614051835295877
                    86552123805417707087326237259945875570517388086903
                    93647783463838973619031375364955834992555598419585
                    93680865189109754700833125514749997252298276449644
                    08532107884666557244757362336353067996857134986514
                    95985416152932810517582073377481192674721483835033
                    51817947851292651019626542119198731125390244483065
                    42130152497845627886758210063819409277278037971390
                    22846222722392173144911498124622263762556297135799
                    12991476187783467147893547560740494329605275322184
                    72847758596800711647195207815846432905338351479722
                    76625783445031054465600606029383933811394144549916
                    75399051033257520096512262404228163918778716613969
                    71050272517627382736126624668252876766658122078227
                    91553099424225902561578601700094217249553393903866
                    52393523143979523187416086683508300247975052291717
                    42439849381576402557448811144234328562782819535722
                    44699693718421884209408629980999899657811805537222
                    47371772149023528051050125766868603163822501525756
                    01425820418297597111429171696692836924331763474919
                    75784425336398994743098294658517001590759607096696
                    80989681019942501232514157563343960774110382841718
                    45379848297363851751878210438439229169184979216267
                    33246346349488728012465502515835727748075661320440
                    94225581352181360560295400258287887763614409248206
                    10516131547281258707684177763777809520979886388927
                    56560559992172866846718663746826331406030145201705
                    24514241384392975281951062730998080957582038094340
                    05465349443547202137623711977961945635153179851222
                  | 39306227452805339194206261922327328881385264946493    |
                  | 107731598333726490360478756392805900488889            |
------------------+-------------------------------------------------------+---------
99^99             | 36972963764972677265718790562880544059566876428174    | 0.000168
                  | 11024302599724235525704552775234214106500101282327    |
                  | 27940978889548326540119429996769494359451621570193    |
                  | 644014418071060667659301384999779999159200499899      |                                                
------------------+-------------------------------------------------------+---------
9^9               | 387420489                                             | 0.000024

 

 

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.