克里基。好的,首先,bignums 是如何实现的:在 GMP 和其他库中,通常您将固定宽度的字段指定为“肢体”或数字的一部分。到目前为止,您已经掌握了该部分,除了您更有可能分别使用uint32_t
oruint64_t
用于 32 位和 64 位平台,因为这些是寄存器的大小和指令,例如adc
在添加两个寄存器溢出时设置进位标志。
无论如何,重点是,这些肢体代表的是大元的实际大小,而不是它的符号。使用二进制补码,我们希望在某个地方有一个符号位,但是如果你想调整一个数字的大小(并且adc
不关心签名,它只是进行二进制加法),那会变得很乱,因为你需要找到旧的符号位,提取它,记住它,然后它回到正确的位置......非常慢。
我不确定你想实现什么反转每个肢体中的位。如果你想象一组这样的肢体(简单的缩写)
1011 0111 1010 1011 = 47019
你最终会得到:
0100 1000 0101 0100 = 18516
无论如何,GMP并不代表四肢的迹象。GMP 中的有符号整数类型mpz_t
由以下结构定义:
typedef struct
{
int _mp_alloc; /* Number of *limbs* allocated and pointed
to by the _mp_d field. */
int _mp_size; /* abs(_mp_size) is the number of limbs the
last field points to. If _mp_size is
negative this is a negative number. */
mp_limb_t *_mp_d; /* Pointer to the limbs. */
} __mpz_struct;
typedef __mpz_struct mpz_t[1];
如您所见,_mp_size
GMP 是如何表示有符号数的。
在代码中(特别是mpz/aors.h
),你会看到这个用法:
usize = u->_mp_size;
vsize = VARIATION v->_mp_size;
// .....
if ((usize ^ vsize) < 0)
{
/* U and V have different sign. Need to compare them to determine
which operand to subtract from which. */
// does subtraction instead of add.
实际操作由mpn_
您的无符号类型的一系列函数执行。
GMP 具有许多基本类型的导入/导出功能,它们应该允许您正确设置大小。我不太确定您要做什么,但是假设它们还不够,您应该可以自己设置。