📄 cuddapa.c
字号:
/**CFile*********************************************************************** FileName [cuddApa.c] PackageName [cudd] Synopsis [Arbitrary precision arithmetic functions.] Description [External procedures included in this module: <ul> <li> </ul> Internal procedures included in this module: <ul> <li> () </ul> Static procedures included in this module: <ul> <li> () </ul>] Author [Fabio Somenzi] Copyright [This file was created at the University of Colorado at Boulder. The University of Colorado at Boulder makes no warranty about the suitability of this software for any purpose. It is presented on an AS IS basis.]******************************************************************************/#include "util.h"#include "cuddInt.h"/*---------------------------------------------------------------------------*//* Constant declarations *//*---------------------------------------------------------------------------*//*---------------------------------------------------------------------------*//* Stucture declarations *//*---------------------------------------------------------------------------*//*---------------------------------------------------------------------------*//* Type declarations *//*---------------------------------------------------------------------------*//*---------------------------------------------------------------------------*//* Variable declarations *//*---------------------------------------------------------------------------*/#ifndef lintstatic char rcsid[] DD_UNUSED = "$Id: cuddApa.c,v 1.1.1.1 2003/02/24 22:23:51 wjiang Exp $";#endifstatic DdNode *background, *zero;/*---------------------------------------------------------------------------*//* Macro declarations *//*---------------------------------------------------------------------------*//**AutomaticStart*************************************************************//*---------------------------------------------------------------------------*//* Static function prototypes *//*---------------------------------------------------------------------------*/static DdApaNumber cuddApaCountMintermAux ARGS((DdNode * node, int digits, DdApaNumber max, DdApaNumber min, st_table * table));static enum st_retval cuddApaStCountfree ARGS((char * key, char * value, char * arg));/**AutomaticEnd***************************************************************//*---------------------------------------------------------------------------*//* Definition of exported functions *//*---------------------------------------------------------------------------*//**Function******************************************************************** Synopsis [Finds the number of digits for an arbitrary precision integer.] Description [Finds the number of digits for an arbitrary precision integer given the maximum number of binary digits. The number of binary digits should be positive. Returns the number of digits if successful; 0 otherwise.] SideEffects [None] SeeAlso []******************************************************************************/intCudd_ApaNumberOfDigits( int binaryDigits){ int digits; digits = binaryDigits / DD_APA_BITS; if ((digits * DD_APA_BITS) != binaryDigits) digits++; return(digits);} /* end of Cudd_ApaNumberOfDigits */ /**Function******************************************************************** Synopsis [Allocates memory for an arbitrary precision integer.] Description [Allocates memory for an arbitrary precision integer. Returns a pointer to the allocated memory if successful; NULL otherwise.] SideEffects [None] SeeAlso []******************************************************************************/DdApaNumberCudd_NewApaNumber( int digits){ return(ALLOC(DdApaDigit, digits));} /* end of Cudd_NewApaNumber *//**Function******************************************************************** Synopsis [Makes a copy of an arbitrary precision integer.] Description [Makes a copy of an arbitrary precision integer.] SideEffects [Changes parameter <code>dest</code>.] SeeAlso []******************************************************************************/voidCudd_ApaCopy( int digits, DdApaNumber source, DdApaNumber dest){ int i; for (i = 0; i < digits; i++) { dest[i] = source[i]; }} /* end of Cudd_ApaCopy *//**Function******************************************************************** Synopsis [Adds two arbitrary precision integers.] Description [Adds two arbitrary precision integers. Returns the carry out of the most significant digit.] SideEffects [The result of the sum is stored in parameter <code>sum</code>.] SeeAlso []******************************************************************************/DdApaDigitCudd_ApaAdd( int digits, DdApaNumber a, DdApaNumber b, DdApaNumber sum){ int i; DdApaDoubleDigit partial = 0; for (i = digits - 1; i >= 0; i--) { partial = a[i] + b[i] + DD_MSDIGIT(partial); sum[i] = (DdApaDigit) DD_LSDIGIT(partial); } return(DD_MSDIGIT(partial));} /* end of Cudd_ApaAdd *//**Function******************************************************************** Synopsis [Subtracts two arbitrary precision integers.] Description [Subtracts two arbitrary precision integers. Returns the borrow out of the most significant digit.] SideEffects [The result of the subtraction is stored in parameter <code>diff</code>.] SeeAlso []******************************************************************************/DdApaDigitCudd_ApaSubtract( int digits, DdApaNumber a, DdApaNumber b, DdApaNumber diff){ int i; DdApaDoubleDigit partial = DD_APA_BASE; for (i = digits - 1; i >= 0; i--) { partial = a[i] - b[i] + DD_MSDIGIT(partial) + DD_APA_MASK; diff[i] = (DdApaDigit) DD_LSDIGIT(partial); } return(DD_MSDIGIT(partial) - 1);} /* end of Cudd_ApaSubtract *//**Function******************************************************************** Synopsis [Divides an arbitrary precision integer by a digit.] Description [Divides an arbitrary precision integer by a digit.] SideEffects [The quotient is returned in parameter <code>quotient</code>.] SeeAlso []******************************************************************************/DdApaDigitCudd_ApaShortDivision( int digits, DdApaNumber dividend, DdApaDigit divisor, DdApaNumber quotient){ int i; DdApaDigit remainder; DdApaDoubleDigit partial; remainder = 0; for (i = 0; i < digits; i++) { partial = remainder * DD_APA_BASE + dividend[i]; quotient[i] = (DdApaDigit) (partial/(DdApaDoubleDigit)divisor); remainder = (DdApaDigit) (partial % divisor); } return(remainder);} /* end of Cudd_ApaShortDivision *//**Function******************************************************************** Synopsis [Divides an arbitrary precision integer by an integer.] Description [Divides an arbitrary precision integer by a 32-bit unsigned integer. Returns the remainder of the division. This procedure relies on the assumption that the number of bits of a DdApaDigit plus the number of bits of an unsigned int is less the number of bits of the mantissa of a double. This guarantees that the product of a DdApaDigit and an unsigned int can be represented without loss of precision by a double. On machines where this assumption is not satisfied, this procedure will malfunction.] SideEffects [The quotient is returned in parameter <code>quotient</code>.] SeeAlso [Cudd_ApaShortDivision]******************************************************************************/unsigned intCudd_ApaIntDivision( int digits, DdApaNumber dividend, unsigned int divisor, DdApaNumber quotient){ int i; double partial; unsigned int remainder = 0; double ddiv = (double) divisor; for (i = 0; i < digits; i++) { partial = (double) remainder * DD_APA_BASE + dividend[i]; quotient[i] = (DdApaDigit) (partial / ddiv); remainder = (unsigned int) (partial - ((double)quotient[i] * ddiv)); } return(remainder);} /* end of Cudd_ApaIntDivision *//**Function******************************************************************** Synopsis [Shifts right an arbitrary precision integer by one binary place.] Description [Shifts right an arbitrary precision integer by one binary place. The most significant binary digit of the result is taken from parameter <code>in</code>.] SideEffects [The result is returned in parameter <code>b</code>.] SeeAlso []******************************************************************************/voidCudd_ApaShiftRight( int digits, DdApaDigit in, DdApaNumber a, DdApaNumber b){ int i; for (i = digits - 1; i > 0; i--) { b[i] = (a[i] >> 1) | ((a[i-1] & 1) << (DD_APA_BITS - 1)); } b[0] = (a[0] >> 1) | (in << (DD_APA_BITS - 1));} /* end of Cudd_ApaShiftRight *//**Function******************************************************************** Synopsis [Sets an arbitrary precision integer to a one-digit literal.] Description [Sets an arbitrary precision integer to a one-digit literal.] SideEffects [The result is returned in parameter <code>number</code>.] SeeAlso []******************************************************************************/voidCudd_ApaSetToLiteral( int digits, DdApaNumber number, DdApaDigit literal){ int i; for (i = 0; i < digits - 1; i++) number[i] = 0; number[digits - 1] = literal;} /* end of Cudd_ApaSetToLiteral *//**Function******************************************************************** Synopsis [Sets an arbitrary precision integer to a power of two.] Description [Sets an arbitrary precision integer to a power of two. If the power of two is too large to be represented, the number is set to 0.] SideEffects [The result is returned in parameter <code>number</code>.] SeeAlso []******************************************************************************/voidCudd_ApaPowerOfTwo( int digits, DdApaNumber number, int power){ int i; int index; for (i = 0; i < digits; i++) number[i] = 0; i = digits - 1 - power / DD_APA_BITS; if (i < 0) return; index = power & (DD_APA_BITS - 1); number[i] = 1 << index;} /* end of Cudd_ApaPowerOfTwo *//**Function******************************************************************** Synopsis [Compares two arbitrary precision integers.] Description [Compares two arbitrary precision integers. Returns 1 if the first number is larger; 0 if they are equal; -1 if the second number is larger.] SideEffects [None] SeeAlso []******************************************************************************/intCudd_ApaCompare( int digitsFirst, DdApaNumber first, int digitsSecond, DdApaNumber second){ int i; int firstNZ, secondNZ; /* Find first non-zero in both numbers. */ for (firstNZ = 0; firstNZ < digitsFirst; firstNZ++) if (first[firstNZ] != 0) break; for (secondNZ = 0; secondNZ < digitsSecond; secondNZ++) if (second[secondNZ] != 0) break; if (digitsFirst - firstNZ > digitsSecond - secondNZ) return(1); else if (digitsFirst - firstNZ < digitsSecond - secondNZ) return(-1); for (i = 0; i < digitsFirst - firstNZ; i++) { if (first[firstNZ + i] > second[secondNZ + i]) return(1); else if (first[firstNZ + i] < second[secondNZ + i]) return(-1); } return(0);} /* end of Cudd_ApaCompare *//**Function******************************************************************** Synopsis [Compares the ratios of two arbitrary precision integers to two unsigned ints.] Description [Compares the ratios of two arbitrary precision integers to two unsigned ints. Returns 1 if the first number is larger; 0 if they are equal; -1 if the second number is larger.] SideEffects [None] SeeAlso []******************************************************************************/intCudd_ApaCompareRatios( int digitsFirst, DdApaNumber firstNum, unsigned int firstDen, int digitsSecond, DdApaNumber secondNum, unsigned int secondDen){ int result; DdApaNumber first, second; unsigned int firstRem, secondRem; first = Cudd_NewApaNumber(digitsFirst); firstRem = Cudd_ApaIntDivision(digitsFirst,firstNum,firstDen,first); second = Cudd_NewApaNumber(digitsSecond); secondRem = Cudd_ApaIntDivision(digitsSecond,secondNum,secondDen,second); result = Cudd_ApaCompare(digitsFirst,first,digitsSecond,second); if (result == 0) { if ((double)firstRem/firstDen > (double)secondRem/secondDen) return(1); else if ((double)firstRem/firstDen < (double)secondRem/secondDen) return(-1); } return(result);} /* end of Cudd_ApaCompareRatios *//**Function******************************************************************** Synopsis [Prints an arbitrary precision integer in hexadecimal format.]
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -