0

I am trying to implement multi-precision arithmetic for 256-bit operands based on radix-2^32 representation. In order to do that I defined operands as:

typedef union UN_256fe{

uint32_t uint32[8];

}UN_256fe;

and here is my MP addition function:

void add256(UN_256fe* A, UN_256fe* B, UN_256fe* result){

uint64_t t0, t1;
t0 = (uint64_t) A->uint32[7] + B->uint32[7];
result->uint32[7] = (uint32_t)t0;
t1 = (uint64_t) A->uint32[6] + B->uint32[6] + (t0 >> 32);
result->uint32[6] = (uint32_t)t1;
t0 = (uint64_t) A->uint32[5] + B->uint32[5] + (t1 >> 32);
result->uint32[5] = (uint32_t)t0;
t1 = (uint64_t) A->uint32[4] + B->uint32[4] + (t0 >> 32);
result->uint32[4] = (uint32_t)t1;
t0 = (uint64_t) A->uint32[3] + B->uint32[3] + (t1 >> 32);
result->uint32[3] = (uint32_t)t0;
t1 = (uint64_t) A->uint32[2] + B->uint32[2] + (t0 >> 32);
result->uint32[2] = (uint32_t)t1;
t0 = (uint64_t) A->uint32[1] + B->uint32[1] + (t1 >> 32);
result->uint32[1] = (uint32_t)t0;
t1 = (uint64_t) A->uint32[0] + B->uint32[0] + (t0 >> 32);
result->uint32[0] = (uint32_t)t1;

}

I implemented it without using loop for simplicity. Now when I test my function inside main:

#include <stdint.h>
#include <stdio.h>
#include <inttypes.h>
#include "mmulv3.0.h"

int main(){

UN_256fe result;
uint32_t c;

UN_256fe a = {0x00000f00,0xff00ff00,0xffff0000,0xf0f0f0f0,0x00000000,0xffffffff,0xf0fff000,0xfff0fff0};
UN_256fe b = {0x0000f000,0xff00ff00,0xffff0000,0xf0f0f0f0,0x00000000,0xffffffff,0xf0fff000,0xfff0ffff};
c = 2147483577;
printf("a:\n");
for(int i = 0; i < 8; i +=1){
    printf("%"PRIu32, a.uint32[i]);
}
printf("\nb:\n");
for(int i = 0; i < 8; i +=1){
    printf("%"PRIu32, b.uint32[i]);
}

add256(&a, &b, &result);
printf("\nResult for add256(a,b) = a + b:\n");
for(int i = 0; i < 8; i +=1){
    printf("%"PRIu32, result.uint32[i]);
}

return 0;
}

I've got:

a:
38404278255360429490176040423221600429496729540433049604293984240
b:
614404278255360429490176040423221600429496729540433049604293984255
Result for add256(a,b) = a + b:
652814261543425429483622537896770241429496729537916426254293001199

However, when I verified my result with sage, I've got:

sage: a=38404278255360429490176040423221600429496729540433049604293984240
sage: b=614404278255360429490176040423221600429496729540433049604293984255
sage: a+b
652808556510720858980352080846443200858993459080866099208587968495

Would you please help me out here?

4

3 回答 3

3

加法算法似乎是正确的,但是您不能通过单独转换每个组件来以十进制打印这些 256 位整数。

想想这个简单的例子:0x100000000,存储为{ 0,0,0,0,0,0,1,0 },将打印为10而不是4294967296。Base-10 转换比简单的加法要复杂得多。

于 2015-12-01T20:53:23.407 回答
1

会有助于在数字之间写一个空格字符。

但是 384 + 6144 + 1 是多少?我认为您是从错误的一端添加的。

于 2015-12-01T20:50:56.163 回答
0

要以十进制打印多精度数字需要一些代码,因为许多数字取决于整个uint32[8].

以十六进制打印出来要容易得多。

fputs("0x", stdout);
for (int i = 0; i < 8; i +=1){
    printf("%08" PRIX32, a.uint32[i]);
}
于 2015-12-01T21:58:24.143 回答