varch/doc/intl.md
2024-09-27 02:18:53 +08:00

230 lines
6.8 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

## 介绍
`intl`为一个大型整数模块,该模块允许对超过 C 语言标准数据类型限制的大整数进行操作。它提供了一个灵活的长整型表示,使用 16 位和 32 位段来存储。
现在主流的计算机系统中一般支持的最大整形数为 32bits 或者 64bits 的,其能满足在一般情况下的计算及存储,但是面对一些更大的数时候就会显得有心无力。
而`intl`模块作为额外的整型数扩充,采用了一致的存储机制,而且在使用起来也非常方便。提供以下的计算:
- 支持基本算术操作:加法、减法、乘法、除法和取模。
- 位运算:与、或、异或、非。
- 移位操作:左移和右移。
- 将字符串和标准整数转换为大整数的功能。
- 提供以十进制、十六进制和二进制格式输出大整数的函数。
`intl` 可以按需配置为 128bits、256bits、512bits、1024bits、2048bits、4096bits、8192bits如果都还不满足还提供了生成更大bits的函数来生成更大的配置。
## 接口
## 结构定义
### `intl`
一个结构体,用于表示长整型整数,使用联合体以两种不同方式存储整数:
- 一个 `uint16_t` 类型的数组16 位段)。
- 一个 `uint32_t` 类型的数组32 位段)。
```c
typedef struct {
union {
uint16_t u16[INTL_U16_PARTS];
uint32_t u32[INTL_U32_PARTS];
};
} intl;
```
### 定义函数
```c
intl intl_from(const char *str); //
intl intl_from2(int value); //
```
`intl`提供了两种定义函数。
`intl_from`为从数字字符串中解析生成一个`intl`,支持解析十进制、二进制、八进制、十六进制字符串。
`intl_from2`为从`int`型中创建一个`intl`,此函数封装成更简短的宏定义方法`intl()`更贴近使用习惯,此方法执行效率更高。
两者的使用,当值在`int`的取值范围内时,推荐使用`intl()`方法,而当数值超越`int`的取值范围时或者需要不同进制进行定义时,就可以使用`intl_from()`方法。
同时,也可以使用常用值的宏定义`INTL_MAX`、`INTL_MIN`、`INTL_ZERO`。
例子:
```c
static void test_define(void)
{
intl a = intl(0);
intl b = intl(10);
intl c = intl(-10);
intl d = intl(0xFF);
intl e = intl_from("0");
intl f = intl_from("100");
intl g = intl_from("-100");
intl h = intl_from("123456789123456789123456789");
intl i = intl_from("0b1110000001111100101010100");
intl j = intl_from("0o1236541236763210233642166");
intl k = intl_from("0xF125E3F6D743648EEFFF12356");
intl max = INTL_MAX;
intl min = INTL_MIN;
intl n0 = INTL_ZERO;
}
```
### 转换函数
```c
const char* intl_sdec(intl a, char buffer[INTL_MAX_DEC]);
const char* intl_shex(intl a, char buffer[INTL_MAX_HEX]);
const char* intl_sbin(intl a, char buffer[INTL_MAX_BIN]);
```
此三个函数使用方法上是一致的,把`a`的值转换成十进制、十六进制、二进制到传入的`buffer`中,并返回有效位的`buffer`地址。
```c
#define INTL_P_DEC 0x01
#define INTL_P_BIN 0x02
#define INTL_P_HEX 0x04
static void print_intl(intl a, int type)
{
char buffer[INTL_MAX_BIN];
if (type & INTL_P_DEC) printf("intl (decimal): %s\n", intl_sdec(a, buffer));
if (type & INTL_P_HEX) printf("intl (hex): %s\n", intl_shex(a, buffer));
if (type & INTL_P_BIN) printf("intl (bin): %s\n", intl_sbin(a, buffer));
}
static void test_print(void)
{
intl a = intl_from("123456789123456789123456789");
print_intl(a, INTL_P_DEC);
print_intl(a, INTL_P_BIN);
print_intl(a, INTL_P_HEX);
}
```
结果:
```
intl (decimal): 123456789123456789123456789
intl (bin): 110011000011110111111011111001011100011101100011001111101111100000001000101111100010101
intl (hex): 661EFDF2E3B19F7C045F15
```
### 运算函数
```c
intl intl_add(intl a, intl b); // a+b
intl intl_sub(intl a, intl b); // a-b
intl intl_mul(intl a, intl b); // a*b
intl intl_div(intl a, intl b); // a/b
intl intl_mod(intl a, intl b); // a%b
intl intl_and(intl a, intl b); // a&b
intl intl_xor(intl a, intl b); // a^b
intl intl_or(intl a, intl b); // a|b
intl intl_shl(intl a, uint32_t amount); // a<<amount
intl intl_shr(intl a, uint32_t amount); // a>>amount
intl intl_not(intl a); // ~a
intl intl_abs(intl a); // |a|
intl intl_inc(intl a); // a++
intl intl_dec(intl a); // a--
intl intl_neg(intl a); // -a
int intl_cmp(intl a, intl b); // a>b a<b a>=b a<=b
int intl_sign(intl a); // a>0 a<0 a==0
```
`intl`运算函数与类似符号运算一致。
使用例子:
```c
static void test_calculate(void)
{
intl a = intl_from("123456789123456789123456789");
intl b = intl_from("987654321987654321987654321");
printf("a: \r\n");
print_intl(a, INTL_P_DEC);
printf("b: \r\n");
print_intl(b, INTL_P_DEC);
printf("a + b: \r\n");
print_intl(intl_add(a, b), INTL_P_DEC);
printf("a - b: \r\n");
print_intl(intl_sub(a, b), INTL_P_DEC);
printf("a * b: \r\n");
print_intl(intl_mul(a, b), INTL_P_DEC);
printf("b / a: \r\n");
print_intl(intl_div(b, a), INTL_P_DEC);
printf("b %% a: \r\n");
print_intl(intl_mod(b, a), INTL_P_DEC);
printf("a & b: \r\n");
print_intl(intl_and(a, b), INTL_P_DEC);
printf("a | b: \r\n");
print_intl(intl_or(a, b), INTL_P_DEC);
printf("a ^ b: \r\n");
print_intl(intl_xor(a, b), INTL_P_DEC);
printf("~a: \r\n");
print_intl(intl_not(a), INTL_P_DEC);
printf("a << 1: \r\n");
print_intl(intl_shl(a, 1), INTL_P_DEC);
printf("b >> 1: \r\n");
print_intl(intl_shr(b, 1), INTL_P_DEC);
printf("compare: %d\r\n", intl_cmp(a, b));
printf("a incremented: \r\n");
print_intl(intl_inc(a), INTL_P_DEC);
printf("b decremented: \r\n");
print_intl(intl_dec(b), INTL_P_DEC);
}
```
结果:
```
a:
intl (decimal): 123456789123456789123456789
b:
intl (decimal): 987654321987654321987654321
a + b:
intl (decimal): 1111111111111111111111111110
a - b:
intl (decimal): -864197532864197532864197532
a * b:
intl (decimal): 121932631356500531591068431581771069347203169112635269
b / a:
intl (decimal): 8
b % a:
intl (decimal): 9000000009000000009
a & b:
intl (decimal): 38793946662829560778723857
a | b:
intl (decimal): 1072317164448281550332387253
a ^ b:
intl (decimal): 1033523217785451989553663396
~a:
intl (decimal): -123456789123456789123456790
a << 1:
intl (decimal): 246913578246913578246913578
b >> 1:
intl (decimal): 493827160993827160993827160
compare: -1
a incremented:
intl (decimal): 123456789123456789123456790
b decremented:
intl (decimal): 987654321987654321987654320
```