[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [tyndur-devel] [PATCH 1/4] libc: strtod



On Wed, May 26 22:34, Kevin Wolf wrote:
> + libc: Eine halbe Implementierung von strtod
> 
> Signed-off-by: Kevin Wolf <kevin@xxxxxxxxxx>
> ---
>  src/include/stdlib.h |    4 +++
>  src/lib/string.c     |   70 ++++++++++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 74 insertions(+), 0 deletions(-)
> 
> diff --git a/src/include/stdlib.h b/src/include/stdlib.h
> index d56d879..873dda8 100644
> --- a/src/include/stdlib.h
> +++ b/src/include/stdlib.h
> @@ -58,6 +58,10 @@ long strtol(const char* str, char** endptr, int base);
>  unsigned long strtoul(const char *nptr, char **endptr, int base);
>  unsigned long long strtoull(const char *nptr, char **endptr, int base);
>  
> +long double strtold(const char* nptr, char** end);
> +double strtod(const char* nptr, char** end);
> +float strtof(const char* nptr, char** end);
> +
>  int atoi(const char* s);
>  long atol(const char* str);
>  
> diff --git a/src/lib/string.c b/src/lib/string.c
> index f6f4132..d6d662f 100644
> --- a/src/lib/string.c
> +++ b/src/lib/string.c
> @@ -198,6 +198,76 @@ long atol(const char *str)
>      return result;
>  }
>  
> +long double strtold(const char* nptr, char** end)
> +{
> +    long double result = 0;
> +    long double frac = 0;
> +    long double base = 10.0;
> +    int neg = 0;
> +    int decimal = 0;
> +
> +    // Leerzeichen am Anfang muessen ignoriert werden
> +    while (isspace(*nptr)) {
> +        nptr++;
> +    }
> +
> +    // Vorzeichen
> +    if (*nptr == '+') {
> +        nptr++;
> +    } else if (*nptr == '-') {
> +        neg = 1;
> +        nptr++;
> +    }
> +
> +    // Ergebnis berechnen
> +    result = 0;
> +    while (*nptr) {
> +        switch (*nptr) {
> +            case '0' ... '9':
> +                if (*nptr - '0' > base - 1) {
> +                    goto out;
> +                }
> +                if (!decimal) {
> +                    result = result * base + (*nptr - '0');
> +                } else {
> +                    frac = frac + ((*nptr - '0') / base);
> +                    base *= 10.0;
> +                }
> +                break;
> +
> +            case '.':
> +                decimal = 1;
> +                break;
> +
> +            case 'E':
> +            case 'e':
> +                // TODO
> +
> +            default:
> +                goto out;
> +        }
> +        nptr++;
> +    }
> +out:
> +    result += frac;
> +
> +    if (end != NULL) {
> +        *end = (char*) nptr;

Hm bist du da nicht off by one mit end? Laut manpage soll das auf das
letzte konvertierte Zeichen zeigen.

> +    }
> +
> +    return neg ? - result : result;
> +}
> +
> +double strtod(const char* nptr, char** end)
> +{
> +    return strtold(nptr, end);
> +}
> +
> +float strtof(const char* nptr, char** end)
> +{
> +    return strtold(nptr, end);
> +}
> +
>  /**
>   * Zwei Strings unter Beruecksichtigung des aktuellen locales vergleichen
>   */

Abgesehen davon sieht das gut aus, glaube ich. Wenn du das also
korrigierst, oder ich das falsch verstehe, kann das rein. ;-)

Acked-by: Antoine Kaufmann <toni@xxxxxxxxxx>

-- 
Antoine Kaufmann
<toni@xxxxxxxxxxxxxxxx>

Attachment: pgpR9pBI0byQ6.pgp
Description: PGP signature