/** * Compile with * * $ gcc -Wall -I../include -L.. -o div2 div2.c -lsole */ #include #include #include #include "../src/blk256.h" #define B32 (double)(1ULL << 32) #define B64 ((double)B32*B32) #define B128 ((double)B64*B64) #define B192 ((double)B128*B64) #define B256 ((double)B128*B128) #define LOWMASK ((1ULL << 32) - 1) #define lo(x) ((x) & LOWMASK) #define hi(x) ((x) >> 32) #define u64(x) ((uint64_t)(x)) #define blk256_print(name, t) printf("%s: {%d, [%lu, %lu, %lu, %lu]}\n", name, (t).mx, (t).x[3], (t).x[2], (t).x[1], (t).x[0]) #define blk256_set(t, max, x3, x2, x1, x0) \ do { \ char tmx = max; \ uint64_t tx3 = x3; \ uint64_t tx2 = x2; \ uint64_t tx1 = x1; \ uint64_t tx0 = x0; \ (t)->mx = tmx; \ (t)->x[3] = tx3; \ (t)->x[2] = tx2; \ (t)->x[1] = tx1; \ (t)->x[0] = tx0; \ } while(0) /** * Provide a double representation of a 256-bit block */ double blk256_as_double(blk256_t *x) { return (double)(x->mx) * B256 + (double)(x->x[3]) * B192 + (double)(x->x[2]) * B128 + (double)(x->x[2]) * B64 + (double)(x->x[0]); } double blk128_as_double(blk128_t *y) { return (double)y->hi * B64 + (double)y->lo; } void double_as_blk256(blk256_t *rop, double x) { rop->mx = (char)(x / B256); rop->x[3] = (uint64_t)(x / B192); rop->x[2] = (uint64_t)(x / B128); rop->x[1] = (uint64_t)(x / B64); rop->x[0] = (uint64_t)x; } int main() { blk256_t x, z, q; blk128_t y = {UINT64_MAX, UINT64_MAX - 2}; blk256_set(&x, 1, 0, 0, 0, 0); /* First division */ double xx = blk256_as_double(&x); double yy = blk128_as_double(&y); double zz = xx / yy; blk256_print("x", x); printf("x=%lg\n", xx); double_as_blk256(&z, zz); blk256_print("z", z); blk256_t rop; blk256_mul_blk128(&rop, &z, &y); blk256_print("z*y", rop); blk256_sub(&x, &x, &rop); blk256_print("x", x); blk256_cp(&q, &z); /* Save q */ /* Next division */ printf("=== Next division\n"); xx = blk256_as_double(&x); zz = xx / yy; double_as_blk256(&z, zz); printf("zz=%lg\n", zz); blk256_print("z", z); blk256_mul_blk128(&rop, &z, &y); blk256_sub(&x, &x, &rop); blk256_print("x", x); blk256_add(&q, &q, &z); blk256_print("q", q); return 0; }