"Keith Thompson" <ks***@mib.orgwrote in message

news:ln************@nuthaus.mib.org...

"Dann Corbit" <dc*****@connx.comwrites:
>Use sscanf() instead.

It's a lot better to boot.

Instead of what? Please provide context.

sscanf() invokes undefined behavior if the input string cannot be

represented in the specified type.

Good point. Maybe something like this could be used as a starting point.

It's not very robust for error checking, but it could easily be improved to

a useful state.

#include <stdlib.h>

#include <float.h>

typedef enum {FALSE=0,TRUE=1} BOOL;

BOOL asciiToLongDouble(const char * const numberString, long double

*pldNumber)

{

/* Convert ASCII string to long double data type. */

long double ldReturnValue;

long double ldOneTenth = 0.1e0L;

long double ldTen = 10.0e0L;

long double ldZero = 0.0e0L;

BOOL bFoundDigits = FALSE;

BOOL bIsNegative = FALSE;

const char * pszNum;

/* Check pointers. */

if (pldNumber == NULL) {

return FALSE;

}

if (numberString == NULL) {

*pldNumber = ldZero;

return FALSE;

}

ldReturnValue = ldZero;

pszNum = numberString;

/* Advance past white space. */

while ((*pszNum == ' ') || (*pszNum == '\t'))

pszNum++;

/* Check for sign. */

if (*pszNum == '+')

pszNum++;

else if (*pszNum == '-')

{

bIsNegative = TRUE;

pszNum++;

}

/* Calculate the integer part. */

while ((*pszNum >= '0') && (*pszNum <= '9'))

{

bFoundDigits = TRUE;

ldReturnValue *= ldTen;

ldReturnValue += *pszNum - '0';

pszNum++;

}

/* Calculate the fractional part. */

if (*pszNum == '.')

{

long double ldScale = ldOneTenth;

pszNum++;

while ((*pszNum >= '0') && (*pszNum <= '9'))

{

bFoundDigits = TRUE;

ldReturnValue += ldScale * (*pszNum - '0');

pszNum++;

ldScale *= ldOneTenth;

}

}

/* If this is not a number, return error condition. */

if (!bFoundDigits)

{

*pldNumber = ldZero;

return FALSE;

}

/* If all digits of integer & fractional part are 0, return 0.0 */

if (ldReturnValue == ldZero)

{

*pldNumber = ldZero;

return TRUE; /* Not an error condition, and no need to continue. */

}

/* Process the exponent (if any) */

if ((*pszNum == 'e') || (*pszNum == 'E'))

{

BOOL bIsNegativeExponent = FALSE;

BOOL bGetOut = FALSE;

long lIndex;

long lExponent = 0;

long double ldTooBigTest = LDBL_MAX*ldOneTenth;

long double ldTooSmallTest= LDBL_MIN*ldTen;

pszNum++;

if (*pszNum == '+')

pszNum++;

else if (*pszNum == '-')

{

pszNum++;

bIsNegativeExponent = TRUE;

}

/* What if the exponent is empty? Return the current result. */

if ((*pszNum < '0') || (*pszNum '9'))

{

if (bIsNegative)

ldReturnValue = -ldReturnValue;

*pldNumber = ldReturnValue;

return (TRUE);

}

/* Convert char exponent to number <= 2 billion. */

while ((*pszNum >= '0') && (*pszNum <= '9') && (lExponent <

200000000))

{

lExponent *= 10;

lExponent += *pszNum - '0';

pszNum++;

}

/* Compensate for the exponent. */

if (bIsNegativeExponent)

{

for (lIndex = 1; lIndex <= lExponent && !bGetOut; lIndex++)

if (ldReturnValue < ldTooSmallTest)

{

bGetOut = TRUE;

ldReturnValue = LDBL_MIN;

}

else

ldReturnValue *= ldOneTenth;

}

else

for (lIndex = 1; lIndex <= lExponent && !bGetOut; lIndex++)

{

if (ldReturnValue ldTooBigTest)

{

bGetOut = TRUE;

ldReturnValue = LDBL_MAX;

}

else

ldReturnValue *= ldTen;

}

}

if (bIsNegative)

ldReturnValue = -ldReturnValue;

*pldNumber = ldReturnValue;

return (TRUE);

}

--

Keith Thompson (The_Other_Keith) ks***@mib.org

<http://www.ghoti.net/~kst>

San Diego Supercomputer Center <*>

<http://users.sdsc.edu/~kst>

We must do something. This is something. Therefore, we must do this.