cc89strtod

strtod with base parameter


I don't want to unnecessarily re-invent the wheel, but I have been looking for the functionality of strtod but with a base parameter (2,8,10,16). (I know strtoul allows a base parameter but I'm looking for return type double). Any advice / pointers in the right direction? Thanks.


Solution

  • For arbitrary base, this is a hard problem, but as long as your base is a power of two, the plain naive algorithm will work just fine.

    strtod (in C99) supports hex floats in the same format as the C language's hex float constants. 0x prefix is required, p separates the exponent, and the exponent is in base 10 and represents a power of 2. If you need to support pre-C99 libraries, you'll have no such luck. But since you need base 2/4/8 too, it's probably just best to roll your own anyway.

    Edit: An outline of the naive algorithm:

    1. Start with a floating point accumulator variable (double or whatever, as you prefer) initialized to 0.
    2. Starting from the leftmost digit, and up to the radix point, for each character you process, multiply the accumulator by the base and add the value of the character as a digit.
    3. After the radix point, start a new running place-value variable, initially 1/base. On each character you process, add the digit value times the place-value variable, and then divide the place-value variable by base.
    4. If you see the exponent character, read the number following it as an integer and use one of the standard library functions to scale a floating point number by a power of 2.

    If you want to handle potentially rounding up forms that have too many digits, you have to work out that logic once you exceed the number of significant places in step 2 or 3. Otherwise you can ignore that.