我有一个代表bigint的unsigned char vector mynumber[]
。
这个数字是正数,我想将其转换为负数。
我试过这种方式
for(int i = 0; i < dimvector;i++)
mynumber[i] = ~mynumber[i];
我迭代我的矢量,但我需要总结一个。 如何总和?
如果我有溢出,怎么解决?
我使用GMP,导出后我必须将矢量传递给SHA256。
最后,我使用导入(GMP)在大数字中转换摘要的结果。
在导入中我有同样的导出问题。 标志很重要。
答案 0 :(得分:2)
Crikey。好的,首先,如何实现bignums:在GMP和其他库中,通常您将固定宽度字段指定为“肢体”或数字的一部分。到目前为止,你已经得到了那个部分,除了你更有可能分别使用uint32_t
或uint64_t
用于32位和64位平台,因为这些是寄存器和指令的大小,如{ {1}}如果添加两个寄存器溢出,则设置进位标志。
无论如何,重点是,这些肢体代表了bignum的实际大小,而不是它的标志。使用两个补码,我们期望在某个地方有一个符号位,但是如果你想调整一个数字(并且adc
不关心签名,它只是进行二进制加法)会变得混乱,因为你需要找到旧标志位,提取它,记住它,然后它回到正确的位置......非常慢。
我不确定你想要实现的是如何反转每个肢体中的位。如果你想象一组像这样的肢体(简单的简称)
adc
你最终得到:
1011 0111 1010 1011 = 47019
无论如何,GMP并不代表四肢的标志。 GMP中的带符号整数类型是0100 1000 0101 0100 = 18516
,由此结构定义:
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];
是GMP代表签名号码的方式。
在代码中(具体来说,_mp_size
)你会看到这个:
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.
系列函数执行,这些函数是您的无符号类型。
GMP具有许多基本类型的导入/导出功能,可以让您正确设置大小。我不太确定你要做什么,但假设它们不够,你应该能够自己设置它。