【问题标题】:Malloc() to create a new size for integers for use with math - Guidance neededMalloc() 为用于数学的整数创建新大小 - 需要指导
【发布时间】:2017-01-24 10:02:07
【问题描述】:

我的目标是创建一个大于 4 字节的整数类型,如果我使用 long,则为 8。我尝试 malloc 尝试在内存中为更大的整数提供更多字节,但它在第 31 次迭代时仍然中断(给出一个负数)。这是我的代码:

int main()
{
    int x = 31; //(normally an int can do up to 30 without going negative so this is my test number)
    int i;

    int *bigNum = NULL;
    bigNum = malloc((sizeof(int)*2));
    *bigNum = 1;
    for (i=0; i<x; i++) {
          *bigNum = *bigNum * 2;
          printf("%d \n", *bigNum);
    }
    free(bigNum);
}

输出:

2
4
...
..
...
1073741824
-2147483648

【问题讨论】:

  • 整数溢出。你系统上的INT_MAX 是什么?
  • 它在第 31 次迭代时仍然中断 ....您有一个非常好的水晶证据表明正在发生的事情.... ...
  • 这里真的没有必要使用malloc和动态分配和指针。只需像普通变量一样定义您的 bigNum 变量也可以正常工作(或者就像您现在拥有的一样)。
  • 至于发生了什么,你有一个溢出。虽然溢出有符号整数(就像您所做的那样)在技术上是未定义的行为,但实际发生的事情取决于负数在您的计算机上的表示方式。阅读two's complement了解更多信息。

标签: c memory malloc


【解决方案1】:

虽然您为整数分配了更多内存,但系统的其他部分不知道这一点,包括:

  • 编译器不知道这一点;

  • CPU 芯片不知道这一点。

  • printf 不知道。

所以所有计算都只是使用原生 int 大小进行。

请注意,您不能告诉 CPU 芯片您使用了更大的整数;这是芯片的物理/设计限制。

【讨论】:

  • 很有道理!谢谢
【解决方案2】:

取消引用int * 会为您提供int,无论您为它分配多少额外内存

如果您想要一个能够保存更多信息的 dat 类型,请尝试使用 long(尽管保证它至少int 一样大)。

如果您想处理超出您的实现提供的整数,请使用 bignum 库,例如 MPIR

【讨论】:

  • 我对 bignum 库背后的逻辑很感兴趣,它们是如何产生这些数据类型的?
  • @SteveSlayo 任何整数都是字节数组,其中第一个字节的值是 0 到 2^8 - 1,第二个字节的值是 2^8 到 2^16 -1,依此类推。形式上类似于2^(0*8) &lt;= b0 - 1 &lt;= 2^(1*8)2^(1*8) &lt;= b1 - 1 &lt;= 2^(2*8)、...、2^(n*8) &lt;= bn - 1 &lt;= 2^((n+1)*8)
  • @Rand,要是我有答案就好了。等一下,我做: stackoverflow.com/questions/1218149/… :-)
  • @paxdiablo 你这个厚脸皮的家伙。那是一篇了不起的文章,完全回答了我的问题,谢谢!
【解决方案3】:

目标是创建一个更大尺寸的整数类型

要处理多个int整数,代码还需要支持每个基本操作的函数:

int main(void) {
    int x = 31;

    RandBigNum *bigNum = RandBigNum_Init();
    RandBigNum_Assign_int(bigNum, 1);
    for (int i=0; i<x; i++) {
      RandBigNum_Muliply_int(bigNum, 2);
      RandBigNum_Print(bigNum);
      printf(" \n");
    }

现在,如何实现这一切?许多方法。

下面是一个简单,不完整且未经测试的。这不一定是一个的方法,但可以初步了解完成一个大数字库所需的细节。

//  Numbers are all positive.  The first array element is the size of the number
typedef unsigned RandBigNum;

#define RandBigNum_MAXP1 (UINT_MAX + 1ull)

RandBigNum *RandBigNum_Init(void) {
  return calloc(1, sizeof *RandBigNum);
}

void RandBigNum_Muliply_int(RandBigNum *x, unsigned scale) {
  unsigned carry = 0;
  for (unsigned i = 1; i <= x[0]; i++) {
    unsigned long long product = 1ull * x[i] * scale + carry;
    x[i] = product % RandBigNum_MAXP1;
    carry *= product / RandBigNum_MAXP1;
  }
  if (carry) {
    unsigned n = x[0] + 2;
    x = realloc(x, sizeof *x * n); // re-alloc check omitted
    x[x[0]] = carry;
    x[0]++;
  }
}

// many other functions

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-13
    • 2021-05-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多