Question

I need to convert a floating point number to the following nonstandard format: "a floating point number F (in standard decimal exponential format), followed by the string times 10 to the power, followed by an integer K."

Is there a way to extract the exponent from e% or a function similar to frexp()?

E.g.: 3349.25 should be "3.34925 times 10 to the power 3"

Was it helpful?

Solution

You can implement a decimal equivalent of frexp yourself quite easily. The code you need looks something like this:

int exponent = (int)log10(fabs(d));
double mantissa = d / pow(10, exponent);
printf("%f X 10^%d\n", mantissa, exponent);

First we determine the exponent by taking the base-10 logarithm of the absolute value of your number. (We need fabs because log10 requires a positive argument.) The cast rounds towards zero, which is, conveniently, what we need. Then we normalize the mantissa by dividing.

This doesn't handle d==0 (or infinity or NaN), the division will introduce some error into the result, and I haven't tested it with small numbers or negative numbers, but this should give you something to start from.

OTHER TIPS

I like the OP approach to let printf(), using the "%e" format, to do the heavy lifting.

There are many issues with double to string conversion that existing functions already handle nicely. (INF, Nan, -0, rounding, negatives). OP use of frexp(), power() typically have troubles near values a power of 10 do to rounding and and finite precision.

OP is fuzzy on how much precision given only 1 example. power(0.5, 100) would need 100 digits. Let's limit it to DBL_DIG, rather than use the %e default of 6. (which is really 7 digits, just 6 after the DP.)

char *Heyhey_Notation(char *dest, double x) {
  static const char Times[] = " times 10 to the power ";
  char buffer[3 + DBL_DIG + sizeof(Times) + 20 + 1];

  sprintf(buffer, "%.*e", DBL_DIG, x);
  char *e = strchr(buffer, 'e');  // find exponent position
  if (e) {
    char *zero = e;
    while (zero[-1] == '0') zero--; 
    *zero = '\0'; // OP wants excess zeros trimmed.
    int power = atoi(&e[1]);  // trim excess zeros by converting to int
    sprintf(dest, "%s%s%d", buffer, Times, power);
    }
  else {
    strcpy(dest, buffer);
  }
  return dest;
}

int main() {
  char buf[100];
  puts(Heyhey_Notation(buf, 3349.25));
  puts(Heyhey_Notation(buf, -0.0));
  puts(Heyhey_Notation(buf, 123));
  puts(Heyhey_Notation(buf, -1234567890.0/9999999999.0));
  puts(Heyhey_Notation(buf, -1/0.0));
  puts(Heyhey_Notation(buf, atof("nan")));
  return 0;
}

3.34925 times 10 to the power 3
-0. times 10 to the power 0
1.23 times 10 to the power 2
-1.234567890123457 times 10 to the power -1
-inf
nan
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top