riimu/kit-baseconversion

任意精度数字基数转换库

v1.2.0 2017-07-15 13:45 UTC

This package is auto-updated.

Last update: 2024-09-19 20:08:24 UTC


README

BaseConversion 是一个PHP库,用于转换数字基数,类似于PHP内置函数 base_convert()。然而,与内置函数不同,这个库不受32位整数的限制,能够转换任意精度的数字。这个库还支持分数的转换,并在数字基数方面提供了更多的自定义。

为了优化大数的转换,这个库还采用了两种不同的转换策略。在某些情况下,可以通过简单地用其他基数的数字替换数字来转换数字(例如,将基数从2转换为16)。这比另一种策略快得多,后者只是使用任意精度整数算术来计算新数字。

可以使用Apigen生成的API文档,可以在以下网址在线阅读: http://kit.riimu.net/api/baseconversion/

Travis Scrutinizer Scrutinizer Coverage Packagist

要求

  • 最低支持的PHP版本是 5.6
  • 该库依赖于以下PHP扩展
    • gmp (仅需要IDN支持)

安装

使用Composer安装

安装此库最简单的方法是使用Composer处理您的依赖项。为了通过Composer安装此库,只需遵循以下两个步骤

  1. 通过在项目根目录中运行Composer的 命令行安装 来获取 composer.phar

  2. 一旦运行了安装脚本,您应该在项目根目录中拥有 composer.phar 文件,并且可以运行以下命令

    php composer.phar require "riimu/kit-baseconversion:^1.2"
    

通过Composer安装此库后,您可以通过包含Composer在安装过程中生成的 vendor/autoload.php 文件来加载库。

添加库作为依赖项

如果您已经熟悉如何使用Composer,您还可以通过将以下 composer.json 文件添加到您的项目中并运行 composer install 命令来将库作为依赖项添加

{
    "require": {
        "riimu/kit-baseconversion": "^1.2"
    }
}

手动安装

如果您不希望使用Composer加载库,您也可以通过下载 最新版本 并将 src 文件夹提取到您的项目中手动下载库。然后,您可以将提供的 src/autoload.php 文件包含进来以加载库类。

使用

使用此库最方便的方法是通过 BaseConverter 类提供的 baseConvert() 静态方法。在大多数情况下,它的工作方式与 base_convert() 相同。例如

<?php

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

该方法接受负数和分数,方式相同。可以使用可选的第四个参数来定义转换的精度。例如

<?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

静态方法只是创建 BaseConvert 实例并调用 setPrecision()convert() 方法的方便包装。如果您需要转换多个数字,以非静态方式调用对象更有效。例如

<?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

如果提供的数字包含不属于定义的数字基数的无效数字,则方法将返回 false。

转换分数

虽然这个库支持分数的转换,但重要的是要理解,分数不能像整数一样总是从一种数制准确转换为另一种数制。这是由于并非所有分数都可以在另一种数制中表示。

例如,假设我们在3进制中有数字0.1。这等于10进制中的1/3。然而,如果你将1/3表示为十进制数,你会得到无限循环的'0.3333...'。例如

<?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

由于这种行为,可以设置用于不精确分数转换的精度。正如前一个例子所示,精度值定义了结果数字的最大位数。结果可能有更少的位数,但如果使用少量数字可以准确转换数字,则可能如此。如果转换器知道它可以准确转换分数,则可以完全忽略精度。

精度值还有一个替代定义。如果精度为0或负数,则结果数字的最大位数基于原始数字的精度。如果精度为0,则结果数字将具有与原始数字相同精度的位数。负数将简单地增加位数。例如

<?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

在前一个例子中,原始数字是16进制中的0.A7。16进制中有两位小数的数字可以表示精度为1/(16 * 16) == 1/256的数字。要在10进制中用相同精度表示小数部分,我们需要至少3位数字,因为两位数字只能表示精度为1/100的数字。

库默认使用的精度值是-1。还应注意,最后一位数字不会四舍五入(因为这会导致某些情况下结果不一致)。

大小写敏感

为了使用户与库的交互更加方便,库以不区分大小写的方式处理所有数字,除非数字基禁止这样做。例如,16进制可以不区分大小写处理,因为它只定义了数字0-9A-F的值。然而,62进制不能不区分大小写处理,因为字母如Aa有不同的值。

返回的数字将始终尊重数字基定义的字符大小写。例如

<?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

自定义数字基

这个库的一个特点是它允许比base_convert()更好的数字基自定义。在大多数情况下,你可能会使用简单的整数,如1016来定义数字基。然而,这个整数的尺寸没有限制。例如

<?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

然而,对于大的数字基,数字只是由一个由#和数字值组成的字符串表示。每当使用整数定义数字基时,数字遵循以下规则

  • 等于或小于62的基使用字符串0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz中的数字
  • 64进制的数字使用base64标准中的数字,即ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/
  • 等于或小于256的其他基使用字节作为数字,字节值表示数字值。
  • 大基使用由#和数字值组成的字符串作为数字(字符串的长度取决于最大的数字值)。

除了使用整数定义数字基数之外,还可以使用字符串来定义数字基数。字符串中的每个字符代表一个数字,每个字符的位置代表它的值。例如,十六进制基数可以定义为 0123456789ABCDEF。以这种方式定义数字基数还可以更容易地获取特定情况的最终结果。例如

<?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

还可以使用数组定义数字基数,这是第三种方法。这种方法可以提供更大的基数自定义。数组中的每个值代表一个数字,索引表示其值。例如

<?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: -¤---¤-!-%-"

致谢

本库版权所有(c)2013-2017 Riikka Kalliomäki。

有关许可和复制信息,请参阅LICENSE。