All pastes #253991 Raw Edit

Someone

public text v1 · immutable
#253991 ·published 2006-11-21 10:40 UTC
rendered paste body
#include <stdlib.h>
#include <string.h>

#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;
}