//
// LiDIA - a library for computational number theory
//   Copyright (c) 1994, 1995 by the LiDIA Group
//
// File        : lattice_modules.c
// Author      : Werner Backes (WB), Thorsten Lauer (TL)
// Last change : WB/TL, May 09 1996, initial version, previously
//                      class bigint_lattice_gensys/basis
//               WB/TL, Jul 27 1996, 
//                      redesign of class structure introducing 
//                      lattice_modules, initial version
//               WB/TL, Aug 06 1996, 
//                      added template parameter to use more
//                      variations of the modules
//                      - class modules<T,S,Variation>
//                        -> implementation that are equal for
//                           both basis and gensys
//                      - class basis_modules<T,S,Variation>
//                        -> derived from modules implementing
//                           the basis parts
//                      - class gensys_modules<T,S,Variation>
//                        -> derived from modules implementing
//                           the gensys parts
//
//
#ifndef __lattice_modules_c__
#define __lattice_modules_c__

#ifdef NO_LATTICE_INLINE
#include <LiDIA/lattice_modules.h>
#else
#ifdef LIDIA_INLINE_PROBLEM
#define LATTICE_INLINE
#include <LiDIA/lattice_modules.h>
#endif
#endif

//
// Code for 
// 	     * base_modules<{bigfloat,bigint},{double,xdouble,bigfloat}>
//
//
// bigint / double 
//
LATTICE_INLINE void prec_modules<bigint, double>::
prec_startup(dense_alg<bigint>&) { };

LATTICE_INLINE void prec_modules<bigint, double>::
prec_update(dense_alg<bigint>& da) 
{ 
  da.d.cut_bit_prec=(1+(da.d.bit_prec/MANTISSA_CUT))*MANTISSA_CUT;
  da.d.approx_prec=(sdigit )((double )da.d.bit_prec*log(2)/log(10));
};

LATTICE_INLINE void prec_modules<bigint, double>::
prec_exact(const dense_alg<bigint>&) { };

LATTICE_INLINE void prec_modules<bigint, double>::
prec_approx(const dense_alg<bigint>&) { };

LATTICE_INLINE void prec_modules<bigint, double>::
prec_correct(const dense_alg<bigint>&) { };

LATTICE_INLINE void prec_modules<bigint, double>::
prec_restore(const dense_alg<bigint>&) { };

//
// bigint / xdouble
//
LATTICE_INLINE void prec_modules<bigint, xdouble>::
prec_startup(dense_alg<bigint>&) { };

LATTICE_INLINE void prec_modules<bigint, xdouble>::
prec_update(dense_alg<bigint>& da) 
{ 
  da.d.cut_bit_prec=(1+(da.d.bit_prec/MANTISSA_CUT))*MANTISSA_CUT;
  da.d.approx_prec=(sdigit )((double )da.d.bit_prec*log(2)/log(10));
};

LATTICE_INLINE void prec_modules<bigint, xdouble>::
prec_exact(const dense_alg<bigint>&) { };

LATTICE_INLINE void prec_modules<bigint, xdouble>::
prec_approx(const dense_alg<bigint>&) { };

LATTICE_INLINE void prec_modules<bigint, xdouble>::
prec_correct(const dense_alg<bigint>&) { };

LATTICE_INLINE void prec_modules<bigint, xdouble>::
prec_restore(const dense_alg<bigint>&) { };


//
// bigint / bigfloat
//
LATTICE_INLINE void prec_modules<bigint, bigfloat>::
prec_startup(dense_alg<bigint>& da) 
{ 
  da.d.old_prec=bigfloat::get_precision();
  da.d.approx_prec=(sdigit )((double )da.d.bit_prec*log(2)/log(10));
};

LATTICE_INLINE void prec_modules<bigint, bigfloat>::
prec_update(dense_alg<bigint>& da) 
{ 
  da.d.cut_bit_prec=(1+(da.d.bit_prec/MANTISSA_CUT))*MANTISSA_CUT;
  da.d.approx_prec=(sdigit )((double )da.d.bit_prec*log(2)/log(10));
};

LATTICE_INLINE void prec_modules<bigint, bigfloat>::
prec_exact(const dense_alg<bigint>&) { };

LATTICE_INLINE void prec_modules<bigint, bigfloat>::
prec_approx(const dense_alg<bigint>& da) 
{ 
  bigfloat::precision(da.d.approx_prec);
};

LATTICE_INLINE void prec_modules<bigint, bigfloat>::
prec_correct(const dense_alg<bigint>&) { };

LATTICE_INLINE void prec_modules<bigint, bigfloat>::
prec_restore(const dense_alg<bigint>& da) 
{ 
  bigfloat::precision(da.d.old_prec);
};

//
// bigfloat / double
//
LATTICE_INLINE void prec_modules<bigfloat, double>::
prec_startup(dense_alg<bigfloat>& da) 
{
//
// Compute precision of read lattice
//
  da.d.old_prec=bigfloat::get_precision();
  da.d.read_prec=0;
  for (fcl(i)=0;i<da.b.rows;++i)
    for (fcl(j)=0;j<da.b.columns;++j)
      if (da.d.read_prec < (tempsdt=(sdigit )(da.s.value[i][j].bit_length()/
					      log(10)+1)))
        da.d.read_prec=tempsdt;
  da.d.exact_prec=da.d.read_prec*((da.b.columns>da.b.rows)?
				  da.b.columns:da.b.rows);
  da.d.exact_prec*=Magic_Precision_Factor;
};

LATTICE_INLINE void prec_modules<bigfloat, double>::
prec_update(dense_alg<bigfloat>& da) 
{ 
  da.d.cut_bit_prec=(1+(da.d.bit_prec/MANTISSA_CUT))*MANTISSA_CUT;
  da.d.approx_prec=(sdigit )((double )da.d.bit_prec*log(2)/log(10));
};

LATTICE_INLINE void prec_modules<bigfloat, double>::
prec_approx(const dense_alg<bigfloat>&) { };

LATTICE_INLINE void prec_modules<bigfloat, double>::
prec_exact(const dense_alg<bigfloat>& da) 
{ 
  bigfloat::precision(da.d.exact_prec);
};

LATTICE_INLINE void prec_modules<bigfloat, double>::
prec_correct(const dense_alg<bigfloat>& da) 
{ 
  bigfloat::precision(da.b.columns+((sdigit )(DOUBLE_MANTISSA_BITS*log(2)/
					      log(10)+1)*2));
};

LATTICE_INLINE void prec_modules<bigfloat, double>::
prec_restore(const dense_alg<bigfloat>& da) 
{ 
  bigfloat::precision(da.d.old_prec);
};

//
// bigfloat / xdouble
//
LATTICE_INLINE void prec_modules<bigfloat, xdouble>::
prec_startup(dense_alg<bigfloat>& da) 
{
  da.d.old_prec=bigfloat::get_precision();
//
// Compute precision of read lattice
//
  da.d.read_prec=0;
  for (fcl(i)=0;i<da.b.rows;++i)
    for (fcl(j)=0;j<da.b.columns;++j)
      if (da.d.read_prec < (tempsdt=(sdigit )(da.s.value[i][j].bit_length()/
					      log(10)+1)))
        da.d.read_prec=tempsdt;
  da.d.exact_prec=da.d.read_prec*((da.b.columns>da.b.rows)?
				  da.b.columns:da.b.rows);
  da.d.exact_prec*=Magic_Precision_Factor;
};

LATTICE_INLINE void prec_modules<bigfloat, xdouble>::
prec_update(dense_alg<bigfloat>& da) 
{ 
  da.d.cut_bit_prec=(1+(da.d.bit_prec/MANTISSA_CUT))*MANTISSA_CUT;
  da.d.approx_prec=(sdigit )((double )da.d.bit_prec*log(2)/log(10));
};

LATTICE_INLINE void prec_modules<bigfloat, xdouble>::
prec_approx(const dense_alg<bigfloat>&) { };

LATTICE_INLINE void prec_modules<bigfloat, xdouble>::
prec_exact(const dense_alg<bigfloat>& da) 
{ 
  bigfloat::precision(da.d.exact_prec);
};

LATTICE_INLINE void prec_modules<bigfloat, xdouble>::
prec_correct(const dense_alg<bigfloat>& da) 
{ 
  bigfloat::precision(da.b.columns+((sdigit )(DOUBLE_MANTISSA_BITS*log(2)/
					      log(10)+1)*4));
};

LATTICE_INLINE void prec_modules<bigfloat, xdouble>::
prec_restore(const dense_alg<bigfloat>& da) 
{ 
  bigfloat::precision(da.d.old_prec);
};

//
// bigfloat / bigfloat
//
LATTICE_INLINE void prec_modules<bigfloat, bigfloat>::
prec_startup(dense_alg<bigfloat>& da) 
{
  da.d.old_prec=bigfloat::get_precision();
  da.d.approx_prec=(sdigit )((double )da.d.bit_prec*log(2)/log(10));
//
// Compute precision of read lattice
//
  da.d.read_prec=0;
  for (fcl(i)=0;i<da.b.rows;++i)
    for (fcl(j)=0;j<da.b.columns;++j)
      if (da.d.read_prec < (tempsdt=(sdigit )(da.s.value[i][j].bit_length()/
					      log(10)+1)))
        da.d.read_prec=tempsdt;
  da.d.exact_prec=da.d.read_prec*((da.b.columns>da.b.rows)?
				  da.b.columns:da.b.rows);
  da.d.exact_prec*=Magic_Precision_Factor;
};

LATTICE_INLINE void prec_modules<bigfloat, bigfloat>::
prec_update(dense_alg<bigfloat>& da) 
{ 
  da.d.cut_bit_prec=(1+(da.d.bit_prec/MANTISSA_CUT))*MANTISSA_CUT;
  da.d.approx_prec=(sdigit )((double )da.d.bit_prec*log(2)/log(10));
};

LATTICE_INLINE void prec_modules<bigfloat, bigfloat>::
prec_approx(const dense_alg<bigfloat>& da) 
{ 
  bigfloat::precision(da.d.approx_prec);
};

LATTICE_INLINE void prec_modules<bigfloat, bigfloat>::
prec_exact(const dense_alg<bigfloat>& da) 
{ 
  bigfloat::precision(da.d.exact_prec);
};

LATTICE_INLINE void prec_modules<bigfloat, bigfloat>::
prec_correct(const dense_alg<bigfloat>& da) 
{ 
  bigfloat::precision(da.b.columns+((sdigit )(da.d.bit_prec*log(2)/
					      log(10)+1)*2));
};

LATTICE_INLINE void prec_modules<bigfloat, bigfloat>::
prec_restore(const dense_alg<bigfloat>& da) 
{ 
  bigfloat::precision(da.d.old_prec);
};
//
// End of  
// 	     * prec_modules<{bigfloat,bigint},{double,xdouble,bigfloat}>
//

//
// Code for 
// 	     * base_modules<bigint,{double,xdouble,bigfloat},Normal>
// 	     * basis_modules<bigint,{double,xdouble,bigfloat},Normal>
// 	     * gensys_modules<bigint,{double,xdouble,bigfloat},Normal>
//
LATTICE_INLINE void base_modules<bigint, double, Normal>::
E_convert_value_A(dense_alg<bigint>&, double& d, const bigint& bin)
{
  d=dbl(bin);
}

LATTICE_INLINE bool base_modules<bigint, double, Normal>::
A_convert_value_E_bound(dense_alg<bigint>&, bigint& bin, const double& dbl, 
		        const double& bound) 
{
  if (fabs(dbl) > bound)
    {
      tempbfl.assign(dbl);
      tempbfl.bigintify(bin);
      return (true);
    }
  else
    {
      bin.assign((sdigit )dbl);
      return (false);
    }
}

LATTICE_INLINE void base_modules<bigint, xdouble, Normal>::
E_convert_value_A(dense_alg<bigint>&, xdouble& xd, const bigint& bin)
{
  xd=xdbl(bin);
}

LATTICE_INLINE bool base_modules<bigint, xdouble, Normal>::
A_convert_value_E_bound(dense_alg<bigint>&, bigint& bin, const xdouble& xdbl, 
		        const xdouble& bound) 
{
  tempbfl.assign(xdbl);
  tempbfl.bigintify(bin);
  if (fabs(xdbl) > bound)
    return (true);
  return (false);
}

LATTICE_INLINE void base_modules<bigint, bigfloat, Normal>::
E_convert_value_A(dense_alg<bigint>& da, bigfloat& bfl, const bigint& bin) 
{
  bi_bit_len=bin.bit_length();
  if (bi_bit_len > da.d.cut_bit_prec)
    {
      bit_diff=bi_bit_len-da.d.cut_bit_prec;
      shift_right(tempbin, bin, bit_diff);
      bfl.assign(tempbin);
      shift_left(bfl, bfl, bit_diff);
    }
  else
    bfl.assign(bin);
}

LATTICE_INLINE bool base_modules<bigint, bigfloat, Normal>::
A_convert_value_E_bound(dense_alg<bigint>&, bigint& bin, const bigfloat& bfl, 
	           	const bigfloat& bound) 
{
  bfl.bigintify(bin);
  if (abs(bfl).compare(bound) > 0)
    return (true);
  return (false);
} 

LATTICE_INLINE void basis_modules<bigint, double, Normal>::
E_convert_lattice_A(dense_alg<bigint>& da, double** dblvalue)
{
  for (fcl(i)=0;i<da.b.rows;i++)
    for (fcl(j)=0;j<da.b.columns;j++)
      dblvalue[i][j]=dbl(da.s.value[i][j]);
}

LATTICE_INLINE bool basis_modules<bigint, double, Normal>::
E_convert_vector_A(dense_alg<bigint>& da, double **dblvalue, const lidia_size_t k)
{
  for (fcl(i)=0;i<da.b.columns;i++)
    dblvalue[k][i]=dbl(da.s.value[k][i]);
  return(false);
}

LATTICE_INLINE void basis_modules<bigint, xdouble, Normal>::
E_convert_lattice_A(dense_alg<bigint>& da, xdouble** xdblvalue)
{
  for (fcl(i)=0;i<da.b.rows;i++)
    for (fcl(j)=0;j<da.b.columns;j++)
      xdblvalue[i][j]=xdbl(da.s.value[i][j]);
}

LATTICE_INLINE bool basis_modules<bigint, xdouble, Normal>::
E_convert_vector_A(dense_alg<bigint>& da, xdouble **xdblvalue, const lidia_size_t k)
{
  for (fcl(i)=0;i<da.b.columns;i++)
    xdblvalue[k][i]=xdbl(da.s.value[k][i]);
  return(false);
}

LATTICE_INLINE void basis_modules<bigint, bigfloat, Normal>::
E_convert_lattice_A(dense_alg<bigint>& da, bigfloat** bflvalue)
{
  for (fcl(i)=0;i<da.b.rows;i++)
    for (fcl(j)=0;j<da.b.columns;j++)
      {
        bi_bit_len=da.s.value[i][j].bit_length();
        if (bi_bit_len > da.d.cut_bit_prec)
          {
            bit_diff=bi_bit_len-da.d.cut_bit_prec;
            shift_right(tempbin, da.s.value[i][j], bit_diff);
            bflvalue[i][j].assign(tempbin);
            shift_left(bflvalue[i][j], bflvalue[i][j], bit_diff);
          }
        else
          bflvalue[i][j].assign(da.s.value[i][j]);
      }
}

LATTICE_INLINE bool basis_modules<bigint, bigfloat, Normal>::
E_convert_vector_A(dense_alg<bigint>& da, bigfloat** bflvalue, const lidia_size_t k)
{
  for (fcl(i)=0;i<da.b.columns;i++)
    {
      bi_bit_len=da.s.value[k][i].bit_length();
      if (bi_bit_len > da.d.cut_bit_prec)
	{
	  bit_diff=bi_bit_len-da.d.cut_bit_prec;
	  shift_right(tempbin, da.s.value[k][i], bit_diff);
	  bflvalue[k][i].assign(tempbin);
	  shift_left(bflvalue[k][i], bflvalue[k][i], bit_diff);
	}
      else
	bflvalue[k][i].assign(da.s.value[k][i]);
    }
  return (false);
}

LATTICE_INLINE void gensys_modules<bigint, double, Normal>::
E_convert_lattice_A(dense_alg<bigint>& da, double** dblvalue)
{
  for (fcl(i)=0;i<da.b.rank;)
    {
      is_zero=true;
      for (fcl(j)=0;j<da.b.columns;j++)
	if ((!is_zero) || (!da.s.value[i][j].is_zero()))
	  {
	    dblvalue[i][j]=dbl(da.s.value[i][j]);
	    is_zero=false;
	  }
	else
	  dblvalue[i][j]=0.0;
      if (is_zero)
	{
	  da.b.rank--;
	  for (fcl(j)=i;j<da.b.rank;j++)
	    {
	      tempP=(void *)dblvalue[j];
	      dblvalue[j]=dblvalue[j+1];
	      dblvalue[j+1]=(double *)tempP;
	      tempP=(void *)da.s.value[j];
	      da.s.value[j]=da.s.value[j+1];
	      da.s.value[j+1]=(bigint *)tempP;
	    }
	}
      else
        i++;
    }
}

LATTICE_INLINE bool gensys_modules<bigint, double, Normal>::
E_convert_vector_A(dense_alg<bigint>& da, double** dblvalue, 
		   const lidia_size_t k)
{
  is_zero=true;
  for (fcl(i)=0;i<da.b.columns;i++)
    if ((!is_zero) || (!da.s.value[k][i].is_zero()))
      {
	dblvalue[k][i]=dbl(da.s.value[k][i]);
	is_zero=false;
      }
    else
      dblvalue[k][i]=0.0;
  if (is_zero)
    {
      da.b.rank--;
      for (fcl(i)=k;i<da.b.rank;i++)
	{
	  tempP=(void *)dblvalue[i];
	  dblvalue[i]=dblvalue[i+1];
	  dblvalue[i+1]=(double *)tempP;
	  tempP=(void *)da.s.value[i];
	  da.s.value[i]=da.s.value[i+1];
	  da.s.value[i+1]=(bigint *)tempP;
	}
      return(true);
    }
  return(false);
}

LATTICE_INLINE void gensys_modules<bigint, xdouble, Normal>::
E_convert_lattice_A(dense_alg<bigint>& da, xdouble** xdblvalue)
{
  for (fcl(i)=0;i<da.b.rank;)
    {
      is_zero=true;
      for (fcl(j)=0;j<da.b.columns;j++)
	if ((!is_zero) || (!da.s.value[i][j].is_zero()))
	  {
	    xdblvalue[i][j]=xdbl(da.s.value[i][j]);
	    is_zero=false;
	  }
	else
	  xdblvalue[i][j]=0.0;
      if (is_zero)
	{
	  da.b.rank--;
	  for (fcl(j)=i;j<da.b.rank;j++)
	    {
	      tempP=(void *)xdblvalue[j];
	      xdblvalue[j]=xdblvalue[j+1];
	      xdblvalue[j+1]=(xdouble *)tempP;
	      tempP=(void *)da.s.value[j];
	      da.s.value[j]=da.s.value[j+1];
	      da.s.value[j+1]=(bigint *)tempP;
	    }
	}
      else
        i++;
    }
}

LATTICE_INLINE bool gensys_modules<bigint, xdouble, Normal>::
E_convert_vector_A(dense_alg<bigint>& da, xdouble** xdblvalue, 
		   const lidia_size_t k)
{
  is_zero=true;
  for (fcl(i)=0;i<da.b.columns;i++)
    if ((!is_zero) || (!da.s.value[k][i].is_zero()))
      {
	xdblvalue[k][i]=xdbl(da.s.value[k][i]);
	is_zero=false;
      }
    else
      xdblvalue[k][i]=0.0;
  if (is_zero)
    {
      da.b.rank--;
      for (fcl(i)=k;i<da.b.rank;i++)
	{
	  tempP=(void *)xdblvalue[i];
	  xdblvalue[i]=xdblvalue[i+1];
	  xdblvalue[i+1]=(xdouble *)tempP;
	  tempP=(void *)da.s.value[i];
	  da.s.value[i]=da.s.value[i+1];
	  da.s.value[i+1]=(bigint *)tempP;
	}
      return(true);
    }
  return(false);
}

LATTICE_INLINE void gensys_modules<bigint, bigfloat, Normal>::
E_convert_lattice_A(dense_alg<bigint>& da, bigfloat** bflvalue)
{
  for (fcl(i)=0;i<da.b.rank;)
    {
      is_zero=true;
      for (fcl(j)=0;j<da.b.columns;j++)
	if ((!is_zero) || (!da.s.value[i][j].is_zero()))
	  {
	    bi_bit_len=da.s.value[i][j].bit_length();
	    if (bi_bit_len > da.d.cut_bit_prec)
	      {
		bit_diff=bi_bit_len-da.d.cut_bit_prec;
		shift_right(tempbin, da.s.value[i][j], bit_diff);
		bflvalue[i][j].assign(tempbin);
		shift_left(bflvalue[i][j], bflvalue[i][j], bit_diff);
	      }
	    else
	      bflvalue[i][j].assign(da.s.value[i][j]);
	    is_zero=false;
	  }
	else
	  bflvalue[i][j].assign_zero();
      if (is_zero)
	{
	  da.b.rank--;
	  for (fcl(j)=i;j<da.b.rank;j++)
	    {
	      tempP=(void *)bflvalue[j];
	      bflvalue[j]=bflvalue[j+1];
	      bflvalue[j+1]=(bigfloat *)tempP;
	      tempP=(void *)da.s.value[j];
	      da.s.value[j]=da.s.value[j+1];
	      da.s.value[j+1]=(bigint *)tempP;
	    }
	}
      else
        i++;
    }
}

LATTICE_INLINE bool gensys_modules<bigint, bigfloat, Normal>::
E_convert_vector_A(dense_alg<bigint>& da, bigfloat** bflvalue, 
		   const lidia_size_t k)
{
  is_zero=true;
  for (fcl(i)=0;i<da.b.columns;i++)
    if ((!is_zero) || (!da.s.value[k][i].is_zero()))
      {
	bi_bit_len=da.s.value[k][i].bit_length();
	if (bi_bit_len > da.d.cut_bit_prec)
	  {
	    bit_diff=bi_bit_len-da.d.cut_bit_prec;
	    shift_right(tempbin, da.s.value[k][i], bit_diff);
	    bflvalue[k][i].assign(tempbin);
	    shift_left(bflvalue[k][i], bflvalue[k][i], bit_diff);
	  }
	else
	  bflvalue[k][i].assign(da.s.value[k][i]);
	is_zero=false;
      }
    else
      bflvalue[k][i].assign_zero();
  if (is_zero)
    {
      da.b.rank--;
      for (fcl(i)=k;i<da.b.rank;i++)
	{
	  tempP=(void *)bflvalue[i];
	  bflvalue[i]=bflvalue[i+1];
	  bflvalue[i+1]=(bigfloat *)tempP;
	  tempP=(void *)da.s.value[i];
	  da.s.value[i]=da.s.value[i+1];
	  da.s.value[i+1]=(bigint *)tempP;
	}
      return(true);
    }
  return(false);
}
//
// End of  
// 	     * base_modules<bigint,{double,xdouble,bigfloat},Normal>
// 	     * basis_modules<bigint,{double,xdouble,bigfloat},Normal>
// 	     * gensys_modules<bigint,{double,xdouble,bigfloat},Normal>
//

//
// Code for 
// 	     * base_modules<bigint,{double,xdouble,bigfloat},VariationI>
// 	     * basis_modules<bigint,{double,xdouble,bigfloat},VariationI>
// 	     * gensys_modules<bigint,{double,xdouble,bigfloat},VariationI>
//
LATTICE_INLINE void base_modules<bigint, double, VariationI>::
E_convert_value_A(dense_alg<bigint>& da, double& d, const bigint& bin)
{
  tempbfl.assign(bin);
  shift_right(tempbfl, tempbfl, da.d.bit_factor);
  tempbfl.doublify(d);
}

LATTICE_INLINE bool base_modules<bigint, double, VariationI>::
A_convert_value_E_bound(dense_alg<bigint>&, bigint& bin, const double& dbl, 
		        const double& bound) 
{
  if (fabs(dbl) > bound)
    {
      tempbfl.assign(dbl);
      tempbfl.bigintify(bin);
      return (true);
    }
  else
    {
      bin.assign((sdigit )dbl);
      return (false);
    }
}

LATTICE_INLINE void base_modules<bigint, xdouble, VariationI>::
E_convert_value_A(dense_alg<bigint>& da, xdouble& xd, const bigint& bin)
{
  tempbfl.assign(bin);
  shift_right(tempbfl, tempbfl, da.d.bit_factor);
  tempbfl.xdoublify(xd);
}

LATTICE_INLINE bool base_modules<bigint, xdouble, VariationI>::
A_convert_value_E_bound(dense_alg<bigint>&, bigint& bin, const xdouble& xdbl, 
		        const xdouble& bound) 
{
  tempbfl.assign(xdbl);
  tempbfl.bigintify(bin);
  if (fabs(xdbl) > bound)
    return (true);
  return (false);
}

LATTICE_INLINE void base_modules<bigint, bigfloat, VariationI>::
E_convert_value_A(dense_alg<bigint>& da, bigfloat& bfl, const bigint& bin) 
{
  bi_bit_len=bin.bit_length();
  if (bi_bit_len > da.d.cut_bit_prec)
    {
      bit_diff=bi_bit_len-da.d.cut_bit_prec;
      shift_right(tempbin, bin, bit_diff);
      bfl.assign(tempbin);
      shift_left(bfl, bfl, bit_diff);
    }
  else
    bfl.assign(bin);
  shift_right(bfl, bfl, da.d.bit_factor);
}

LATTICE_INLINE bool base_modules<bigint, bigfloat, VariationI>::
A_convert_value_E_bound(dense_alg<bigint>&, bigint& bin, const bigfloat& bfl, 
	           	const bigfloat& bound) 
{
  bfl.bigintify(bin);
  if (abs(bfl).compare(bound) > 0)
    return (true);
  return (false);
} 

LATTICE_INLINE void basis_modules<bigint, double, VariationI>::
E_convert_lattice_A(dense_alg<bigint>& da, double** dblvalue)
{
  for (fcl(i)=0;i<da.b.rows;i++)
    for (fcl(j)=0;j<da.b.columns;j++)
      {
	tempbfl.assign(da.s.value[i][j]);
	shift_right(tempbfl, tempbfl, da.d.bit_factor);
	tempbfl.doublify(dblvalue[i][j]);
      }
}

LATTICE_INLINE bool basis_modules<bigint, double, VariationI>::
E_convert_vector_A(dense_alg<bigint>& da, double **dblvalue, const lidia_size_t k)
{
  for (fcl(i)=0;i<da.b.columns;i++)
    {
      tempbfl.assign(da.s.value[k][i]);
      shift_right(tempbfl, tempbfl, da.d.bit_factor);
      tempbfl.doublify(dblvalue[k][i]);
    }
  return(false);
}

LATTICE_INLINE void basis_modules<bigint, xdouble, VariationI>::
E_convert_lattice_A(dense_alg<bigint>& da, xdouble** xdblvalue)
{
  for (fcl(i)=0;i<da.b.rows;i++)
    for (fcl(j)=0;j<da.b.columns;j++)
      {
	tempbfl.assign(da.s.value[i][j]);
	shift_right(tempbfl, tempbfl, da.d.bit_factor);
	tempbfl.xdoublify(xdblvalue[i][j]);
      }
}

LATTICE_INLINE bool basis_modules<bigint, xdouble, VariationI>::
E_convert_vector_A(dense_alg<bigint>& da, xdouble **xdblvalue, const lidia_size_t k)
{
  for (fcl(i)=0;i<da.b.columns;i++)
    {
      tempbfl.assign(da.s.value[k][i]);
      shift_right(tempbfl, tempbfl, da.d.bit_factor);
      tempbfl.xdoublify(xdblvalue[k][i]);
    }
  return(false);
}

LATTICE_INLINE void basis_modules<bigint, bigfloat, VariationI>::
E_convert_lattice_A(dense_alg<bigint>& da, bigfloat** bflvalue)
{
  for (fcl(i)=0;i<da.b.rows;i++)
    for (fcl(j)=0;j<da.b.columns;j++)
      {
        bi_bit_len=da.s.value[i][j].bit_length();
        if (bi_bit_len > da.d.cut_bit_prec)
          {
            bit_diff=bi_bit_len-da.d.cut_bit_prec;
            shift_right(tempbin, da.s.value[i][j], bit_diff);
            bflvalue[i][j].assign(tempbin);
            shift_left(bflvalue[i][j], bflvalue[i][j], bit_diff);
          }
        else
          bflvalue[i][j].assign(da.s.value[i][j]);
	shift_right(bflvalue[i][j], bflvalue[i][j], da.d.bit_factor);
      }
}

LATTICE_INLINE bool basis_modules<bigint, bigfloat, VariationI>::
E_convert_vector_A(dense_alg<bigint>& da, bigfloat** bflvalue, 
		   const lidia_size_t k)
{
  for (fcl(i)=0;i<da.b.columns;i++)
    {
      bi_bit_len=da.s.value[k][i].bit_length();
      if (bi_bit_len > da.d.cut_bit_prec)
	{
	  bit_diff=bi_bit_len-da.d.cut_bit_prec;
	  shift_right(tempbin, da.s.value[k][i], bit_diff);
	  bflvalue[k][i].assign(tempbin);
	  shift_left(bflvalue[k][i], bflvalue[k][i], bit_diff);
	}
      else
	bflvalue[k][i].assign(da.s.value[k][i]);
      shift_right(bflvalue[k][i], bflvalue[k][i], da.d.bit_factor);
    }
  return (false);
}

LATTICE_INLINE void gensys_modules<bigint, double, VariationI>::
E_convert_lattice_A(dense_alg<bigint>& da, double** dblvalue)
{
  for (fcl(i)=0;i<da.b.rank;)
    {
      is_zero=true;
      for (fcl(j)=0;j<da.b.columns;j++)
	if ((!is_zero) || (!da.s.value[i][j].is_zero()))
	  {
	    tempbfl.assign(da.s.value[i][j]);
	    shift_right(tempbfl, tempbfl, da.d.bit_factor);
	    tempbfl.doublify(dblvalue[i][j]);
	    is_zero=false;
	  }
	else
	  dblvalue[i][j]=0.0;
      if (is_zero)
	{
	  da.b.rank--;
	  for (fcl(j)=i;j<da.b.rank;j++)
	    {
	      tempP=(void *)dblvalue[j];
	      dblvalue[j]=dblvalue[j+1];
	      dblvalue[j+1]=(double *)tempP;
	      tempP=(void *)da.s.value[j];
	      da.s.value[j]=da.s.value[j+1];
	      da.s.value[j+1]=(bigint *)tempP;
	    }
	}
      else
        i++;
    }
}

LATTICE_INLINE bool gensys_modules<bigint, double, VariationI>::
E_convert_vector_A(dense_alg<bigint>& da, double** dblvalue, 
		   const lidia_size_t k)
{
  is_zero=true;
  for (fcl(i)=0;i<da.b.columns;i++)
    if ((!is_zero) || (!da.s.value[k][i].is_zero()))
      {
	tempbfl.assign(da.s.value[k][i]);
	shift_right(tempbfl, tempbfl, da.d.bit_factor);
	tempbfl.doublify(dblvalue[k][i]);
	is_zero=false;
      }
    else
      dblvalue[k][i]=0.0;
  if (is_zero)
    {
      da.b.rank--;
      for (fcl(i)=k;i<da.b.rank;i++)
	{
	  tempP=(void *)dblvalue[i];
	  dblvalue[i]=dblvalue[i+1];
	  dblvalue[i+1]=(double *)tempP;
	  tempP=(void *)da.s.value[i];
	  da.s.value[i]=da.s.value[i+1];
	  da.s.value[i+1]=(bigint *)tempP;
	}
      return(true);
    }
  return(false);
}

LATTICE_INLINE void gensys_modules<bigint, xdouble, VariationI>::
E_convert_lattice_A(dense_alg<bigint>& da, xdouble** xdblvalue)
{
  for (fcl(i)=0;i<da.b.rank;)
    {
      is_zero=true;
      for (fcl(j)=0;j<da.b.columns;j++)
	if ((!is_zero) || (!da.s.value[i][j].is_zero()))
	  {
	    tempbfl.assign(da.s.value[i][j]);
	    shift_right(tempbfl, tempbfl, da.d.bit_factor);
	    tempbfl.xdoublify(xdblvalue[i][j]);
	    is_zero=false;
	  }
	else
	  xdblvalue[i][j]=0.0;
      if (is_zero)
	{
	  da.b.rank--;
	  for (fcl(j)=i;j<da.b.rank;j++)
	    {
	      tempP=(void *)xdblvalue[j];
	      xdblvalue[j]=xdblvalue[j+1];
	      xdblvalue[j+1]=(xdouble *)tempP;
	      tempP=(void *)da.s.value[j];
	      da.s.value[j]=da.s.value[j+1];
	      da.s.value[j+1]=(bigint *)tempP;
	    }
	}
      else
        i++;
    }
}

LATTICE_INLINE bool gensys_modules<bigint, xdouble, VariationI>::
E_convert_vector_A(dense_alg<bigint>& da, xdouble** xdblvalue, 
		   const lidia_size_t k)
{
  is_zero=true;
  for (fcl(i)=0;i<da.b.columns;i++)
    if ((!is_zero) || (!da.s.value[k][i].is_zero()))
      {
	tempbfl.assign(da.s.value[k][i]);
	shift_right(tempbfl, tempbfl, da.d.bit_factor);
	tempbfl.xdoublify(xdblvalue[k][i]);
	is_zero=false;
      }
    else
      xdblvalue[k][i]=0.0;
  if (is_zero)
    {
      da.b.rank--;
      for (fcl(i)=k;i<da.b.rank;i++)
	{
	  tempP=(void *)xdblvalue[i];
	  xdblvalue[i]=xdblvalue[i+1];
	  xdblvalue[i+1]=(xdouble *)tempP;
	  tempP=(void *)da.s.value[i];
	  da.s.value[i]=da.s.value[i+1];
	  da.s.value[i+1]=(bigint *)tempP;
	}
      return(true);
    }
  return(false);
}

LATTICE_INLINE void gensys_modules<bigint, bigfloat, VariationI>::
E_convert_lattice_A(dense_alg<bigint>& da, bigfloat** bflvalue)
{
  for (fcl(i)=0;i<da.b.rank;)
    {
      is_zero=true;
      for (fcl(j)=0;j<da.b.columns;j++)
	if ((!is_zero) || (!da.s.value[i][j].is_zero()))
	  {
	    bi_bit_len=da.s.value[i][j].bit_length();
	    if (bi_bit_len > da.d.cut_bit_prec)
	      {
		bit_diff=bi_bit_len-da.d.cut_bit_prec;
		shift_right(tempbin, da.s.value[i][j], bit_diff);
		bflvalue[i][j].assign(tempbin);
		shift_left(bflvalue[i][j], bflvalue[i][j], bit_diff);
	      }
	    else
	      bflvalue[i][j].assign(da.s.value[i][j]);
	    shift_right(bflvalue[i][j], bflvalue[i][j], da.d.bit_factor);
	    is_zero=false;
	  }
	else
	  bflvalue[i][j].assign_zero();
      if (is_zero)
	{
	  da.b.rank--;
	  for (fcl(j)=i;j<da.b.rank;j++)
	    {
	      tempP=(void *)bflvalue[j];
	      bflvalue[j]=bflvalue[j+1];
	      bflvalue[j+1]=(bigfloat *)tempP;
	      tempP=(void *)da.s.value[j];
	      da.s.value[j]=da.s.value[j+1];
	      da.s.value[j+1]=(bigint *)tempP;
	    }
	}
      else
        i++;
    }
}

LATTICE_INLINE bool gensys_modules<bigint, bigfloat, VariationI>::
E_convert_vector_A(dense_alg<bigint>& da, bigfloat** bflvalue, 
		   const lidia_size_t k)
{
  is_zero=true;
  for (fcl(i)=0;i<da.b.columns;i++)
    if ((!is_zero) || (!da.s.value[k][i].is_zero()))
      {
	bi_bit_len=da.s.value[k][i].bit_length();
	if (bi_bit_len > da.d.cut_bit_prec)
	  {
	    bit_diff=bi_bit_len-da.d.cut_bit_prec;
	    shift_right(tempbin, da.s.value[k][i], bit_diff);
	    bflvalue[k][i].assign(tempbin);
	    shift_left(bflvalue[k][i], bflvalue[k][i], bit_diff);
	  }
	else
	  bflvalue[k][i].assign(da.s.value[k][i]);
	shift_right(bflvalue[k][i], bflvalue[k][i], da.d.bit_factor);
	is_zero=false;
      }
    else
      bflvalue[k][i].assign_zero();
  if (is_zero)
    {
      da.b.rank--;
      for (fcl(i)=k;i<da.b.rank;i++)
	{
	  tempP=(void *)bflvalue[i];
	  bflvalue[i]=bflvalue[i+1];
	  bflvalue[i+1]=(bigfloat *)tempP;
	  tempP=(void *)da.s.value[i];
	  da.s.value[i]=da.s.value[i+1];
	  da.s.value[i+1]=(bigint *)tempP;
	}
      return(true);
    }
  return(false);
}
//
// End of  
// 	     * base_modules<bigint,{double,xdouble,bigfloat},VariationI>
// 	     * basis_modules<bigint,{double,xdouble,bigfloat},VariationI>
// 	     * gensys_modules<bigint,{double,xdouble,bigfloat},VariationI>
//

//
// Code for 
// 	     * base_modules<bigfloat,{double,xdouble,bigfloat},Normal>
// 	     * basis_modules<bigfloat,{double,xdouble,bigfloat},Normal>
// 	     * gensys_modules<bigfloat,{double,xdouble,bigfloat},Normal>
//
LATTICE_INLINE void base_modules<bigfloat, double, Normal>::
E_convert_value_A(dense_alg<bigfloat>&, double& d, const bigfloat& bfl)
{
  bfl.doublify(d);
}

LATTICE_INLINE bool base_modules<bigfloat, double, Normal>::
A_convert_value_E_bound(dense_alg<bigfloat>&, bigfloat& bfl, const double& dbl, 
		        const double& bound) 
{
  if (fabs(dbl) > bound)
    {
      bfl.assign(dbl);
      return (true);
    }
  else
    {
      bfl.assign((sdigit )dbl);
      return (false);
    }
}

LATTICE_INLINE void base_modules<bigfloat, xdouble, Normal>::
E_convert_value_A(dense_alg<bigfloat>&, xdouble& xd, const bigfloat& bfl)
{
  bfl.xdoublify(xd);
}

LATTICE_INLINE bool base_modules<bigfloat, xdouble, Normal>::
A_convert_value_E_bound(dense_alg<bigfloat>&, bigfloat& bfl, const xdouble& xdbl, 
		        const xdouble& bound) 
{
  bfl.assign(xdbl);
  if (fabs(xdbl) > bound)
    return (true);
  return (false);
}

LATTICE_INLINE void base_modules<bigfloat, bigfloat, Normal>::
E_convert_value_A(dense_alg<bigfloat>& da, bigfloat& bfla, const bigfloat& bfl) 
{
  bigfloat::precision(da.d.approx_prec);
  mant.assign(bfl.mantissa());
  expo=bfl.exponent();
  bi_bit_len=mant.bit_length();
  if (bi_bit_len > da.d.cut_bit_prec)
    {
      bit_diff=bi_bit_len-da.d.cut_bit_prec;
      shift_right(mant, mant, bit_diff);
      bfla.assign(mant);
      shift_left(bfla, bfla, bit_diff);
    }
  else
    bfla.assign(mant);
  shift_left(bfla, bfla, expo);
  bigfloat::precision(da.d.exact_prec);
}

LATTICE_INLINE bool base_modules<bigfloat, bigfloat, Normal>::
A_convert_value_E_bound(dense_alg<bigfloat>&, bigfloat& bfla, 
			const bigfloat& bfl, const bigfloat& bound) 
{
  bfla.assign(bfl);
  if (abs(bfl).compare(bound) > 0)
    return (true);
  return (false);
} 

LATTICE_INLINE void basis_modules<bigfloat, double, Normal>::
E_convert_lattice_A(dense_alg<bigfloat>& da, double** dblvalue)
{
  for (fcl(i)=0;i<da.b.rows;i++)
    for (fcl(j)=0;j<da.b.columns;j++)
      da.s.value[i][j].doublify(dblvalue[i][j]);
}

LATTICE_INLINE bool basis_modules<bigfloat, double, Normal>::
E_convert_vector_A(dense_alg<bigfloat>& da, double **dblvalue, const lidia_size_t k)
{
  for (fcl(i)=0;i<da.b.columns;i++)
    da.s.value[k][i].doublify(dblvalue[k][i]);
  return(false);
}

LATTICE_INLINE void basis_modules<bigfloat, xdouble, Normal>::
E_convert_lattice_A(dense_alg<bigfloat>& da, xdouble** xdblvalue)
{
  for (fcl(i)=0;i<da.b.rows;i++)
    for (fcl(j)=0;j<da.b.columns;j++)
      da.s.value[i][j].xdoublify(xdblvalue[i][j]);
}

LATTICE_INLINE bool basis_modules<bigfloat, xdouble, Normal>::
E_convert_vector_A(dense_alg<bigfloat>& da, xdouble **xdblvalue, const lidia_size_t k)
{
  for (fcl(i)=0;i<da.b.columns;i++)
    da.s.value[k][i].xdoublify(xdblvalue[k][i]);
  return(false);
}

LATTICE_INLINE void basis_modules<bigfloat, bigfloat, Normal>::
E_convert_lattice_A(dense_alg<bigfloat>& da, bigfloat** bflvalue)
{
  bigfloat::precision(da.d.approx_prec);
  for (fcl(i)=0;i<da.b.rows;i++)
    for (fcl(j)=0;j<da.b.columns;j++)
      {
	mant.assign(da.s.value[i][j].mantissa());
	expo=da.s.value[i][j].exponent();
	bi_bit_len=mant.bit_length();
	if (bi_bit_len > da.d.cut_bit_prec)
	  {
	    bit_diff=bi_bit_len-da.d.cut_bit_prec;
	    shift_right(mant, mant, bit_diff);
	    bflvalue[i][j].assign(mant);
	    shift_left(bflvalue[i][j], bflvalue[i][j], bit_diff);
	  }
	else
	  bflvalue[i][j].assign(mant);
	shift_left(bflvalue[i][j], bflvalue[i][j], expo);
      }
  bigfloat::precision(da.d.exact_prec);
}

LATTICE_INLINE bool basis_modules<bigfloat, bigfloat, Normal>::
E_convert_vector_A(dense_alg<bigfloat>& da, bigfloat** bflvalue, 
		   const lidia_size_t k)
{
  bigfloat::precision(da.d.approx_prec);
  for (fcl(i)=0;i<da.b.columns;i++)
    {
      mant.assign(da.s.value[k][i].mantissa());
      expo=da.s.value[k][i].exponent();
      bi_bit_len=mant.bit_length();
      if (bi_bit_len > da.d.cut_bit_prec)
	{
	  bit_diff=bi_bit_len-da.d.cut_bit_prec;
	  shift_right(mant, mant, bit_diff);
	  bflvalue[k][i].assign(mant);
	  shift_left(bflvalue[k][i], bflvalue[k][i], bit_diff);
	}
      else
	bflvalue[k][i].assign(mant);
      shift_left(bflvalue[k][i], bflvalue[k][i], expo);
    }
  bigfloat::precision(da.d.exact_prec);
  return (false);
}

LATTICE_INLINE void gensys_modules<bigfloat, double, Normal>::
E_convert_lattice_A(dense_alg<bigfloat>& da, double** dblvalue)
{
  for (fcl(i)=0;i<da.b.rank;)
    {
      is_zero=true;
      for (fcl(j)=0;j<da.b.columns;j++)
	if ((!is_zero) || (!da.s.value[i][j].is_zero()))
	  {
	    da.s.value[i][j].doublify(dblvalue[i][j]);
	    is_zero=false;
	  }
	else
	  dblvalue[i][j]=0.0;
      if (is_zero)
	{
	  da.b.rank--;
	  for (fcl(j)=i;j<da.b.rank;j++)
	    {
	      tempP=(void *)dblvalue[j];
	      dblvalue[j]=dblvalue[j+1];
	      dblvalue[j+1]=(double *)tempP;
	      tempP=(void *)da.s.value[j];
	      da.s.value[j]=da.s.value[j+1];
	      da.s.value[j+1]=(bigfloat *)tempP;
	    }
	}
      else
        i++;
    }
}

LATTICE_INLINE bool gensys_modules<bigfloat, double, Normal>::
E_convert_vector_A(dense_alg<bigfloat>& da, double** dblvalue, 
		   const lidia_size_t k)
{
  is_zero=true;
  for (fcl(i)=0;i<da.b.columns;i++)
    if ((!is_zero) || (!da.s.value[k][i].is_zero()))
      {
	da.s.value[k][i].doublify(dblvalue[k][i]);
	is_zero=false;
      }
    else
      dblvalue[k][i]=0.0;
  if (is_zero)
    {
      da.b.rank--;
      for (fcl(i)=k;i<da.b.rank;i++)
	{
	  tempP=(void *)dblvalue[i];
	  dblvalue[i]=dblvalue[i+1];
	  dblvalue[i+1]=(double *)tempP;
	  tempP=(void *)da.s.value[i];
	  da.s.value[i]=da.s.value[i+1];
	  da.s.value[i+1]=(bigfloat *)tempP;
	}
      return(true);
    }
  return(false);
}

LATTICE_INLINE void gensys_modules<bigfloat, xdouble, Normal>::
E_convert_lattice_A(dense_alg<bigfloat>& da, xdouble** xdblvalue)
{
  for (fcl(i)=0;i<da.b.rank;)
    {
      is_zero=true;
      for (fcl(j)=0;j<da.b.columns;j++)
	if ((!is_zero) || (!da.s.value[i][j].is_zero()))
	  {
	    da.s.value[i][j].xdoublify(xdblvalue[i][j]);
	    is_zero=false;
	  }
	else
	  xdblvalue[i][j]=0.0;
      if (is_zero)
	{
	  da.b.rank--;
	  for (fcl(j)=i;j<da.b.rank;j++)
	    {
	      tempP=(void *)xdblvalue[j];
	      xdblvalue[j]=xdblvalue[j+1];
	      xdblvalue[j+1]=(xdouble *)tempP;
	      tempP=(void *)da.s.value[j];
	      da.s.value[j]=da.s.value[j+1];
	      da.s.value[j+1]=(bigfloat *)tempP;
	    }
	}
      else
        i++;
    }
}

LATTICE_INLINE bool gensys_modules<bigfloat, xdouble, Normal>::
E_convert_vector_A(dense_alg<bigfloat>& da, xdouble** xdblvalue, 
		   const lidia_size_t k)
{
  is_zero=true;
  for (fcl(i)=0;i<da.b.columns;i++)
    if ((!is_zero) || (!da.s.value[k][i].is_zero()))
      {
	da.s.value[k][i].xdoublify(xdblvalue[k][i]);
	is_zero=false;
      }
    else
      xdblvalue[k][i]=0.0;
  if (is_zero)
    {
      da.b.rank--;
      for (fcl(i)=k;i<da.b.rank;i++)
	{
	  tempP=(void *)xdblvalue[i];
	  xdblvalue[i]=xdblvalue[i+1];
	  xdblvalue[i+1]=(xdouble *)tempP;
	  tempP=(void *)da.s.value[i];
	  da.s.value[i]=da.s.value[i+1];
	  da.s.value[i+1]=(bigfloat *)tempP;
	}
      return(true);
    }
  return(false);
}

LATTICE_INLINE void gensys_modules<bigfloat, bigfloat, Normal>::
E_convert_lattice_A(dense_alg<bigfloat>& da, bigfloat** bflvalue)
{
  bigfloat::precision(da.d.approx_prec);
  for (fcl(i)=0;i<da.b.rank;)
    {
      is_zero=true;
      for (fcl(j)=0;j<da.b.columns;j++)
	if ((!is_zero) || (!da.s.value[i][j].is_zero()))
	  {
	    mant.assign(da.s.value[i][j].mantissa());
	    expo=da.s.value[i][j].exponent();
	    bi_bit_len=mant.bit_length();
	    if (bi_bit_len > da.d.cut_bit_prec)
	      {
		bit_diff=bi_bit_len-da.d.cut_bit_prec;
		shift_right(mant, mant, bit_diff);
		bflvalue[i][j].assign(mant);
		shift_left(bflvalue[i][j], bflvalue[i][j], bit_diff);
	      }
	    else
	      bflvalue[i][j].assign(mant);
	    shift_left(bflvalue[i][j], bflvalue[i][j], expo);
	    is_zero=false;
	  }
	else
	  bflvalue[i][j].assign_zero();
      if (is_zero)
	{
	  da.b.rank--;
	  for (fcl(j)=i;j<da.b.rank;j++)
	    {
	      tempP=(void *)bflvalue[j];
	      bflvalue[j]=bflvalue[j+1];
	      bflvalue[j+1]=(bigfloat *)tempP;
	      tempP=(void *)da.s.value[j];
	      da.s.value[j]=da.s.value[j+1];
	      da.s.value[j+1]=(bigfloat *)tempP;
	    }
	}
      else
        i++;
    }
  bigfloat::precision(da.d.exact_prec);
}

LATTICE_INLINE bool gensys_modules<bigfloat, bigfloat, Normal>::
E_convert_vector_A(dense_alg<bigfloat>& da, bigfloat** bflvalue, 
		   const lidia_size_t k)
{
  bigfloat::precision(da.d.approx_prec);
  is_zero=true;
  for (fcl(i)=0;i<da.b.columns;i++)
    if ((!is_zero) || (!da.s.value[k][i].is_zero()))
      {
	mant.assign(da.s.value[k][i].mantissa());
	expo=da.s.value[k][i].exponent();
	bi_bit_len=mant.bit_length();
	if (bi_bit_len > da.d.cut_bit_prec)
	  {
	    bit_diff=bi_bit_len-da.d.cut_bit_prec;
	    shift_right(mant, mant, bit_diff);
	    bflvalue[k][i].assign(mant);
	    shift_left(bflvalue[k][i], bflvalue[k][i], bit_diff);
	  }
	else
	  bflvalue[k][i].assign(mant);
	shift_left(bflvalue[k][i], bflvalue[k][i], expo);
	is_zero=false;
      }
    else
      bflvalue[k][i].assign_zero();
  if (is_zero)
    {
      da.b.rank--;
      for (fcl(i)=k;i<da.b.rank;i++)
	{
	  tempP=(void *)bflvalue[i];
	  bflvalue[i]=bflvalue[i+1];
	  bflvalue[i+1]=(bigfloat *)tempP;
	  tempP=(void *)da.s.value[i];
	  da.s.value[i]=da.s.value[i+1];
	  da.s.value[i+1]=(bigfloat *)tempP;
	}
      bigfloat::precision(da.d.exact_prec);
      return(true);
    }
  bigfloat::precision(da.d.exact_prec);
  return(false);
}
//
// End of  
// 	     * base_modules<bigfloat,{double,xdouble,bigfloat},Normal>
// 	     * basis_modules<bigfloat,{double,xdouble,bigfloat},Normal>
// 	     * gensys_modules<bigfloat,{double,xdouble,bigfloat},Normal>
//

#endif
