PHP: "инновационный" калькулятор или считаем всё сразу :)
Зачем делать лишние клики? Вво-о-одим число, выбира-а-аем операцию, второ-ое число, да ещё и "равно" или Enter. Километровый пробег мыши или пальцев :) Почему не сделать так: ввести число, нажать клавишу TAB, ввести второе число, нажать Enter, и всё сразу посчитано - арифметические действия, степень и корень, тригонометрические функции, экспонента и логарифмы, ну, можно ещё полярные кооррдинаты, проценты, а для целых значений - количество сочетаний и перестановок.
На самом деле, конечно, шучу. Это очередной учебный, а если мне повезёт, то и завершающий серию скрипт на PHP. Писался, в основном, для иллюстрации проверки ошибок при вычислениях конструкциями вида
if (is_nan($r) or is_infinite($r)) return ERROR;
- "если получено не число или бесконечность". Ну и ещё полезные мелочи можно в исходнике найти.
Вызывается также "напрямую" методом GET, например, вот так. Думаю, параметры хорошо видны из адресной строки:
x=число
иy=число
- первый и второй операнды формул. Для отделения дробной части от целой можно использовать и запятую вместо точки, скрипт это исправит;signs=число
- целое количество знаков в дробной части, допустимы значения от -1 до константыPRESITION-1
включительно, -1 означает "не округлять", 0 - округлять до целых, 1 - оставлять 1 знак в дробной части и т.д.;action=1
- чтобы всё сразу вычислилось, иначе просто заполнятся поля ввода.
Исходник на момент написания приводится ниже. В нём жертвуется сестра таланта во имя тупочитабельности.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta content="text/html; charset=Windows-1251" http-equiv="content-type"> <title>Калькулятор с 2 операндами</title> </head> <body> <?php error_reporting(E_ERROR); define ('PRESITION','9'); //предельное число знаков в дробной части + 1 define ('ERROR','Ошибка!'); //сообщение об ошибке function trimall($string) { $string = str_replace(",",".",trim($string)); return preg_replace("/(^\s*)|(\s*$)/","",preg_replace("/\s+/"," ",$string)); } function magic ($path) { @ini_set('magic_quotes_runtime', '0'); @ini_set('magic_quotes_sybase', '0'); return (@get_magic_quotes_gpc()=='1' ? stripslashes($path) : $path); } function get_word_form ($n,$word,$o1,$o2,$o5) { //Получить нормальное окончание для слова $word и числа объектов $n. //Параметры: //$o1 - окончание для числа *1, //$o2 - окончание для *2-*4, //$o5 - окончание для чисел *5-*9,*0,*11-*19 if ($n%100>10 and $n%100<20 or $n%10==0 or $n%10>4) $word.=$o5; else if ($n%10>1 and $n%10<5) $word.=$o2; else $word.=$o1; return $word; } $params = array ('x','y','signs','action'); while (list($num,$var) = each($params)) { if (!empty($_POST[$var])) $$var = floatval(trimall(htmlspecialchars(magic($_POST[$var])))); else if (!empty($_GET[$var])) $$var = floatval(trimall(htmlspecialchars(magic($_GET[$var])))); else $$var = ($var=='signs' ? '-1' : '0'); } if (is_nan($x) or is_infinite($x)) $x=0; if (is_nan($y) or is_infinite($y)) $y=0; $signs=intval($signs); if (is_nan($signs) or is_infinite($signs)) $signs=-1; if ($signs<-1) $signs=-1; if ($signs>PRESITION-1) $signs=PRESITION-1; $result=''; if (!empty($action)) { $result = '<table align="center" border="0" cellpadding="3" cellspacing="0"> <tr> <td colspan="2" align="center" valign="middle"><b>Арифметика</b></td> <tr> <tr> <td>'.r_($x,$signs).'+'.($y<0?'(':'').r_($y,$signs).($y<0?')':'').' = '.plus($x,$y,$signs).'</td> <td>'.r_($x,$signs).'-'.($y<0?'(':'').r_($y,$signs).($y<0?')':'').' = '.minus($x,$y,$signs).'</td> </tr> <tr> <td>'.r_($x,$signs).'*'.r_($y,$signs).' = '.multiply($x,$y,$signs).'</td> <td>'.r_($x,$signs).'/'.r_($y,$signs).' = '.divide($x,$y,$signs).'</td> </tr> <tr> <td colspan="2" align="center" valign="middle"><b>Деление нацело и остаток от деления</b></td> <tr> <tr> <td>'.i_($x).' div '.i_($y).' = '.div($x,$y).'</td> <td>'.i_($x).' mod '.i_($y).' = '.mod($x,$y).'</td> </tr> <tr> <td colspan="2" align="center" valign="middle"><b>Степень и квадратный корень</b></td> <tr> <tr> <td>'.$x.'<sup>'.$y.'</sup> = '.power($x,$y,$signs).'</td> <td>√<span style="text-decoration: overline;">'.$x.'</span> = '.sqrt_($x,$signs).'</td> </tr> <tr> <td colspan="2" align="center" valign="middle"><b>Тригонометрия</b></td> <tr> <tr> <td>sin('.$x.' рад) = '.sin_($x,'rad',$signs).'</td> <td>sin('.$x.'°) = '.sin_($x,'deg',$signs).'</td> </tr> <tr> <td>cos('.$x.' рад) = '.cos_($x,'rad',$signs).'</td> <td>cos('.$x.'°) = '.cos_($x,'deg',$signs).'</td> </tr> <tr> <td>tan('.$x.' рад) = '.tan_($x,'rad',$signs).'</td> <td>tan('.$x.'°) = '.tan_($x,'deg',$signs).'</td> </tr> <tr> <td colspan="2" align="center" valign="middle"><b>Полярные координаты</b></td> <tr> <tr> <td>ρ('.$x.','.$y.') = '.rho($x,$y,$signs).'</td> <td>φ('.$x.','.$y.') = '.phi($x,$y,$signs).'</td> </tr> <tr> <td colspan="2" align="center" valign="middle"><b>Экспонента и логарифмы</b></td> <tr> <tr> <td>exp('.$x.') = '.exp_($x,$signs).'</td> <td>ln('.$x.') = '.ln_($x,$signs).'</td> </tr> <tr> <td>log<sub>10</sub>'.$x.' = '.log10_($x,$signs).'</td> <td>log<sub>'.$y.'</sub>'.$x.' = '.log_($x,$y,$signs).'</td> </tr> <tr> <td colspan="2" align="center" valign="middle"><b>Сочетания и перестановки</b></td> <tr> <tr> <td>'.i_($x).'! = '.fact($x).'</td> <td>'.i_($y).'! = '.fact($y).'</td> </tr> <tr> <td colspan="2">Сочетаний из '.i_($x).' по '.i_($y).' (порядок объектов неважен) = '.soch($x,$y).'</td> </tr> <tr> <td colspan="2">Перестановок из '.i_($x).' по '.i_($y).' (порядок объектов важен) = '.perest($x,$y).'</td> </tr> <tr> <td colspan="2" align="center" valign="middle"><b>Проценты</b></td> <tr> <tr> <td>'.$y.'% от '.$x.' = '.ps1($x,$y,$signs).'</td> <td>Значение '.$x.' в % от '.$y.' = '.ps2($x,$y,$signs).'%</td> </tr> </table>'."\n"; } echo ' <script type="text/javascript"> function clearme() { document.f1.x.value = ""; document.f1.y.value = ""; document.getElementById("result").innerHTML = ""; document.f1.signs.selectedIndex = 0; } </script> <noscript> <div align="center"><small>Кнопка Очистить и автовыделение полей не будут работать из-за выключенного в вашем браузере Javascript!</small></div> </noscript> <form name="f1" method="post" action="'.$_SERVER['PHP_SELF'].'"> <table align="center" border="0" cellpadding="3" cellspacing="0"> <tr> <td align="right">X=</td> <td> <input type="text" name="x" maxlength="'.(PRESITION+2).'" size="'. (PRESITION+4).'" value="'.$x.'" onclick="this.select();"> </td> <td align="right">Y=</td> <td> <input type="text" name="y" maxlength="'.(PRESITION+2).'" size="'. (PRESITION+4).'" value="'.$y.'" onclick="this.select();"> </td> <tr> <td colspan="2">'; echo '<select name="signs" size="1">'."\n"; echo '<option value="-1"'.($signs==-1?' selected':'').'>Не округлять'."\n"; for ($i=0; $i<PRESITION; $i++) echo '<option value="'.$i.'"'.($signs==$i?' selected':'').'>'.$i.' '.get_word_form ($i,'знак','','а','ов')."\n"; echo '</select>'."\n"; echo ' </td> <td colspan="2"> <input type="hidden" name="action" value="1"> <input type="submit" value="Вычислить"> <input type="button" value="Очистить" onclick="clearme();"> </td> </tr> </table> </form>'."\n".' <script type="text/javascript"> function start() { document.f1.x.select(); } start(); </script> <table align="center" border="0" cellpadding="4" cellspacing="0"> <tr> <td><div id="result">'.$result.'</div></td> </td> </tr> </table>'."\n"; function r_($x,$signs) { return $signs==-1 ? $x : round($x,$signs); } function i_($x) { $r=intval($x); if (is_nan($r) or is_infinite($r)) return 0; else return $r; } function plus ($x,$y,$signs) { $r = $x+$y; if (is_nan($r) or is_infinite($r)) return ERROR; return $signs==-1 ? $r : round($r,$signs); } function minus ($x,$y,$signs) { $r = $x-$y; if (is_nan($r) or is_infinite($r)) return ERROR; return $signs==-1 ? $r : round($r,$signs); } function multiply ($x,$y,$signs) { $r = $x*$y; if (is_nan($r) or is_infinite($r)) return ERROR; return $signs==-1 ? $r : round($r,$signs); } function divide ($x,$y,$signs) { if (!$y) return ERROR; $r = $x/$y; if (is_nan($r) or is_infinite($r)) return ERROR; return $signs==-1 ? $r : round($r,$signs); } function div ($x,$y) { if (!$y) return ERROR; return intval($y) ? floor(intval($x)/intval($y)) : ERROR; } function mod ($x,$y) { if (!$y) return ERROR; return intval($y) ? intval($x)%intval($y) : ERROR; } function power ($x,$y,$signs) { $r = pow($x,$y); if (is_nan($r) or is_infinite($r)) return ERROR; return $signs==-1 ? $r : round($r,$signs); } function sqrt_ ($x,$signs) { $r = sqrt($x); if (is_nan($r) or is_infinite($r)) return ERROR; return $signs==-1 ? $r : round($r,$signs); } function sin_ ($x,$measure,$signs) { $r = $measure=='rad' ? sin($x) : sin(deg2rad($x)); if (is_nan($r) or is_infinite($r)) return ERROR; return $signs==-1 ? $r : round($r,$signs); } function cos_ ($x,$measure,$signs) { $r = $measure=='rad' ? cos($x) : cos(deg2rad($x)); if (is_nan($r) or is_infinite($r)) return ERROR; return $signs==-1 ? $r : round($r,$signs); } function tan_ ($x,$measure,$signs) { $p = -1*(PRESITION-1); if ($measure=='rad' and abs(cos($x))<pow(10,$p)) return ERROR; if ($measure=='deg' and abs(cos(deg2rad($x)))<pow(10,$p)) return ERROR; $r = $measure=='rad' ? tan($x) : tan(deg2rad($x)); if (is_nan($r) or is_infinite($r)) return ERROR; return $signs==-1 ? $r : round($r,$signs); } function rho ($x,$y,$signs) { $r = sqrt(pow($x,2)+pow($y,2)); if (is_nan($r) or is_infinite($r)) return ERROR; return $signs==-1 ? $r : round($r,$signs); } function phi ($x,$y,$signs) { $r = atan2($y,$x); if (is_nan($r) or is_infinite($r)) return ERROR; if ($signs==-1) return $r.' ('.rad2deg($r).'°)'; else return round($r,$signs).' ('.round(rad2deg($r),$signs).'°)'; } function exp_ ($x,$signs) { $r = exp($x); if (is_nan($r) or is_infinite($r)) return ERROR; return $signs==-1 ? $r : round($r,$signs); } function ln_ ($x,$signs) { $r = log($x); if (is_nan($r) or is_infinite($r)) return ERROR; return $signs==-1 ? $r : round($r,$signs); } function log10_ ($x,$signs) { $r = log10($x); if (is_nan($r) or is_infinite($r)) return ERROR; return $signs==-1 ? $r : round($r,$signs); } function log_ ($number,$base,$signs) { $r = log($number) / log($base); if (is_nan($r) or is_infinite($r)) return ERROR; return $signs==-1 ? $r : round($r,$signs); } function fact($n) { $n = intval($n); if ($n<0 or is_nan($n) or is_infinite($n)) return ERROR; $r = 1; for ($index = 1; $index <= $n; $index++) { $r *= $index; if (is_nan($r) or is_infinite($r)) return ERROR; } return $r; } function soch ($x,$y) { if ($x<0 or $y<0 or $x<$y or is_nan(intval($x)) or is_nan(intval($y))) return ERROR; $f1 = fact($x); $f2 = fact($y); $f3 = fact(i_($x)-i_($y)); if ($f1==ERROR or $f2==ERROR or $f3==ERROR) return ERROR; $r = $f1 / ($f2*$f3); if (is_nan($r) or is_infinite($r)) return ERROR; return $r; } function perest ($x,$y) { if ($x<0 or $y<0 or $x<$y or is_nan(intval($x)) or is_nan(intval($y))) return ERROR; $f1 = fact($x); $f3 = fact(i_($x)-i_($y)); if ($f1==ERROR or $f3==ERROR) return ERROR; $r = $f1 / $f3; if (is_nan($r) or is_infinite($r)) return ERROR; return $r; } function ps1 ($x,$y,$signs) { $r = $y*$x/100; if (is_nan($r) or is_infinite($r)) return ERROR; return $signs==-1 ? $r : round($r,$signs); } function ps2 ($x,$y,$signs) { $r = $x/$y*100; if (is_nan($r) or is_infinite($r)) return ERROR; return $signs==-1 ? $r : round($r,$signs); } ?> </body></html>
02.03.2016, 18:45 [7359 просмотров]