C 将无限长基数2^32数字转换为可打印基数10的算法

C 将无限长基数2^32数字转换为可打印基数10的算法,c,decimal,largenumber,C,Decimal,Largenumber,我将一个无限精确的整数表示为在GPU上处理的无符号整数数组。出于调试的目的,我想打印其中一个数字的以10为基数的表示形式,但是我很难理解它。以下是我想做的: //the number 4*(2^32)^2+5*(2^32)^1+6*(2^32)^0 unsigned int aNumber[3] = {4,5,6}; char base10TextRepresentation[50]; convertBase2To32ToBase10Text(aNumber,base10TextRepresen

我将一个无限精确的整数表示为在GPU上处理的无符号整数数组。出于调试的目的,我想打印其中一个数字的以10为基数的表示形式,但是我很难理解它。以下是我想做的:

//the number 4*(2^32)^2+5*(2^32)^1+6*(2^32)^0
unsigned int aNumber[3] = {4,5,6};
char base10TextRepresentation[50];
convertBase2To32ToBase10Text(aNumber,base10TextRepresentation);
对如何解决这个问题有什么建议吗

编辑:多亏了drhirsch,这里有一个完整的实现

#include <string.h>
#include <stdio.h>
#include <stdint.h>

#define SIZE 4

uint32_t divideBy10(uint32_t * number) {
  uint32_t r = 0;
  uint32_t d;
  for (int i=0; i<SIZE; ++i) {
    d = (number[i] + r*0x100000000) / 10;
    r = (number[i] + r*0x100000000) % 10;
    number[i] = d;
  }
  return r;
}

int zero(uint32_t* number) {
  for (int i=0; i<SIZE; ++i) {
    if (number[i] != 0) {
      return 0;
    }
  }
  return 1;
}

void swap(char *a, char *b) {
  char tmp = *a;
  *a = *b;
  *b = tmp;
}

void reverse(char *str) {
  int x = strlen(str);
  for (int y = 0; y < x/2; y++) {
    swap(&str[y],&str[x-y-1]);
  }
}

void convertTo10Text(uint32_t* number, char* buf) {
  int n = 0;
  do {
    int digit = divideBy10(number);
    buf[n++] = digit + '0';
  } while(!zero(number));
  buf[n] = '\0';
  reverse(buf);
}

int main(int argc, char** argv) {
  uint32_t aNumber[SIZE] = {0,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF};
  uint32_t bNumber[4] = {1,0,0,0};

  char base10TextRepresentation[50];

  convertTo10Text(aNumber, base10TextRepresentation);
  printf("%s\n",base10TextRepresentation);
  convertTo10Text(bNumber, base10TextRepresentation);
  printf("%s\n",base10TextRepresentation);
}
#包括
#包括
#包括
#定义大小4
uint32除以10(uint32*编号){
uint32_t r=0;
uint32_t d;

对于(int i=0;i如果它是.NET,请查看。

如果您可以访问64位算术,则更容易。我将按照以下方式进行操作:

int32_t divideBy10(int32_t* number) {
    uint32_t r = 0;
    uint32_t d;
    for (int i=0; i<SIZE; ++i) {
        d = (number[i] + r*0x100000000) / 10;
        r = (number[i] + r*0x100000000) % 10;
        number[i] = d;
        number[i] = r;
}

void convertTo10Text(int32_t* number, char* buf) {
    do {
        digit = divideBy10(number);
        *buf++ = digit + '0';
    } while (!isEqual(number, zero));
    reverse(buf);
}
int32除以10(int32*number){
uint32_t r=0;
uint32_t d;

对于(int i=0;i基本上,您需要使用传统的十进制打印,通过重复将数字除以10(以2^32为基数),并将余数用作数字。您可能没有一个除以(任何东西,更不用说)10例程,这可能是您的问题的关键根源

如果你在C或C++中工作,你可以得到一个完整的无限精度算术包。大多数其他广泛使用的语言都有类似的可用软件包。


当然,如果你有太多的空闲时间,你总是可以自己实现多精度除法。你已经从Knuth那里借用了术语;他还提供了半数值算法中的多精度算法。

使用长双精度如何?然后你在尾数中得到80位,但我想当你使用浮点数。

您使用的是哪种语言?C还是Java?您是如何实现无限精度的?:p我猜您指的是任意精度。等等,基数是2^32?必须使用非常大的字符集才能表示该基数中的一个数字!:)我们是否正在寻找新的方法在一张打印纸上填补美国的国家赤字?@Carl和Konamiman,在C工作。@Ben S,是的,任意;我从Knuth那里借用,他称之为“无限精度”。@Carl,数组的每个元素都是数字:一个数字[0]是以2^32为基数的数字的第一位。宇宙中的电子数(~10^73)可以用3,2^32位来表示。这是一个大数字:-}这就是问题所在。不幸的是,我必须自己实现所有多精度的东西,因为我想把它卸载到GPU上。实现除法似乎是一个很好的下一步。让GPU以无限精度除法打印数字是GPU的一个糟糕用法;它将产生多少十进制可打印数字在正常情况下,ce在一秒钟内完成?最好让传统软件完成。你暗示你正在GPU上实现无限精度算法。假设它不是用于十进制转换过程,你为什么要这样做?GPU给这个问题带来了什么,为什么你希望它能很好地扩展?对不起,这不是我的意思这并不意味着。打印数字只是为了在GPU外调试。在GPU上,我正在为任意精度的整数实现素性测试仪,这是一个令人尴尬的并行问题。啊哈。那么你是在并行测试一个数字,还是并行测试许多数字?我不是GPU专家,但我认为他们没有处理操作它在时间上有很大的差异才能很好地执行,因为在当前操作集的“末尾”实际上有一个障碍同步,而Amhdahl定律在这种情况下意味着效率低下的加速。我希望无限精度算术运算在乘法/除法/模运算的计时上有很大的差异。我遗漏了什么?