计算任意大二进制数之和的最快方法是什么

时间:2013-12-31 17:47:23

标签: c binary add

我似乎无法找到关于此的任何好文献。拥有BigBinaryNumber(虚拟符号位的两个补码)结构,如下所示:

typedef unsigned char byte;
enum Sign {NEGATIVE = (-1), ZERO = 0, POSITIVE = 1};
typedef enum Sign Sign;
struct BigBinaryNumber
{
    byte *number;
    Sign signum;
    unsigned int size;
};
typedef struct BigBinaryNumber BigBinaryNumber;

我可以选择小学方法(即将各个字节相加并使用进位进行后续求和),也可以使用固定大小的查找表。

关于最快的二元求和方法有没有好的文献?

2 个答案:

答案 0 :(得分:2)

添加数字的最快方法是处理器现有的add指令。只要你在内存中明确地设置了数字(例如,你没有倒序或者任何顺序),从每个数字一次加载32位应该非常简单,将它们原生地加在一起,并得到携带:

uint32_t *word_1 = &number1.number + offset, *word_2 = &number2.number + offset;
uint32_t *word_tgt = &dest.number + offset;
uint64_t sum = *word_1 + *word_2 + carry; // note the type!
*word_tgt = (uint32_t) sum; // truncate
carry = sum >> 32;

请注意,您可能需要添加一些特殊情况来处理数字中的最后一个字节(或确保*number总是分配了4个字节的倍数。)

如果您使用的是64位CPU,则可以将其扩展为使用uint64_t。但是,溢出没有uint128_t,所以你可能不得不使用一些技巧来获取进位。

答案 1 :(得分:0)

“技巧”是使用原生(或可能更大)的整数大小。

@duskwuff只需要花费number,一次多个字节。

与所有“最快的方式......”一样,应该对候选解决方案进行分析。

Follows是一个一个类型的解决方案,因此可以使用最大类型,本机类型或任何1类型。例如uintmax_tunsigned。进位是通过代码处理的偏好,进位生成取决于测试添加是否会溢出。

typedef unsigned MyInt;
#define MyInt_MAX  UINT_MAX

void Add(BigBinaryNumber *a, BigBinaryNumber *b, BigBinaryNumber *sum) {
  // Assume same size for a, b, sum.
  // Assume memory allocated for sum.
  // Assume a->size is a multiple of sizeof(MyInt);
  // Assume a->number endian is little and matches platform endian.
  // Assume a->alignment matches MyInt alignment.
  unsigned int size = a->size;
  MyInt* ap   = a->number;
  MyInt* bp   = b->number;
  MyInt* sump = sum->number;
  int carry = 0;
  while (size > 0) {
    size -= sizeof(MyInt);
    if (carry) {
      if (*ap <= (MyInt_MAX - 1 - *bp)) {
        carry = 0;
      }
      *sump++ = *ap++ + *bp++ + 1;
    }
    else {
      if (*ap > (MyInt_MAX - *bp)) {
        carry = 1;
      }
      *sump++ = *ap++ + *bp++;
    } 
  } // end while
  // Integer overflow/underflow handling not shown, 
  //   but depend on carry, and the sign of a, b
  // Two's complement sign considerations not shown.
}