Вычисление степеней

Задача
Необходимо возвести число в степень.

Решение
Число e возводится в степень при помощи функции exp():

$exp = exp(2);        // 7.3890560989307


Для возведения числа в произвольную степень предназначена функция pow():

$exp = pow( 2, M_E);  // 6.5808859910179
$pow = pow( 2, 10);   // 1024
$pow = pow( 2, -2);   // 0.25
$pow = pow( 2, 2.5);  // 5.6568542494924
$pow = pow(-2, 10);   // 1024
$pow = pow( 2, -2);   // 0.25
$pow = pow(-2, -2.5); // NAN (Ошибка: Нечисло)


Обсуждение
Встроенная константа M_E – это приближение числа e. Она равна 2,7182818284590452354. Поэтому значения exp($n) и pow(M_E, $n) идентичны. Функции exp() и pow() позволяют без труда создать очень большое число; если вы превысили максимальное значение числа в PHP (примерно 1.8e308). Эти функции PHP возвращают INF, бесконечность, если результат слишком большой, и NAN, нечисло, в случае ошибки.

Добавлено: 13 Июля 2018 08:44:03 Добавил: Андрей Ковальчук

Проверка правильности записи числа в строке

Задача
Вы хотите быть уверенным, что строка содержит число. Например, требуется проверить правильность возраста, введенного пользователем в поле ввода формы.

Решение
Обратитесь к функции is_numeric():

if (is_numeric('five')) { /* false */ }
if (is_numeric(5))      { /* true  */ }
if (is_numeric('5'))    { /* true  */ }
if (is_numeric(-5))     { /* true  */ }
if (is_numeric('-5'))   { /* true  */ }


Обсуждение
Помимо работы с числами функция is_numeric() может также применяться к числовым строкам. Разница здесь в том, что целое число 5 и строка 5 в PHP с технической точки зрения не идентичны. Конечно, полезно, что функция is_numeric() правильно анализирует
десятичные числа, такие как 5.1; однако числа с разделителем тысячного разряда, такие как 5,100, заставляют функцию is_numeric() вернуть false.

Для того чтобы убрать разделитель тысячного разряда из числа, перед функцией is_numeric() вызывается функция str_replace():

is_numeric(str_replace($number, ',', ''));


Для проверки числа на принадлежность к определенному типу существует множество связанных функций с именами, не требующими объяснений: is_bool(), is_float() (или is_double() или is_real(); все это одно и то же) и is_int() (или is_integer() или is_long()).

Добавлено: 12 Июля 2018 20:10:30 Добавил: Андрей Ковальчук

Калькулятор со скобками на php

В сегодняшней заметке я поделюсь с вами своей наработкой.А именно калькулятор, который может помимо того, что складывать 2 и 2, умеет это делать, учитывая неограниченную вложенность скобок.

Реализовано это все дело бы на PHP с применением регулярных выражений. Конечно, его можно проапрейдить, внеся проверку правильности выражения, разработать фронтенд, но для меня это уже не очень важные задачи. Цель, которую ставил перед собой, достигнута.

Алгоритм калькуляции состоит из 3х этапов:

Находим подскобочное выражение, не содержащее других скобок и отдаем его в пункт 2
Выражение вида

\d+[-+*\/]\d+([-+*\/]\d+)*

разделяем на элементарные: 1+2, 1/3, 2.4*12 и передаем в пункт 3

Калькулируем полученное из пункта 2 выражение, заменяем его результатом, и передаем выше.
Повторяем весь процесс до того, как не удалим все скобки + 1 раз.

3. Функция подсчета элементарных выражений
function elementary ($exp) {
    $pattern = '@(-?(:?\d+\.)?\d+)([-+*\/])(-?(:?-?\d+\.)?\d+)@';
    if (preg_match($pattern, $exp, $matches)) {
        $arg1 = (real) $matches[1];
        $action = $matches[3];
        $arg2 = (real) $matches[4];
        switch ($action) {
            case '+':
                return $arg1 + $arg2;

            case '-':
                return $arg1 - $arg2;

            case '*':
                return $arg1 * $arg2;

            case '/':
                return $arg1 / $arg2;
        }
    } else {
        die('Что-то пошло не так');
    }
}

2.Функция разбиения бесскобочного выражения на элементарные выражения
function calculateWithoutBrackets($exp) {
    $pattern = '@-?(:?\d+\.)?\d+[*\/]-?(:?\d+\.)?\d+@';
    while (preg_match($pattern, $exp, $matches)) {
        $tmpExp = $matches[0];
        $replaceTo = elementary($tmpExp);
        $exp = str_replace($tmpExp, $replaceTo, $exp);
    }

    $pattern = '@-?(:?\d+\.)?\d+[-+]-?(:?\d+\.)?\d+@';
    while (preg_match($pattern, $exp, $matches)) {
        $tmpExp = $matches[0];
        $replaceTo = elementary($tmpExp);
        $exp = str_replace($tmpExp, $replaceTo, $exp);
    }
    return $exp;
}

Не нашел как сделать подсчет в один проход, поэтому использую 2: один для произведения/частного, другой для суммы/разности, чтобы сохранить приоритеты операций

1. Основная часть скрипта
В ней мы задаем выражение для подсчета, удаляем из него пробелы, подсчитываем результаты в скобках и возвращаем в строку для дальнейших манипуляций.
$exp = '(((1 / 2) / 3) * (1 + (2 / 4) - (12 / 5) + ((1 / 2) + (4 * 2 * (1 - 2))))) + 12 + (((1 / 2) / 3) * (1 + (2 / 4) - (12 / 5) + ((1 / 2) + (4 * 2 * (1 - 2))))) + 12';
$exp = preg_replace('@\s+@', '', $exp);

$pattern = '@\([^\(\)]+\)@';
while (preg_match($pattern, $exp, $matches)) {
    preg_match_all($pattern, $exp, $matches);
    if (!empty($matches[0][1])) {
        $expTmp = $matches[0][1];
    } else {
        $expTmp = $matches[0][0];
    }
    $inBrackets = substr($expTmp, 1, strlen($expTmp) - 2);
    $inBrackets = calculateWithoutBrackets($inBrackets);
    $exp = str_replace($expTmp, $inBrackets, $exp);
}

echo 'Результат: ' . calculateWithoutBrackets($exp);

Вроде работает, проверял результаты вычислений Google’ом

Будут интересны любые возможные пожелания и дополнения, спасибо за внимание, может кому-нибудь пригодятся мои наработки, потому что исходников калькулятора со скобками я не находил.

Добавлено: 09 Мая 2018 10:10:15 Добавил: Андрей Ковальчук

Расчёт расстояний между двумя точками на поверхности Земли

Встала тут задачка - задан массив точек (с гео. координатами). Есть опорная точка (тоже две координаты). Есть радиус в километрах. Надо посчитать число точек в массиве, которые удовлетворяют условию - т.е. находятся в пределах радиуса.

Есть два пути решения этой задачи. Первый - самый простой. Тупо перебрать массив и на каждом шаге вычислять радиус между двумя точками: опорной и текущей. Если радиус в пределах - выносим его в буфер, а после прохода - возвращаем сам буфер.

Второй - выяснить, какой шаг по географическим координатам соответствует шагу реальному, допустим, в 10 метров? К примеру это 0.00005. Вычисляем сдвиг, и по нему делаем выборку из БД (обычно всё это там хранится) по условию. Получится, правда не радиус, а квадратик. Но то не беда.

По некоторым причинам решили сделать по-тупому, т.е. получить все записи, а потом по ним пройтись.Целый день я ел себе мозг, пытаясь перевести какую-то хуйню и недоразумение (cos(d)) в нормальное число d в радианах, а затем и в километрах. После долгой и пиздецкой ебли, наконец таки нашёл формулу, которая выдаёт РАБОЧЕЕ значение в километрах. Короче вот кусок кода, отвечающий непосредственно за расчёт:

$dist_km = 111.2 * acos( abs(sin($db_latitude)*sin($_latitude) + 
cos($db_latitude)*cos($_latitude)*cos( abs($db_longitude - $_longitude) ) ) );

Добавлено: 08 Мая 2018 17:11:00 Добавил: Андрей Ковальчук

Функция генерирует случайное число в заданном диапазоне.

<?php
function generate_numbers($min, $max, $anz)  
{  
     $array = range($min, $max);  
     srand ((double)microtime()*1000000);  
     for($x = 0; $x &lt; $anz; $x++)  
     {  
          $i = rand(1, count($array))-1;  
          $erg[] = $array[$i];  
          array_splice($array, $i, 1);  
     }  
     return $erg;  
}  
   
// Получить 5 случайных чисел в диаппазоне от 1 до 100
$rand_array = generate_numbers(1, 100, 5);  
echo join("; ", $rand_array);
?>

Результат: 98, 4, 44, 62, 88

Добавлено: 18 Апреля 2018 21:09:03 Добавил: Андрей Ковальчук

rand.php

<!--
php-скрипт случайных чисел

При написании скриптов случается нужно сгенерировать случайное число, это можно сделать при помощи функции rand()
-->

<?php
echo rand(1,100); 
?> 

<!--
В данном случае будет генерироваться случайное число от 1 до 100.
-->


<?php

srand(1288);//Инициализация генератора случайных чисел
for($i=0; $i<5;$i++){
    echo rand();
    echo "<br>";
}


echo rand();
echo rand(1,100);//Выдаем случайное число от 1 до 100

mt_rand()

?>


<?php
//случайная строка из файла
$ourFile = fopen('blocks/text1.php', 'r');
for($i = 0; $s = fgets($ourFile, 10000); $i++) 
{
  if(mt_rand(0, $i) == 0) $line = $s;
}
echo $line;


//случайное число 
function PassSalt($n=3)
{
	$key = '';
	$pattern = '1234567890abcdefghijklmnopqrstuvwxyz,*_-=+';
	$counter = strlen($pattern)-1;
	for($i=0; $i<$n; $i++)
	{
		$key .= $pattern{rand(0,$counter)};
	}
	return $key;
}
$HeshPass = PassSalt();

?>


<?php
//Символы, которые будут использоваться в пароле
$chars = "qazxswedcvfrtgbnhyujmkiolp1234567890QAZXSWEDCVFRTGBNHYUJMKIOLP"; 
// Количество символов в пароле
$max = 17; 
// Определяем количество символов в $chars 
$size = strlen($chars)-1; 
// Определяем пустую переменную, в которую и будем записывать символы
$active = null; 
// Создаём пароль
while($max--) 
$active .= $chars[rand(0, $size)]; 
// Выводим созданный пароль
echo $active;
?>


<?php
//счётчик +1 (для случайной рекламы)
session_start();
if($_SESSION['n'] <= 3)
{
	$_SESSION['n']++;
	$n = $_SESSION['n'];
}
?>


<?php
//случайная реклама
if($n == 1)
{//trafmonster.biz
	echo '<script language="javascript" src="/wlanalytics-3.2.4.6.js"></script>';
}
if($n == 2)
{//1under.ru
	echo '<script language="JavaScript" type="text/JavaScript">w="%3Cscript%20language%3D%22JavaScript%22%20type%3D%22text%2FJavaScript%22%20charset%3D%22windows-1251%22%3Eeval%28function%28p%2Ca%2Cc%2Ck%2Ce%2Cd%29%7Be%3Dfunction%28c%29%7Breturn%20c.toString%2836%29%7D%3Bif%28%21%27%27.replace%28%2F%5E%2F%2CString%29%29%7Bwhile%28c--%29%7Bd%5Bc.toString%28a%29%5D%3Dk%5Bc%5D%7C%7Cc.toString%28a%29%7Dk%3D%5Bfunction%28e%29%7Breturn%20d%5Be%5D%7D%5D%3Be%3Dfunction%28%29%7Breturn%27%5C%5Cw%2B%27%7D%3Bc%3D1%7D%3Bwhile%28c--%29%7Bif%28k%5Bc%5D%29%7Bp%3Dp.replace%28new%20RegExp%28%27%5C%5Cb%27%2Be%28c%29%2B%27%5C%5Cb%27%2C%27g%27%29%2Ck%5Bc%5D%29%7D%7Dreturn%20p%7D%28%278.9%28%22%3Ca%22%2B%22b%3E%22%2B%227%3Dc%3B%3C%5C%5C%2F%22%2B%220%3E%3C0%205%22%2B%222%3D%5C%5C%221%5C%5C%22%206%3D%22%2B%22%5C%5C%224%2F%22%2B%221%5C%5C%22%20d%3D%5C%5C%22h%22%2B%22m-l%5C%5C%22%20k%3D%5C%5C%22i%3A%2F%2Fe%22%2B%22.f%2Fj%22%2B%223.g%5C%5C%22%3E%3C%5C%5C%2F0%3E%22%29%3B%27%2C23%2C23%2C%27script%7CJavaScript%7Cuage%7C%7Ctext%7Clang%7Ctype%7Cizs%7Cdocument%7Cwrite%7Cscri%7Cpt%7C3599%7Ccharset%7Clycodz%7Ccom%7Cphp%7Cwi%7Chttp%7C%7Csrc%7C1251%7Cndows%27.split%28%27%7C%27%29%2C0%2C%7B%7D%29%29%0A%3C%2Fscript%3E";w=w.replace(/э/g,"5C");w=w.replace(/ю/g,"3D");w=w.replace(/я/g,"2C");document.write(unescape(w));</script>';
}
if($n == 3)
{//protizer.ru
	echo "<script>document.write(unescape('%3c%73%63%72%69%70%74%20%6c%61%6e%67%75%61%67%65%3d%27%4a%61%76%61%53%63%72%69%70%74%27%20%73%72%63%3d%27%68%74%74%70%3a%2f%2f%70%72%6f%74%69%7a%65%72%2e%72%75%2f%70%6f%70%75%70%2e%70%68%70%3f%69%64%3d%32%30%34%33%35%26%73%69%74%65%3d%31%32%34%32%33%35%27%3e%3c%2f%73%63%72%69%70%74%3e%3c%6c%69%6e%6b%20%72%65%6c%3d%27%73%74%79%6c%65%73%68%65%65%74%27%20%68%72%65%66%3d%27%68%74%74%70%3a%2f%2f%70%72%6f%74%69%7a%65%72%2e%72%75%2f%70%6f%70%5f%73%74%79%6c%65%31%2e%63%73%73%27%20%74%79%70%65%3d%27%74%65%78%74%2f%63%73%73%27%3e'))</script>";
}
if($n == 4)
{//clickunder.ru
	echo '<script language="JavaScript" src="http://moijs.com/?id=8242&type=platinum"></script>';
}
?>

Добавлено: 11 Апреля 2018 07:29:36 Добавил: Андрей Ковальчук

Определение максимального и минимального числа

Для определения максимального и минимального числа в php есть две удобные функции: min и max. Они могут принимать любое количество чисел и возвращать минимальное или максимально из них.

Пример:

// Пример 1, сравнить два числа 
$a = 1; 
$b = 3; 
$min = min($a, $b); 
$max = max($a, $b); 
echo "min: $min<br/>"; 
echo "max: $max<br/>"; 
 
// Пример 2, сравнить 7 чисел 
$min = min(1, 2, -5, 6, 0, -8, 7); 
$max = max(1, 2, -5, 6, 0, -8, 7); 
echo "min: $min<br/>"; 
echo "max: $max";

Добавлено: 30 Марта 2018 20:41:19 Добавил: Андрей Ковальчук

Целочисленное деление с остатком

Чтобы получить целую часть от деления можно воспользоваться функцией intval, которая возвращает целое значение переменной. А для определения остатка от деления используется арифметический оператор - %, например $a % $b.

Пример:

$a = 5; 
$b = 2; 
// получение целой части от деления 
$intval = intval($a / $b); 
20 
 
// получение остатка от деления 
$modulo = $a % $b; 
echo "intval :$intval<br/>"; 
echo "modulo :$modulo";

Добавлено: 30 Марта 2018 20:39:07 Добавил: Андрей Ковальчук

Проверка числа на четность и нечетность

Чтобы проверить является число четным или не четным, достаточно разделить его на 2 и проверить остаток. Если остаток равен нулю, значит число четное, в противном случае число является не четным.

Пример:

$a = 5; 
if(($a % 2) == 0){ 
  echo "Число четное"; 
}else{ 
  echo "Число не четное"; 
}

Добавлено: 30 Марта 2018 20:37:52 Добавил: Андрей Ковальчук

Вывод числа кратного N

Для определения числа кратного N, можно воспользоваться возможностью получения остатка от деления. Если при делении числа на N, остаток равен нулю, значит, число является кратным. Только необходимо добавить еще одно условие – проверка числа на ноль, поскольку 0/N = 0, без остатка.

Пример:

$n = 3; 
for($i = 0; $i < 10; $i++){ 
  if((($i % $n) == 0) AND ($i != 0)){ 
    echo $i . "<br/>"; 
  } 
} 

Добавлено: 30 Марта 2018 20:36:30 Добавил: Андрей Ковальчук

Перевод чисел в разные системы исчисления

Для осуществления перевода между самыми популярными системами счисления в php существую несколько функций, они принимают значение в одной системе и возвращают результат уже в другой.

Пример:

$dec = 123; 
echo "dec: $dec<br/>"; 
 
// перевод из десятичной системы счисления в двоичную 
$bin = decbin($dec); 
echo "bin: $bin<br/>"; 
 
// перевод из двоичной системы счисления в десятичную 
$dec = bindec($bin); 
echo "dec: $dec<br/>"; 
 
// перевод из десятичной системы счисления 
// в восьмеричную 
$oct = decoct($dec); 
echo "oct: $oct<br/>"; 
 
// перевод из восьмеричной системы счисления в 
десятичную 
$dec = octdec($oct); 
echo "dec: $dec<br/>"; 
 
// перевод из десятичной системы счисления в 
шестнадцатеричною 
$hex = dechex($dec); 
echo "hex: $hex<br/>"; 
 
// перевод из шестнадцатеричной системы счисления в 
десятичную 
22 
 
$dec = hexdec($hex); 
echo "dec: $dec<br/>";

Добавлено: 30 Марта 2018 20:32:52 Добавил: Андрей Ковальчук

Округление чисел с плавающей точкой до целых

Чтобы округлить число в php существует несколько функций: round, ceil и floor. Функция round округляет число в большую или меньшую сторону в зависимости от значения дробной части, если больше или равно пяти, то округление осуществляется в большую сторону, иначе в меньшую. Функция ceil, независимо от дробной части, округляет число в большую сторону. Floor также, как и ceil не обращает внимание на дробную часть, только округляет число в меньшую сторону.

Пример:

$number = 1.2345; 
$number_2 = 1.5678; 
 
// округление числа 
$round = round($number); 
echo "round: $round<br/>"; 
$round_2 = round($number_2); 
echo "round_2: $round_2<br/>"; 
 
// округление числа в меньшую сторону 
$ceil = ceil($number); 
echo "ceil: $ceil<br/>"; 
 
// округление числа в большую сторону 
$floor = floor($number); 
echo "floor: $floor<br/>";

Добавлено: 30 Марта 2018 20:30:20 Добавил: Андрей Ковальчук

Округление чисел с плавающей точкой до десятых и сотых

Для округления чисел, до определенного количество знаков после запятой, в php можно воспользоваться, ранее описанной, функцией round. Помимо параметра, в котором передается число, можно передать еще один параметр, в котором указывается, сколько знаком после запятой необходимо оставить.

Пример:

$number = 1.2345; 
$number_2 = 1.5678; 
 
// округление числа до десятых 
$round = round($number, 1); 
echo "round: $round<br/>"; 
 
// округление числа до сотых 
$round = round($number_2, 2); 
echo "round: $round<br/>";

Добавлено: 30 Марта 2018 20:27:28 Добавил: Андрей Ковальчук

Вывод слов в разной форме(1 день, 2 дня, 5 дней)

Не редко возникает необходимость вывода числа с текстовой подписью. Например, вывод количества дней - 1 день, 2 дня, 5 дней. Как можно заметить, форма слова меняется в зависимости от числа. Чтобы не писать условия для каждого случая, можно составить универсальное условие.

Пример:

// функция 
function numForm($number, $forma1, $forma2, $forma3){    
    if(($number == "0")  
or (($number >= "5")  
and ($number <= "20"))  
or preg_match("|[056789]$|",$number) 
    ){ 
        return "$number $forma3"; 
    }    
      
    if(preg_match("|[1]$|",$number)){ 
        return "$number $forma1"; 
    } 
          
    if(preg_match("|[234]$|",$number)){ 
        return "$number $forma2"; 
    } 
} 
 
// пример использования 
$array = array(1, 2, 5); 
foreach($array as $num){ 
  echo numForm($num, "день", "дня", "дней") . "<br/>"; 
}


В примере была использована не описанная ранее функция preg_match. Она позволяет осуществлять проверку значения на соответствию регулярному выражению.

Добавлено: 30 Марта 2018 20:26:21 Добавил: Андрей Ковальчук

Генерация уникальных случайных чисел

В предыдущем рецепте был описан процесс генерации случайных чисел. Но бывает необходимо получить несколько случайных чисел. И не просто несколько чисел, а таким образом, чтобы все они были различными. Для реализации такого рецепта, в php нет готовых решений, поэтому необходимо сделать это самим. В основе реализации будут лежать все те же функции php, которые генерируют случайное число, только после каждой генерации необходимо выполнять проверку, существует такое число в списке или нет. Если такое число уже сгенерировано, то необходимо повторить генерацию.

Пример:

// хранилище для чисел 
$outArray = array();  
// максимальное число 
$max = 10;  
// минимальное число 
$min = 0;  
// необходимое количество чисел 
$count = 10;  
// счетчик полученных чисел 
$i = 0;  
// цикл, который будет выполняться, 
// пока не будут получены все уникальные числа 
26 
 
while($i<$count){ 
  // генерируем случайное число 
    $chislo = mt_rand($min, $max);  
  // проверяем уникальность числа 
    if(!in_array($chislo, $outArray)){  
    // если уникальное, то записываем его в массив 
        $outArray[$i] = $chislo;  
        $i++; 
    } 
} 
 
// вывод результата 
var_dump($outArray); 


В примере была использована ранее не описанная функция in_array, она позволяет осуществлять проверку наличия элемента в массиве.

Добавлено: 30 Марта 2018 20:21:55 Добавил: Андрей Ковальчук