When must arbitrary precision arithmetic functions be used in PHP?

My colleague uses the Binary Calculator functions in bandwidth calculations; as much as terrabytes, and with percentage splitting on allocation. His usage of these functions appears correct in order not to lose a byte; although he seems to be using them now for everything.

The manual only says:

For arbitrary precision mathematics PHP offers the Binary Calculator which supports numbers of any size and precision, represented as strings.

How much is any size? Is it really necessary? How big is the default float in PHP? Are there any good advice regarding this or things to keep in mind?

The size of integers in PHP is platform dependent.

The size of an integer is platform-dependent, although a maximum value of about two billion is the usual value (that's 32 bits signed). 64-bit platforms usually have a maximum value of about 9E18. PHP does not support unsigned integers. Integer size can be determined using the constant PHP_INT_SIZE, and maximum value using the constant PHP_INT_MAX since PHP 4.4.0 and PHP 5.0.5.

The size of floats, is also platform dependent:

The size of a float is platform-dependent, although a maximum of ~1.8e308 with a precision of roughly 14 decimal digits is a common value (the 64 bit IEEE format).

and there's a big red warning in the manual about float precision:

Floating point numbers have limited precision. Although it depends on the system, PHP typically uses the IEEE 754 double precision format, which will give a maximum relative error due to rounding in the order of 1.11e-16. Non elementary arithmetic operations may give larger errors, and, of course, error progragation must be considered when several operations are compounded.

Additionally, rational numbers that are exactly representable as floating point numbers in base 10, like 0.1 or 0.7, do not have an exact representation as floating point numbers in base 2, which is used internally, no matter the size of the mantissa. Hence, they cannot be converted into their internal binary counterparts without a small loss of precision. This can lead to confusing results: for example, floor((0.1+0.7)*10) will usually return 7 instead of the expected 8, since the internal representation will be something like 7.9999999999999991118....

The BC Math extension bypasses the dependencies, allowing you to explicitly specify a large integer as a string, and avoid PHP's interpretation of integer literals. The GMP functions are also good alternatives and work in similar fashion. We can safely assume that `any size` refers to the maximum size of strings, which is only limited by available memory:

It is no problem for a string to become very large. PHP imposes no boundary on the size of a string; the only limit is the available memory of the computer on which PHP is running.

Whether it makes sense or not can only be decided on a per case basis. I've never noticed any actual performance issues with the extension's functions, but most certainly they aren't as fast as native alternatives.

Is it really necessary?

It's only necessary when it is, but that's not always obvious. You can easily identify blatant abuse, but can't as easily argue on more complex scenarios.

Discuss with your colleague, and find out why he uses them everywhere. Overflows lead to extremely ugly situations, ones that I find quite difficult to identify and solve. If he's abusing BC Math, it might be just because he got horribly stuck once and tries to play it as safe as possible. Although there's nothing inherently wrong with using BC Math, the otherwise insignificant performance penalty may be a serious issue in several scenarios. If you notice any performance issue, make sure you profile your application and be certain that's BC Math related.

Always remember that your calculations should work correctly:

• On every system you're targeting, individual developer machines and (of course) production machine included.

In multi platform development you should always consider the lowest limit as a hard limit. If you are absolutely certain that your calculations will not go over the limits (including their results), then there's no point in using BC Math.

But if what you're describing is that he prefers `echo bcadd("1", "2");` over `echo 1+2;`, well, good luck!

I found an extremely interesting & relevant blog post in my huge list of bookmarks, Integers in PHP, running with scissors, and portability, on Percona's MySQL Performance blog. It's old (2007) but it gives a good overview of various snafus with integer portability in PHP.

• Note that using strings is in no way necessary (in fact, I imagine it's rather ugly and complex to handle internally) for arbitary precision arithmetic, it's just an easy way to get literals for them. – user7043 Dec 29 '11 at 8:56
• @delnan Strings are used to pass parameters in Binary Calculator functions as, obviously, if you could use integers you wouldn't need the functions... The `by representing arbitrary precision numbers as strings` is taken from the manual, did you read that as a suggestion of what goes on internally? - ie, not a native English speaker, how could I improve that part? – yannis Dec 29 '11 at 9:03
• Yes, I think it could be read that as "BC Math uses strings interally" (though I for one have sufficent understanding of arbitary precision arithmetic to doubt that's actually the case), as that's almost literally what you state (below the third quote). I'm not a native speaker either, but I imagine it would be safer to state one interacts with BC Math through strings. – user7043 Dec 29 '11 at 9:12
• @delnan Thanks, I see what you mean. In my mind, the phrasing doesn't suggest what goes on internally, as the use of the library is actually to help you not care of what goes on internally, but I see it's confusing and possibly misleading. – yannis Dec 29 '11 at 9:22
• @delnan Updated the answer. – yannis Dec 29 '11 at 9:27

Are there any good advice regarding this or things to keep in mind?

• you can perform basic calculations on numbers with "numbers of any size and precision".

• calculation is not native (calculations on Integer or Float is PHP native and often CPU native)
• numbers as to be managed as strings
• code is not easy to read

So we can see that BC Math is reserved for a specific usage, and may obfuscate the formulas and even the algorithms, and also slow down massive calculations.

So it is a good idea to understand your business calculations to figure out when such functions are really needed and where they are useless. Thus here you have to focus on code speed and code readability. Then it is appropriate to choose the coding convention of the project on the usage of BC Math.

To do so, you have to understand the technical differences between the PHP native calculations and the BC Math Function. That is your questions "How much is any size? How big is the default float in PHP?"

How much is any size?

We cannot find much documentation about his. Probably as long as a string can be in PHP.

How big is the default float in PHP?

"The size of a float is platform-dependent, although a maximum of ~1.8e308 with a precision of roughly 14 decimal digits is a common value (the 64 bit IEEE format)."

More details at the PHP manual.

Note that PHP also give GMP Functions that performs calculations on big Integers.

I find bcmath much more friendly to use than GMP. So far I have not even been able to find out how to deal with floating point calculations with GMP in PHP. All floating point stuff seems to have been omitted in the PHP release. So I stick with bcmath (for now).

GMP on PHP seems to be geared towards number theory calculations and not numerical calculations like decimals of pi (or e) and similar.

"Are there any good advice regarding this or things to keep in mind?"

There is no real substitute for:

1. knowing the limitations of your PHP platform, and

2. understanding your problem's computational requirements.

In addition, some understanding of the mathematics of computation is always useful.

``````"When must arbitrary precision arithmetic functions be used in PHP?"
``````

I have never heard of a site having to use bcmath functions in PHP for what could be considered normal practices, and keep in mind that most of the largest sites on the internet use use substantial amounts of PHP, and over 240 million of the "smaller" sites are coded using PHP.

bcmath is typically used for extreme cases where numbers are likely to become either very large or very small, rather than situations where a 'long' is needed rather than an int, or when the specific size of an int or float is a concern.

``````"How much is any size?"
``````

bcmath is only limited by memory, and in truth this is not a real limitation. A quick test with bcmath shows it can handle numbers greater than 2^1000000 (which is 301,030+ digits, one million is only seven digits) and '0.1 - 2^1000000' which results in a negative of equal proportion.

As far as performance goes, bcmath is fast but can consume a lot of memory. It basically calculates numbers the same way that we would (as humans) using a pen in pad. Realistic numbers can be processed in just a few hundred steps, typically resulting in just a few milliseconds of time. But these 'few hundred' string copies will add up in memory. Note the numbers above (2^1000000) are unfathomably large and take my fairly old laptop 2-3 seconds to deal with.

``````"Is it really necessary?"
``````

In short, yes, but very rarely.

For example, SHA-1 hashes are actually numbers, not strings. The highest possible number using SHA-1 is 2^160, or 1,461,501,637,330,902,918,203,684,832,716,283,019,655,932,542,976. There's no way to work with such numbers using native data types, and working with SHA-1 hashes (as numbers) is fairly common in distributed algorithms.

Again, this is rare, but when it's needed there really isn't a substitute, regardless of your system or framework of preference.

``````"Advise"
``````

Do not use bcmath unless you either know it is what you need or just enjoy playing with numbers. It won't break anything and shouldn't cause noticeable performance issues, but most problems can be solved using PHP's standard datatypes.

• SHA-1 operates on several 32 bit integers internally. Externally it operates on byte sequences. So it's closer to strings than to big numbers. It's rarely helpful to treat it as a 160 bit integer. (There are other areas of crypto, such as RSA which use big integers internally, but you shouldn't implement those on a general purpose big integer library since that will open up side channel attacks) – CodesInChaos Jan 26 '14 at 11:25
• Hmm, I guess MIT had it wrong when they created Chord. I can hear the cloud crumbling as I type :P – JSON Jan 26 '14 at 21:20
• BTW, your right when it comes to SHA1's internals. – JSON Jan 26 '14 at 21:25
• Chord might interpret a SHA-1 hash as a large number. Not because of SHA-1 is related to big integers, but because the protocol built on top of it might find it convenient to do so. DHTs use a distance metric between hashes, theirs might be expressed using big integers. – CodesInChaos Jan 26 '14 at 21:31
• First off, big integers are a pseudo type. They don't exist natively any system. They are char strings internally, although some implementations allow big ints to be expressed as actual "numbers" in code (1234323456654322345 instead of "1234323456654322345" such as Java). Such implementations still create char strings when the number code is compiled. – JSON Jan 27 '14 at 18:46