📄 epd.c
字号:
/**CFile*********************************************************************** FileName [epd.c] PackageName [epd] Synopsis [Arithmetic functions with extended double precision.] Description [] SeeAlso [] Author [In-Ho Moon] 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.] Revision [$Id: epd.c,v 1.1.1.1 2003/02/24 22:23:57 wjiang Exp $]******************************************************************************/#include <stdio.h>#include <stdlib.h>#include <string.h>#include <math.h>#include "util.h"#include "epd.h"/**Function******************************************************************** Synopsis [Allocates an EpDouble struct.] Description [Allocates an EpDouble struct.] SideEffects [] SeeAlso []******************************************************************************/EpDouble *EpdAlloc(){ EpDouble *epd; epd = ALLOC(EpDouble, 1); return(epd);}/**Function******************************************************************** Synopsis [Compares two EpDouble struct.] Description [Compares two EpDouble struct.] SideEffects [] SeeAlso []******************************************************************************/intEpdCmp(const char *key1, const char *key2){ EpDouble *epd1 = (EpDouble *) key1; EpDouble *epd2 = (EpDouble *) key2; if (epd1->type.value != epd2->type.value || epd1->exponent != epd2->exponent) { return(1); } return(0);}/**Function******************************************************************** Synopsis [Frees an EpDouble struct.] Description [Frees an EpDouble struct.] SideEffects [] SeeAlso []******************************************************************************/voidEpdFree(EpDouble *epd){ FREE(epd);}/**Function******************************************************************** Synopsis [Multiplies two arbitrary precision double values.] Description [Multiplies two arbitrary precision double values.] SideEffects [] SeeAlso []******************************************************************************/voidEpdGetString(EpDouble *epd, char *str){ double value; int exponent; char *pos; if (IsNanDouble(epd->type.value)) { sprintf(str, "NaN"); return; } else if (IsInfDouble(epd->type.value)) { if (epd->type.bits.sign == 1) sprintf(str, "-Inf"); else sprintf(str, "Inf"); return; } assert(epd->type.bits.exponent == EPD_MAX_BIN || epd->type.bits.exponent == 0); EpdGetValueAndDecimalExponent(epd, &value, &exponent); sprintf(str, "%e", value); pos = strstr(str, "e"); if (exponent >= 0) { if (exponent < 10) sprintf(pos + 1, "+0%d", exponent); else sprintf(pos + 1, "+%d", exponent); } else { exponent *= -1; if (exponent < 10) sprintf(pos + 1, "-0%d", exponent); else sprintf(pos + 1, "-%d", exponent); }}/**Function******************************************************************** Synopsis [Converts double to EpDouble struct.] Description [Converts double to EpDouble struct.] SideEffects [] SeeAlso []******************************************************************************/voidEpdConvert(double value, EpDouble *epd){ epd->type.value = value; epd->exponent = 0; EpdNormalize(epd);}/**Function******************************************************************** Synopsis [Multiplies two arbitrary precision double values.] Description [Multiplies two arbitrary precision double values.] SideEffects [] SeeAlso []******************************************************************************/voidEpdMultiply(EpDouble *epd1, double value){ EpDouble epd2; double tmp; int exponent; if (EpdIsNan(epd1) || IsNanDouble(value)) { EpdMakeNan(epd1); return; } else if (EpdIsInf(epd1) || IsInfDouble(value)) { int sign; EpdConvert(value, &epd2); sign = epd1->type.bits.sign ^ epd2.type.bits.sign; EpdMakeInf(epd1, sign); return; } assert(epd1->type.bits.exponent == EPD_MAX_BIN); EpdConvert(value, &epd2); tmp = epd1->type.value * epd2.type.value; exponent = epd1->exponent + epd2.exponent; epd1->type.value = tmp; epd1->exponent = exponent; EpdNormalize(epd1);}/**Function******************************************************************** Synopsis [Multiplies two arbitrary precision double values.] Description [Multiplies two arbitrary precision double values.] SideEffects [] SeeAlso []******************************************************************************/voidEpdMultiply2(EpDouble *epd1, EpDouble *epd2){ double value; int exponent; if (EpdIsNan(epd1) || EpdIsNan(epd2)) { EpdMakeNan(epd1); return; } else if (EpdIsInf(epd1) || EpdIsInf(epd2)) { int sign; sign = epd1->type.bits.sign ^ epd2->type.bits.sign; EpdMakeInf(epd1, sign); return; } assert(epd1->type.bits.exponent == EPD_MAX_BIN); assert(epd2->type.bits.exponent == EPD_MAX_BIN); value = epd1->type.value * epd2->type.value; exponent = epd1->exponent + epd2->exponent; epd1->type.value = value; epd1->exponent = exponent; EpdNormalize(epd1);}/**Function******************************************************************** Synopsis [Multiplies two arbitrary precision double values.] Description [Multiplies two arbitrary precision double values.] SideEffects [] SeeAlso []******************************************************************************/voidEpdMultiply2Decimal(EpDouble *epd1, EpDouble *epd2){ double value; int exponent; if (EpdIsNan(epd1) || EpdIsNan(epd2)) { EpdMakeNan(epd1); return; } else if (EpdIsInf(epd1) || EpdIsInf(epd2)) { int sign; sign = epd1->type.bits.sign ^ epd2->type.bits.sign; EpdMakeInf(epd1, sign); return; } value = epd1->type.value * epd2->type.value; exponent = epd1->exponent + epd2->exponent; epd1->type.value = value; epd1->exponent = exponent; EpdNormalizeDecimal(epd1);}/**Function******************************************************************** Synopsis [Multiplies two arbitrary precision double values.] Description [Multiplies two arbitrary precision double values.] SideEffects [] SeeAlso []******************************************************************************/voidEpdMultiply3(EpDouble *epd1, EpDouble *epd2, EpDouble *epd3){ if (EpdIsNan(epd1) || EpdIsNan(epd2)) { EpdMakeNan(epd1); return; } else if (EpdIsInf(epd1) || EpdIsInf(epd2)) { int sign; sign = epd1->type.bits.sign ^ epd2->type.bits.sign; EpdMakeInf(epd3, sign); return; } assert(epd1->type.bits.exponent == EPD_MAX_BIN); assert(epd2->type.bits.exponent == EPD_MAX_BIN); epd3->type.value = epd1->type.value * epd2->type.value; epd3->exponent = epd1->exponent + epd2->exponent; EpdNormalize(epd3);}/**Function******************************************************************** Synopsis [Multiplies two arbitrary precision double values.] Description [Multiplies two arbitrary precision double values.] SideEffects [] SeeAlso []******************************************************************************/voidEpdMultiply3Decimal(EpDouble *epd1, EpDouble *epd2, EpDouble *epd3){ if (EpdIsNan(epd1) || EpdIsNan(epd2)) { EpdMakeNan(epd1); return; } else if (EpdIsInf(epd1) || EpdIsInf(epd2)) { int sign; sign = epd1->type.bits.sign ^ epd2->type.bits.sign; EpdMakeInf(epd3, sign); return; } epd3->type.value = epd1->type.value * epd2->type.value; epd3->exponent = epd1->exponent + epd2->exponent; EpdNormalizeDecimal(epd3);}/**Function******************************************************************** Synopsis [Divides two arbitrary precision double values.] Description [Divides two arbitrary precision double values.] SideEffects [] SeeAlso []******************************************************************************/voidEpdDivide(EpDouble *epd1, double value){ EpDouble epd2; double tmp; int exponent; if (EpdIsNan(epd1) || IsNanDouble(value)) { EpdMakeNan(epd1); return; } else if (EpdIsInf(epd1) || IsInfDouble(value)) { int sign; EpdConvert(value, &epd2); if (EpdIsInf(epd1) && IsInfDouble(value)) { EpdMakeNan(epd1); } else if (EpdIsInf(epd1)) { sign = epd1->type.bits.sign ^ epd2.type.bits.sign; EpdMakeInf(epd1, sign); } else { sign = epd1->type.bits.sign ^ epd2.type.bits.sign; EpdMakeZero(epd1, sign); } return; } if (value == 0.0) { EpdMakeNan(epd1); return; } assert(epd1->type.bits.exponent == EPD_MAX_BIN); EpdConvert(value, &epd2); tmp = epd1->type.value / epd2.type.value; exponent = epd1->exponent - epd2.exponent; epd1->type.value = tmp; epd1->exponent = exponent; EpdNormalize(epd1);}/**Function******************************************************************** Synopsis [Divides two arbitrary precision double values.] Description [Divides two arbitrary precision double values.] SideEffects [] SeeAlso []******************************************************************************/voidEpdDivide2(EpDouble *epd1, EpDouble *epd2){ double value; int exponent; if (EpdIsNan(epd1) || EpdIsNan(epd2)) { EpdMakeNan(epd1); return; } else if (EpdIsInf(epd1) || EpdIsInf(epd2)) { int sign; if (EpdIsInf(epd1) && EpdIsInf(epd2)) { EpdMakeNan(epd1); } else if (EpdIsInf(epd1)) { sign = epd1->type.bits.sign ^ epd2->type.bits.sign; EpdMakeInf(epd1, sign); } else { sign = epd1->type.bits.sign ^ epd2->type.bits.sign; EpdMakeZero(epd1, sign); } return; } if (epd2->type.value == 0.0) { EpdMakeNan(epd1); return; } assert(epd1->type.bits.exponent == EPD_MAX_BIN);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -