C 数字字节表示

发布于 2024-11-16 02:32:25 字数 327 浏览 2 评论 0原文

我有一个代表 bigint 的无符号字符向量 mynumber[] 。 这个数字是正数,我想将其转换为负数。

我尝试过以这种方式

for(int i = 0; i < dimvector;i++)
 mynumber[i] = ~mynumber[i];

迭代我的向量,但我需要对它求和。 怎么求和一?

如果出现溢出,如何解决?

我使用 GMP,导出后我必须将向量传递给 SHA256。

最后,我使用导入(GMP)将摘要结果转换为大数。

在导入中我遇到了与导出相同的问题。 标志很重要。

I have an unsigned char vector mynumber[] that represents a bigint.
This number is positive and I want to convert it in a negative number.

I have tried in this way

for(int i = 0; i < dimvector;i++)
 mynumber[i] = ~mynumber[i];

I iterate my vector but I need to sum one.
How sum one?

If I have a overflow, how to solve?

I work with GMP and after the export I must pass the vector to SHA256.

At the end I trasform the result of digest in a Big number using import (GMP).

In the import I have the same problem of the export.
The sign is important.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

謸气贵蔟 2024-11-23 02:32:25

克里基。好的,首先,bignums 是如何实现的:在 GMP 和其他库中,通常您将固定宽度字段指定为“肢体”或数字的一部分。到目前为止,您已经完成了该部分,只是您更有可能分别针对 32 位和 64 位平台使用 uint32_tuint64_t,因为它们的大小是如果两个寄存器相加溢出,寄存器和指令(例如adc)会设置进位标志。

不管怎样,重点是,这些四肢代表了 bignum 的实际大小,而不是它的符号。使用二进制补码,我们期望在某处有一个符号位,但是如果您想调整数字的大小,那就会变得混乱(并且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 具有许多基本类型的导入/导出功能,可以让您正确设置大小。我不太确定你想要做什么,但假设它们还不够,你应该能够自己设置。

Crikey. Ok, first up, how bignums are implemented: in GMP and in other libraries, typically you designate a fixed-width field as a "limb", or part of the number. You've got that part right so far, except that you're more likely to use uint32_t or uint64_t for 32 and 64-bit platforms respectively because these are the size of the registers and instructions like adc set a carry flag if adding two registers overflows.

Anyway, the point being, these limbs represent the actual magnitude of the bignum, not its sign. Using two's complement, we'd expect a sign bit somewhere, but that gets messy if you want to resize a number (and adc doesn't care about signing, it just does binary addition) since you need to find the old sign bit, extract it, remember it, and it back in in the right place... very slow.

I'm not sure what you're trying to achieve inverting the bits in each limb. If you imagine a set of limbs like this (short for simplicity)

1011 0111 1010 1011 = 47019

You'd end up with:

0100 1000 0101 0100 = 18516

Anyway, GMP doesn't represent sign in the limbs. The signed integer type in GMP is mpz_t which is defined by this struct:

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]; 

So as you can see, _mp_size is how GMP represents signed numbers.

In code (specifically, mpz/aors.h) you'll see this used:

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.

The actual operations are performed by the mpn_ series of functions which are your unsigned types.

GMP has a number of import/export functions from basic types which should allow you to set the size correctly. I'm not quite sure what you're trying to do, but assuming they're insufficient, you ought to be able to set it yourself.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文