【问题标题】:How to store a digit string into an arbitrary large integer?如何将数字字符串存储为任意大整数?
【发布时间】:2016-09-20 18:10:27
【问题描述】:

ib 为输入基址,ob 为输出基址。 str 是任意大整数 x 的 ASCII 表示。我需要定义f 如:

f(str="1234567890", ib=10, ob=16) = {4, 9, 9, 6, 0, 2, 13, 2}

... 其中f 的返回类型是一个int 数组,其中包含该整数的基本ob 数字。我们假设2 >= ob <= MAX_INT2 >= ib <= 10str 将始终是一个有效的字符串(不需要否定)。

【问题讨论】:

  • 一个以零结尾的 int 数组是什么样的?在您的示例中,我猜想 {4, 9, 9, 6, 0, 2, 13, 2, 0} 将是 {4, 9, 9, 6} 如果它是零终止的。
  • @Welbog,好吧,直觉上,我会用对数来处理这个问题。
  • @4386427 你是对的,没有注意到这一点。编辑。
  • @qleguennec - 使用str is the ascii representation of some arbitrary large integer x 你不能使用任何正常的计算。输入的长度可能为 1.000.000 个字符。
  • @4386427 是的,这就是重点。

标签: c math digits arbitrary-precision


【解决方案1】:

让 OP 开始的东西,但足以让 OP 享受编码体验。

// form  (*d) = (*d)*a + b
static void mult_add(int *d, size_t *width, int ob, int a, int b) {
    // set b as the carry
    // for *width elements,
    //   x = (Multiply d[] by `a` (using wider than int math) and add carry)
    //   d[] = x mod ob
    //   carry = x/ob
    // while (carry <> 0)
    //   widen d
    //   x =  carry
    //   d[] = x mod ob
    //   carry = x/ob
}

int *ql_f(const char *src, int ib, int ob) {
  // Validate input
  assert(ib >= 2 && ib <= 10);
  assert(ob >= 2 && ob <= INT_MAX);
  assert(src);

  // Allocate space
  size_t length = strlen(src);
  // + 2 + 4 is overkill, OP to validate and right-size later
  size_t dsize = (size_t) (log(ib)/log(ob)*length + 2 + 4);   
  int *d = malloc(sizeof *d * dsize);
  assert(d);

  // Initialize d to zero
  d[0] = 0;
  size_t width = 1;
  while (*src) {
    mult_add(d, &width, ob, ib, *src - '0');
    src++;
  }

  // add -1 to end, TBD code

  return d;
}

【讨论】:

    【解决方案2】:

    我是用旧规范写的,所以它不再有效,但它可能作为一个起点有用。

    代码可以处理long long 量级。在 C 中使用任意精度数字是一个很大的飞跃!

    注意使用-1 作为结束标记而不是0。可以接受从 2 到 36 的 ib 和任何 ob

    包括示例main

    函数f不是按原样可重入的。为了使其线程安全,它可以分配所需的内存,然后返回一个指向它的指针。最简单的协议是让调用者负责之后释放内存。

    #include <stdlib.h>
    #include <limits.h>
    #include <stdio.h>
    
    int *f(const char *str, int ib, int ob) {
        static int result[CHAR_BIT * sizeof(long long) + 1];
        int i = sizeof(result) / sizeof(int) - 1;
        long long l = strtoll(str, NULL, ib);
        result[i--] = -1;
        while (l) {
            result[i] = l % ob;
            l /= ob;
            i--;
        }
        return result + i + 1;
    }
    
    int main()
    {
        int *x = f("1234567890", 16, 10);
        while (*x > -1) {
            printf("%d ", *x);
            x++;
        }
        return 0;
    }
    

    【讨论】:

      猜你喜欢
      • 2010-12-07
      • 2021-03-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-11-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多