Teachings of a Samurai Engineer

Teachings of a Samurai Engineer 3: Functions Handling Numerical Value and Numbers

PHP comes with math functions.
Of these functions, several don’t seem to be used much outside of specific jobs.

PHP comes with math functions.
Of these functions, several don’t seem to be used much outside of specific jobs. For example, there may be a time when you need a function to calculate base-10 logarithms (common logarithm), but most of the time you don’t need it.
On the other hand, there are functions that you use more frequently once you remember them. I’d like to introduce several of them.

Personally, one function I use (relatively) frequently is abs().
This function returns the absolute value of a number.

<?php
var_dump( abs(100) );
var_dump( abs(-100) );
var_dump( abs(1.23) );
var_dump( abs(-1.23) );
var_dump( abs('50') );
var_dump( abs('-50') );
var_dump( abs('a') );
var_dump( abs('-5a') );

<Result>
int(100)
int(100)
float(1.23)
float(1.23)
int(50)
int(50)
int(0)
int(5)
</Result>

If your input value is the int data type, the return value is also the int data type; if your input value is a real number (e.g. float) data type, the return value is also that real number data type. So abs() is quite convenient because it returns the absolute value without changing the input value’s data type.

In short, if, for example, you want to make sure the number of pages that come externally from pagination data doesn’t end up as a negative value, you can simply apply abs().

What’s more, if the input value is a number represented as text, that string is interpreted as a numerical value and returned as the int data type. So abs() is convenient in a variety of ways, as it can be used for input values that aren’t specifically cast to the int type.

Next, I sometimes use floor() and ceil(), which are “floor” and “ceiling” functions. Simply put, they round up or round down a fraction. 
var_dump( floor(10.23) );
var_dump( ceil(10.23) );
var_dump( floor(-10.23) );
var_dump( ceil(-10.23) );

<Result>
float(10)
float(11)
float(-11)
float(-10)
</Result>

Rounding up/down a fraction is done quite often.

Cases dealing with negative numbers are relatively rare, I think. So you need to be a bit careful about what value a negative number will become after rounding it up or down.

A related function is round(). It rounds a number to a specified number of digits. But because a floating-point number may have some degree of error, round() may show subtle differences in behavior around boundary values.
var_dump( round(0.4) );
var_dump( round(0.4999999999999999) );
var_dump( round(0.49999999999999991) );
var_dump( round(0.49999999999999992) );
var_dump( round(0.49999999999999994) );
var_dump( round(0.5) );

<Result>
float(0)
float(0)
float(0)
float(1)
float(1)
float(1)
</Result>

For a number up to 0.49999999999999991 and for 0.5, round() behaves as you’d expect it to behave.

How does your intuitive sense compare to round()’s result of 1 (rounding up) when rounding 0.49999999999999992?
Handling such a small number is probably rare, but if there is the possibility, you need to be careful.
If you don’t have a situation where there is such a fine boundary line, round()is a convenient function.

Related to the math functions are two functions that generate random numbers, rand() and mt_rand().
These functions are unexpectedly useful for creating simple games and adding gamification to programs.
<?php
var_dump( mt_rand(1, 6) );
var_dump( mt_rand(1, 6) );
var_dump( mt_rand(1, 6) );
var_dump( mt_rand(1, 6) );
var_dump( mt_rand(1, 6) );
var_dump( mt_rand(1, 6) );

<Result>
int(6)
int(2)
int(1)
int(4)
int(1)
int(3)
</Result>

Because mt_rand() generates high-quality random numbers and is lightweight in its operation, it is used more often than rand().

However, if you read the official documentation of these two functions, you’ll come across the following: “Caution: This function does not generate cryptographically secure values, and should not be used for cryptographic purposes.” It recommends using random_int(), random_bytes(), or openssl_random_pseudo_bytes() to generate cryptographically secure values.

Of these functions, only openssl_random_pseudo_bytes() requires explicitly specifying prescribed compilation options. So I’ll look at random_int() and random_bytes(), which are included in Core PHP.

……Before we proceed, one important point.
random_int() and random_bytes() are available in PHP 7 and later versions.
For PHP 5 versions (PHP 5.2 and later), use a userland implementation, or if using PHP 5.3 or later, use openssl_random_pseudo_bytes().

Returning to our topic,
random_int() can be used like mt_rand().
<?php
var_dump( random_int(1, 6) );
var_dump( random_int(1, 6) );
var_dump( random_int(1, 6) );
var_dump( random_int(1, 6) );
var_dump( random_int(1, 6) );
var_dump( random_int(1, 6) );

<Result>
int(6)
int(2)
int(3)
int(4)
int(3)
int(4)
</Result>

If you desire an int result that is safer than a result generated by mt_rand(), random_int() is sufficient.

On the other hand, if you desire a longer random number string, use random_bytes(). But you need to be careful when you use it.
Depending on your environment and the random number result, the code below may cause the console display to freeze. If that happens, the only thing you can do is force-quit the console. So be careful when you execute random_bytes().

<?php
var_dump( random_bytes(2) );

Most likely, the result displayed will be unintelligible, except on extremely rare occasions.
<Result>
string(2) “??”
</Result>
This is because the output is a random byte sequence (binary).

The result as-is is a bit hard to use.
So we usually use random_bytes() in conjunction with a function like bin2hex() or base64_encode().
bin2hex() converts binary data to hexadecimal representation. When you use this function, the binary data is converted to a printable string composed of characters 0-9 and a-f.

Similarly, base64_encode() encodes binary data using the MIME base64 method. The MIME base64 method replaces binary data with characters ‘0-9 a-z A-Z + /’. (The tail end often appears as padding). In this way a binary value can be converted to a printable string containing (0-9 a-z A-Z + / =).

<?php
var_dump( bin2hex(random_bytes(16)) );
var_dump( bin2hex(random_bytes(16)) );
var_dump( bin2hex(random_bytes(16)) );
var_dump( base64_encode(random_bytes(16)) );
var_dump( base64_encode(random_bytes(16)) );
var_dump( base64_encode(random_bytes(16)) );

<Result>
string(32) “3fc8b08b96511212c7a2dbd876950d9c”
string(32) “07d5fb4f3d3361e18cc3cf0450897e36”
string(32) “16aa3c2941ca24a3b2cc031efd0f6ff1”
string(24) “k4Cu2ndhAmsOboeaLL8BpA==”
string(24) “95EuoBOJ5UkjRme3Xl1L+g==”
string(24) “q5c/AySN1908Gq3YhdQo0w==”
</Result>

Because random_bytes() outputs binary data, using a function like bin2hex() or base64_encode() often make it easy to handle the data.

I think you understand now the things that are possible with PHP. But what are they used for? From my next column, I’d like to explore the uses of PHP, for example, to create “tokens.”

Part 1

Part 2

Part 4

Part 5

Part 6

Part 7

Part 8

Michiaki Furusho

PREVIOUS ARTICLE NEXT ARTICLE