18

I'm currently trying to figure out how to work with arbitrary-precision numbers in PHP. So I guess my first question would be what exactly is arbitrary-precision math. I tried Googling for a good definition but for some reason nobody can put it in simple enough words.

Second, what are the differences between the BCMath and GMP libraries in PHP? I've heard claims that GMP's API is "fresher", but idk. Is one better?

And my final question would be what type of numbers BCMath/GMP takes. Obviously it takes normal integers in string form (e.g. "5.34"), but I've seen implementations where BCMath functions have been used directly with octet strings representing regular integers (e.g. "\x12\x23\x45\x67"), which I've heard as being called "bigint", but again Google has yielded nothing for me.

BenMorel
  • 34,448
  • 50
  • 182
  • 322
parent5446
  • 898
  • 7
  • 17
  • In theory both allow numbers of ANY length to be used, as long as they're fed into the library as strings. It boils down to whichever has the nicer API for your purposes. bc works purely with strings, while gmp can accept strings but uses its own internal representations as well. – Marc B Aug 05 '11 at 19:50
  • Note: to work with arbitrary-precision arithmetics, you can use a library such as [brick/math](https://github.com/brick/math) which uses GMP, BCMath, or even plain PHP behind the scenes automatically, depending on the availability of each extension. This way you don't have to chose between GMP and BCMath, and have a nice OO API to play with. – BenMorel Oct 17 '16 at 15:37

2 Answers2

27

what exactly is arbitrary-precision math?
Arbitrary precision arithmetic aka "bignum math", introduces a way of performing arithmetic operations on numbers which number of digits are only limited by the amount of memory available. This is in departure with the fixed precision arithmetic which is afforded by the CPUs/ALUs of the host systems and where the maximum size/precision of the number represented is a factor of the number of bits of the registers of these hardware processors.

Fixed precision arithmetic is fast, efficient with regards to storage and it is built-in/universally available. It is however applicable to limited (if only sometimes "big enough") numerical ranges. Arbitrary precision arithmetic is slower, somewhat wasteful of the storage and requires specialized libraries such as GMP or BCMath.

what are the differences between the BCMath and GMP libraries
The most salient difference is that GMP works on [arbitrary precision] integer values, whereby BCMath allows [arbitrary precision] decimal / float-like values.
Neither API is hard to learn, but BCMath may be a bit more intuitive (in addition to support float-like values)

One's selection of a particular library over another one is typically driven by the intended use (or by the availability on a given platform). Until you get heavily into MP applications, most library will fit the bill and be generally equivalent (within its class of course, i.e. avoid integer-only library if you need floating point numbers).

what type of numbers BCMath/GMP takes?
As with most arbitrary precision math packages, these two libraries use strings for their API, i.e. to represent their input and output numeric values.
Internally... Some packages like GMP have their own representation for the numbers. The specific of such structures is typically a compromise between minimizing storage requirements and allowing fast computations (including that of "serializing/deserializing" such structures to/from text files.)
The example "\x12\x23\x45\x67" in the question is known as BCD i.e. Binary Coded Decimal. It allows storing 2 decimal digits per byte and is sometimes used by Arbitrary Precision Arithmetic libraries.

mjv
  • 73,152
  • 14
  • 113
  • 156
  • Thanks for the answer! I only have two more things to clarify. Is there a reason to use BCD over regular integers? And do both BCMath and GMP accept BCD as well as regular integers[/floats for BCMath]? – parent5446 Aug 07 '11 at 04:44
  • Neither BCMath nor GMP accept values expressed in BCD. The advantage of BCD (as compared to strings with one digit or special character such as dot or minus sign etc.) is that BCD is more compact: stores 2 -rather than 1- digits per byte, while remaining easily mappable to the number's representation (a particular digit in the number corresponds to exactly one and only one nibble). One drawback of BCD is that it cannot be represented in C strings (because of the possible occurence of 2 zeros which get confused with the null terminator. – mjv Aug 08 '11 at 00:50
  • Typically, _you_ wouldn't want/need to use BCD, but this format is sometimes an internal format of the arbitrary precision arithmetic libraries, and it is also used for special applications. – mjv Aug 08 '11 at 00:52
  • 2
    This really shed a lot of **light**. This means the **BCMath Extension** is the way to go for calculations involving money. Even [Blockchain's PHP API Client Library](https://github.com/blockchain/api-v1-client-php#a-note-about-bitcoin-values) advises to use BCMath for Bitcoin calculations! _NB: never forget to specify your scale (usually the third parameter)!_ – Ema4rl Feb 12 '17 at 00:20
6

GMP is a ton faster BCMath, although BCMath can be made faster using OpenSSL. Here's a benchmark comparing the various techniques:

http://phpseclib.sourceforge.net/math/intro.html

neubert
  • 15,947
  • 24
  • 120
  • 212