tag:code.tutsplus.com,2005:/categories/mathematicsEnvato Tuts+ Code - Mathematics2018-10-12T12:06:59Ztag:code.tutsplus.com,2005:PostPresenter/cms-31972Trigonometry, Random Numbers and More With Built-in PHP Math Functions<p>Basic maths is used a lot during programming. We need to frequently compare, add, multiply, subtract and divide different values when writing code. </p><p>Sometimes, the maths required in a program can be more involved. You might need to work with logarithmic, trigonometric or exponential functions. In this tutorial, I'll discuss how to use each of these functions in PHP, with examples.</p><p>This tutorial will introduce you to the built-in math functions in PHP for doing trigonometry, exponentiation, and logarithm calculations. We'll also look at rounding and generating random numbers.<br></p><h2>Trigonometric Functions in PHP</h2><p>You can calculate the value of sine, cos and tangent of different angles given in radians using <code class="inline">sin($angle)</code>, <code class="inline">cos($angle)</code>, and <code class="inline">tan($angle)</code>. They all return <code class="inline">float</code> values, and the angle measure passed to them is in radians.</p><p>This means that when you simply calculate <code class="inline">tan(45)</code>, you won't get 1 as output, because you will actually be calculating the value of tangent at 45 radians, which is about 2,578 degrees. Luckily, PHP has two very useful functions for converting radians to degrees and vice versa. These functions are <code class="inline">rad2deg()</code> and <code class="inline">deg2rad()</code>. So, if you actually want to calculate the value of the tangent of 45 degrees, you will have to write <code class="inline">tan(deg2rad(45))</code>.</p><p> It is noteworthy that there is no direct PHP function to calculate the value of <code class="inline">cosec()</code>, <code class="inline">sec()</code>, or <code class="inline">cot()</code>. However, these values are just reciprocals of <code class="inline">sin()</code>, <code class="inline">cos()</code>, and <code class="inline">tan()</code>, so you can still calculate their values indirectly.</p><p>You can also do the inverse and calculate the angle at which a trigonometric angle has a particular value. These functions are called <code class="inline">asin()</code>, <code class="inline">acos()</code>, and <code class="inline">atan()</code>. One thing you have to remember is that the values of sin and cos can never go beyond the range of -1 to 1 for any angle. This means that <code class="inline">asin()</code> and <code class="inline">acos()</code> can only accept values in the range -1 to 1 as valid arguments. A value outside this range will give you NaN.</p><p>Trigonometry has a lot of applications like determining the trajectory of a projectile or the heights and distances of different objects, so having access to these functions is definitely helpful if you are writing code that simulates these situations.</p><p>These functions are also very helpful when you want to draw different elements using radial and angular values. Let's say you want to draw a pattern of circles around a larger circle at a uniform distance. If you have read the <a href="https://code.tutsplus.com/tutorials/rendering-text-and-basic-shapes-using-gd--cms-31767" rel="external" target="_blank">PHP GD Shapes tutorial</a> on Envato Tuts+, you probably remember that drawing any shapes will require you to pass coordinates in the form of x, y coordinates, but drawing circular patterns is easier with polar coordinates.</p><p>Using these trigonometric functions in this case will help you draw the desired figures using <code class="inline">sin()</code> and <code class="inline">cos()</code> to convert polar coordinates to cartesian form. Here is an example:</p><pre class="brush: php noskimlinks noskimwords"><?php
$image = imagecreatetruecolor(800, 600);
$bg = imagecolorallocate($image, 255, 255, 255);
imagefill($image, 0, 0, $bg);
$radius = 80;
for($i = 0; $i < 12; $i++) {
$col_ellipse = imagecolorallocate($image, rand(0, 200), rand(0, 200), rand(0, 200));
imagefilledellipse($image, 175 + 125*cos(deg2rad($i*30)), 175 + 125*sin(deg2rad($i*30)), 3*$radius/4, 3*$radius/4, $col_ellipse);
imageellipse($image, 175 + 125*cos(deg2rad($i*30)), 175 + 125*sin(deg2rad($i*30)), 3.5*$radius/4, 3.5*$radius/4, $col_ellipse);
$col_ellipse = imagecolorallocate($image, rand(0, 200), rand(0, 200), rand(0, 200));
imagefilledellipse($image, 575 + 150*cos(deg2rad($i*30)), 375 + 150*sin(deg2rad($i*30)), 3*$radius/4, 3*$radius/4, $col_ellipse);
imageellipse($image, 575 + 150*cos(deg2rad($i*30)), 375 + 150*sin(deg2rad($i*30)), 3.5*$radius/4, 3.5*$radius/4, $col_ellipse);
}
$col_ellipse = imagecolorallocate($image, 255, 255, 255);
imagefilledellipse($image, 175, 175, 275, 275, $col_ellipse);
?></pre><p>The following image shows the final result of the above PHP code.</p><figure class="post_image"><img alt="Using PHP GD with Trigonometric functions" data-src="https://cms-assets.tutsplus.com/uploads/users/1251/posts/31972/image/ellipse_circles.png"></figure><h2>Exponential and Logarithmic Functions <br>
</h2><p>PHP also has some exponential and logarithmic functions. The <code class="inline">exp($value)</code> function will return the constant <strong>e</strong> raised to the power of float <code class="inline">$value</code>. Similarly, you can calculate the logarithm of a given number to any base using the <code class="inline">log($arg, $base)</code> function. If the <code class="inline">$base</code> is omitted, the logarithm will be calculated using the natural base <strong>e</strong>. If you want to calculate the logarithm of a number to base 10, you can simply use the function <code class="inline">log10($arg)</code>.</p><p>One more function that you might find useful is <code class="inline">pow($base, $exp)</code>, which returns <code class="inline">$base</code> raised to the power of <code class="inline">$exp</code>. Some of you might prefer to use the <code class="inline">**</code> operator. The expression <code class="inline">$a**$b</code> will give the same result as <code class="inline">pow($a, $b)</code>. However, you might get incorrect results in certain situations with <code class="inline">$a**$b</code>. For example, <code class="inline">-1**0.5</code> will give you <strong>-1</strong>, which is incorrect. Calculating the same expression using <code class="inline">pow(-1, 0.5)</code> will give the correct value, NaN.</p><pre class="brush: php noskimlinks noskimwords"><?php
echo log(1000, M_E); // 6.9077552789821
echo log(1000); // 6.9077552789821
echo log(1000, 10); // 3
echo log10(1000); // 3
echo pow(121, -121); // 9.6154627930786E-253
echo pow(121, 121); // 1.0399915443694E+252
echo pow(121, 1331); // INF
?></pre><h2>Other Useful Mathematical Functions</h2><h3>Rounding Numbers</h3><p>There are a lot of other important mathematical functions as well. You can round fractions or decimal numbers up to the nearest integer using the <code class="inline">ceil(float $value)</code> function. This will convert both 2.1 and 2.9 to 3. Similarly, you can round fractions or decimal numbers down to the nearest integer using the <code class="inline">floor(float $value)</code> function. It will change both 2.1 and 2.9 to 2.</p><p>These functions are good for rounding up the results of different calculations easily. Let's say you need to know how many persons a hall can accommodate based on its area. Your final answer after the division will most probably be a decimal number, but you can't divide people into fractions, so the right answer would be the floor value of the calculated value.<br></p><p>You will often want to round a number up or down to the nearest integer. For example, you might want to change 2.1 to 2 but 2.9 to 3. This can be done easily using the <code class="inline">round($value, $precision, $mode)</code> function. The <code class="inline">$precision</code> parameter determines the number of decimal places to round to. The default value of 0 will simply return integers. The third <code class="inline">$mode</code> parameter is used to determine what happens if the number you want to round lies exactly in the middle. You can use it to specify if 3.5 should be changed to 3 or 4.</p><h3>Minimum and Maximum</h3><p>PHP also has two functions called <code class="inline">min($values)</code> and <code class="inline">max($values)</code> to help you determine the lowest and highest values in a set or array of numbers. These functions can accept different kinds of parameters like two arrays and a string. You should take a look at the <a href="https://php.net/manual/en/function.min.php" rel="external" target="_blank">documentation</a> to see how they would be compared.</p><pre class="brush: php noskimlinks noskimwords"><?php
$hall_width = 120;
$hall_length = 180;
$per_person_area = 35;
$hall_capacity = floor($hall_length*$hall_length/$per_person_area);
// Output: The hall can only accommodate 925 people.
echo 'The hall can only accommodate '.$hall_capacity.' people.';
$water_tank_volume = 548733;
$bucket_volume = 305;
$buckets_needed = ceil($water_tank_volume/$bucket_volume);
// Output: We will need 1800 buckets of water to completely fill the tank.
echo 'We will need '.$buckets_needed.' buckets of water to completely fill the tank.';
$marks = [49, 58, 93, 12, 30];
// Output: Minimum and maximum obtained marks in the exam are 12 and 93 respectively.
echo 'Minimum and maximum obtained marks in the exam are '.min($marks).' and '.max($marks).' respectively.';
?></pre><h3>Integer Division</h3><p>You can also perform integer division in PHP using the <code class="inline">intdiv($dividend, $divisor)</code> function. In this case, only the integral part of the quotient is returned after a division. Similarly, you can also get the remainder or modulo after the division of two arguments using the <code class="inline">fmod($dividend, $divisor)</code> function. The returned value will always be less than the <code class="inline">$divisor</code> in magnitude.</p><p>There are some other useful functions like <code class="inline">is_nan($value)</code>, <code class="inline">is_finite($value)</code> and <code class="inline">is_infinite($val)</code> which can be used to determine if the value is a number and, if it is a number, whether it is finite or infinite. Remember that PHP considers any value that is too big to fit in a float to be infinite. So <code class="inline">is_finite()</code> will return <code class="inline">true</code> for 100 factorial but <code class="inline">false</code> for 1000 factorial.</p><h2>Generating Random Numbers in PHP</h2><p>Random numbers prove to be quite useful in a number of situations. You can use them to generate "random" data for your application or to spawn enemy instances in games, etc. It is very important to remember that none of the functions we discuss in this section generate cryptographically secure random numbers. These functions are only meant to be used in situations where security is not an issue, like showing random greeting texts to repeat visitors or for generating random statistical data.</p><p>The functions <code class="inline">rand($min, $max)</code> and <code class="inline">mt_rand($min, $max)</code> can generate positive random integers between given values including the <code class="inline">$min</code> and <code class="inline">$max</code> value. When the functions are called without any parameters, they generate random numbers between 0 and <code class="inline">getrandmax()</code>. You can <code class="inline">echo</code> the value of <code class="inline">getrandmax()</code> to see the maximum possible random number that these functions can generate on your platform.</p><p>The function <code class="inline">mt_rand()</code> is 4 times faster than <code class="inline">rand()</code> and returns false if <code class="inline">$max</code> is less than <code class="inline">$min</code>. Starting from PHP 7.1.0, <code class="inline">rand()</code> has actually been made an alias of <code class="inline">mt_rand()</code>. The only difference is that <code class="inline">rand()</code> still doesn't give an error if <code class="inline">$max</code> is less than <code class="inline">$min</code> to maintain backward compatibility.</p><p>Here is a loop to generate random values between 0 and 100 a million times. As you can see, the values 0, 50 and 100 are generated approximately 10,000 times with slight fluctuations.</p><pre class="brush: php noskimlinks noskimwords"><?php
$rand_values = [];
$sum = 0;
$count = 1000000;
for($i = 0; $i < $count; $i++) {
$rand_values[$i] = mt_rand(0, 100);
$sum += $rand_values[$i];
}
$count_frequency = array_count_values($rand_values);
// Output: 100 was randomly generated 9969 times.
echo '100 was randomly generated '.$count_frequency[100].' times.';
// Output: 50 was randomly generated: 9994 times.
echo '50 was randomly generated: '.$count_frequency[50].' times.';
// Output: 0 was randomly generated: 10010 times.
echo '0 was randomly generated: '.$count_frequency[0].' times.';
// Output: Average of random values: 49.97295
echo 'Average of random values: '.($sum/$count);
?></pre><p>Both these functions also have their own seeder functions called <code class="inline">srand()</code> and <code class="inline">mt_srand()</code> to provide a seed for the random number generators. You should just keep in mind that you only call <code class="inline">srand()</code> and <code class="inline">mt_srand()</code> once in your program. Calling them before every call to <code class="inline">rand()</code> and <code class="inline">mt_rand()</code> will give you the same "random" numbers every time.</p><pre class="brush: php noskimlinks noskimwords"><?php
srand(215);
echo rand()."\n"; // 330544099
srand(215);
echo rand()."\n"; // 330544099
srand(215);
echo rand()."\n"; // 330544099
echo rand()."\n"; // 138190029
echo rand()."\n"; // 1051333090
echo rand()."\n"; // 1219572487
?></pre><h2>Final Thoughts</h2><p>PHP comes with a lot of <a href="http://www.php.net/manual/en/ref.math.php" rel="external" target="_blank">built-in functions</a> that should meet all your day-to-day computation needs. You can use these functions to do slightly more complicated calculations like GCD, LCM and factorials yourself.</p><p>There are just a couple of things you should remember when using these functions. For example, the value returned by functions like <code class="inline">floor()</code> and <code class="inline">ceil()</code> is an integer, but it is still a float. Similarly, all trigonometric functions expect their angles to be given in radians. You will get incorrect results if you pass them an angle value that you wanted to be treated as a degree measure. So make sure you check the return value and expected arguments of all these functions in the <a href="http://php.net/manual/en/function.floor.php" rel="external" target="_blank">documentation</a>.<br></p>2018-10-12T12:06:59.000Z2018-10-12T12:06:59.000ZMonty Shokeen