#include #include #include "bint.h" bool bint_create ( bint *b, word n ) { b->data = malloc( 32 * sizeof( word ) ); if ( !b->data ) return false; b->len = 1; b->mem = 32; b->data[0] = n; #ifdef Debug memset( b->data + 1, 0, 31 * sizeof( word ) ); #endif return true; } void bint_set ( bint *b, word n ) { #ifdef Debug memset( b->data, 0, b->len * sizeof( word ) ); #endif b->data[0] = n; b->len = 1; } dword bint_get ( bint *b ) { if ( b->len < 2 ) return b->data[0]; return b->data[0] | ( ( dword ) ( b->data[1] ) << 16 ); } bool bint_copy ( bint *x, bint *y ) { dword len, mem; len = y->len; mem = y->mem; x->data = malloc( mem * sizeof( word ) ); if ( !x->data ) return false; x->len = len; x->mem = mem; memcpy( x->data, y->data, len * sizeof( word ) ); #ifdef Debug memset( x->data + len * sizeof( word ), 0, ( mem - len ) * sizeof( word ) ); #endif return true; } bool bint_destroy ( bint *b ) { free( b->data ); #ifdef Debug memset( b, 0, sizeof( bint ) ); #endif } bool bint_reserve ( bint *b, dword r ) { dword mem; word *data; if ( b->mem >= r ) return true; mem = b->mem; while ( mem && mem < r ) mem <<= 1; if ( !mem ) return false; data = realloc( b->data, mem * sizeof( word ) ); if ( !data ) return false; #ifdef Debug memset( data + b->mem, 0, ( mem - b->mem ) * sizeof( word ) ); #endif b->data = data; b->mem = mem; return true; } bool bint_mul ( bint *b, word n ) { d_word t; word *data; dword i, len; if ( b->len + 2 >= b->mem ) { if ( !bint_reserve( b, b->mem + 2 ) ) return false; } t.d = 0; len = b->len; data = b->data; for ( i = 0; i < len; i++ ) { t.d += ( dword ) n * data[i]; data[i] = t.lo; t.d = t.hi; } if ( t.d ) { data[i] = t.lo; b->len += 1; } return true; } word bint_div ( bint *b, word n ) { word *p; dword i, t; t = 0; i = b->len; p = b->data; while ( i > 0 ) { t <<= 16; t += p[--i]; p[i] = t / n; t = t % n; } i = b->len; while ( --i && !p[i] ); if ( !i ) i++; b->len = i; return t; } bool bint_print ( FILE *f, bint *b ) { bint c; dword m, n; byte *p, *buf; if ( !bint_copy( &c, b ) ) return false; m = c.len * 5 + 3; buf = malloc( m + 1 ); if ( !buf ) { bint_destroy( &c ); return false; } p = buf + m; *p = 0; while ( c.data[c.len - 1] ) { n = bint_div( &c, 10000 ); *--p = ( n % 10 ) + '0'; n = n / 10; *--p = ( n % 10 ) + '0'; n = n / 10; *--p = ( n % 10 ) + '0'; n = n / 10; *--p = n + '0'; } while ( *p == '0' ) p++; fprintf( f, "%s\n", p ); bint_destroy( &c ); free( buf ); return true; }