## riimu/kit-baseconversion

Arbitrary precision number base conversion library

Requires

- php: >=5.4.0
- ext-gmp: *

# README

*BaseConversion* is a PHP library for converting number bases, similar to PHP's
built in function `base_convert()`

. However, unlike the built in function, this
library is not limited by 32 bit integers and is capable of converting numbers
of arbitrary precision. This library also supports conversion of fractions and
allows more customization in terms of number bases.

In order to optimize the conversion of large numbers, this library also employs two different conversion strategies. In some cases, it's possible to convert numbers simply by replacing the digits with digits from the other base (e.g. when converting from base 2 to base 16). This is considerably faster than the other strategy, which simply calculates the new number using arbitrary precision integer arithmetic.

The API documentation, which can be generated using Apigen, can be read online at: http://kit.riimu.net/api/baseconversion/

## Requirements

In order to use this library, the following requirements must be met:

- PHP version 5.4
- GMP extension must be enabled

## Installation

This library can be installed via Composer. To do
this, download the `composer.phar`

and require this library as a dependency. For
example:

```
$ php -r "readfile('https://getcomposer.org/installer');" | php
$ php composer.phar require riimu/kit-baseconversion:1.*
```

Alternatively, you can add the dependency to your `composer.json`

and run
`composer install`

. For example:

{ "require": { "riimu/kit-baseconversion": "1.*" } }

Any library that has been installed via Composer can be loaded by including the
`vendor/autoload.php`

file that was generated by Composer.

It is also possible to install this library manually. To do this, download the
latest release and
extract the `src`

folder to your project folder. To load the library, include
the provided `src/autoload.php`

file.

## Usage

The most convenient way to use this library is via the `baseConvert()`

static
method provided by the `BaseConverter`

class. In most cases, it works the same
way as `base_convert()`

does. For example:

<?php require 'vendor/autoload.php'; use Riimu\Kit\BaseConversion\BaseConverter; echo BaseConverter::baseConvert('A37334', 16, 2); // outputs: 101000110111001100110100

The method accepts negative numbers and fractions in the same way. An optional fourth parameter can be used to define the precision for the conversion. For example:

<?php require 'vendor/autoload.php'; use Riimu\Kit\BaseConversion\BaseConverter; echo BaseConverter::baseConvert('-1BCC7.A', 16, 10) . PHP_EOL; // outputs: -113863.625 echo BaseConverter::baseConvert('-1BCC7.A', 16, 10, 1); // outputs: -113863.6

The static method is simply a convenient wrapper for creating an instance of
`BaseConvert`

and calling the `setPrecision()`

and `convert()`

methods. If you
need to convert multiple numbers, it's more efficient to call the object in a
non static manner. For example:

<?php require 'vendor/autoload.php'; use Riimu\Kit\BaseConversion\BaseConverter; $converter = new BaseConverter(16, 10); echo $converter->convert('A37334') . PHP_EOL; // outputs: 10711860 echo $converter->convert('-1BCC7.A') . PHP_EOL; // outputs: -113863.625 $converter->setPrecision(1); echo $converter->convert('-1BCC7.A'); // outputs: -113863.6

If the provided number contains invalid digits that are not part of the defined number base, the method will return false instead.

### Converting Fractions

While this library does support conversion of fractions, it's important to understand that fractions cannot always be converted accurately from number base to another the same way that integers can be converted. This is result of the fact that not all fractions can be represented in another number base.

For example, let's say we have the number 0.1 in base 3. This equals the same as 1/3 in base 10. However, if you were to represent 1/3 as a decimal number, you would get an infinitely repeating '0.3333...'. For example:

<?php require 'vendor/autoload.php'; use Riimu\Kit\BaseConversion\BaseConverter; echo BaseConverter::baseConvert('0.1', 3, 10) . PHP_EOL; // outputs: 0.33 echo BaseConverter::baseConvert('0.1', 3, 10, 6) . PHP_EOL; // outputs: 0.333333 echo BaseConverter::baseConvert('0.1', 3, 10, 12); // outputs: 0.333333333333

Due to this behavior, it is possible to set the precision used for inaccurate fraction conversions. As can be seen in the previous example, the precision value defines the maximum number of digits in the resulting number. The result may have less digits, however, if the number can be accurately converted using a small number of digits. The precision may also be completely ignored, if the converter knows, that it can accurately convert the fractions.

The precision value also has an alternative definition. If the precision is 0 or a negative number, then the maximum number of digits in the resulting number is based on the precision of the original number. If the precision is 0, the resulting number will have as many digits as it takes to represent the number in the same precision as the original number. A negative number will simply increase the number of digits in addition to that. For example:

<?php require 'vendor/autoload.php'; use Riimu\Kit\BaseConversion\BaseConverter; echo BaseConverter::baseConvert('0.A7', 16, 10, 0) . PHP_EOL; // outputs: 0.652 echo BaseConverter::baseConvert('0.A7', 16, 10, -2); // outputs: 0.65234

In the previous example, the original number is `0.A7`

in the base 16. A base 16
number with two digits in the fractional part can represent a number up to
accuracy of `1/(16 * 16) == 1/256`

. To represent the the fractional part in the
same accuracy in base 10, we need at least 3 digits, because two digit can only
represent numbers up to accuracy of `1/100`

.

The default precision value used by the library is `-1`

. It is also important
to note that the last digit is not rounded (due to the fact that it would
cause inconsistent results in some cases).

### Case Sensitivity

In order to make user interaction with the library more convenient, the library
treats all numbers in a case insensitive manner, unless the number base
prohibits that. For example, the base 16 can be treated in a case insensitive
manner, because it only defines the value for the digits `0-9A-F`

. However,
base 62 cannot be treated in a case insensitive manner, because letters like
`A`

and `a`

have a different value.

The returned numbers will always respect the character case defined by the number base. For example:

<?php require 'vendor/autoload.php'; use Riimu\Kit\BaseConversion\BaseConverter; echo BaseConverter::baseConvert('7BFA11', 16, 12) . PHP_EOL; // outputs: 2879B29 echo BaseConverter::baseConvert('7bfa11', 16, 12); // outputs: 2879B29

### Customizing Number Bases

One of the features of this library is that allows much better customization of
number bases than `base_convert()`

. In most cases, you will probably define the
number base using a simple integer such as `10`

or `16`

. However, there is no
limit to the size of that integer. For example:

<?php require 'vendor/autoload.php'; use Riimu\Kit\BaseConversion\BaseConverter; echo BaseConverter::baseConvert('7F', 16, 1024) . PHP_EOL; // outputs: #0127 echo BaseConverter::baseConvert('5Glm1z', 64, 512); // outputs: #456#421#310#371

For large number bases, however, the digits are simply represented by a string
that consists of `#`

and the value for the digit. Whenever the number base is
defined using an integer, the digits follow the following rules:

- Bases equal or smaller than 62 use digits from the string
`0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz`

- A base 64 number uses digits from the base64 standard, i.e.
`ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/`

- Other bases equal or smaller than 256 use bytes as digits with byte value indicating the digit value.
- Large bases use strings for digits that consist of
`#`

and the value for the digit (the length of the string depends on the greatest digit value).

In addition to defining the number base using an integer, it's also possible
to define the number base using a string. Each character in the string
represents a digit and the position of each character represents it's value.
The base 16, for example, could be defined as `0123456789ABCDEF`

. Defining
number bases this way also makes it easier to get resulting numbers in a
specific case. For example:

<?php require 'vendor/autoload.php'; use Riimu\Kit\BaseConversion\BaseConverter; echo BaseConverter::baseConvert('101100011101', '01', 16) . PHP_EOL; // outputs: B1D echo BaseConverter::baseConvert('101100011101', 2, '0123456789abcdef'); // outputs: b1d

There is also a third way to define the number bases using an array. This allows even greater customization in terms of number bases. Each value in the array represents a digit and the index indicates the value. For example:

<?php require 'src/autoload.php'; use Riimu\Kit\BaseConversion\BaseConverter; echo BaseConverter::baseConvert('22', 10, ['nil', 'one']) . PHP_EOL; // outputs: oneniloneonenil echo BaseConverter::baseConvert('187556', 10, ['-', '-!', '-"', '-#', '-¤', '-%']); // outputs: -¤---¤-!-%-"

## Credits

This library is copyright 2013 - 2015 to Riikka Kalliomäki.

See LICENSE for license and copying information.