开发者

C Checking or Converting Exponents

I have exponents in the represented format of: "1.45e004" or "1.45e-04" or "-1.45e004".

[please note the minus sign in the third one]

Checking (==, !=, >, <, <=, >=, etc) does not work on exponents [incorrect or no results are returned] in their current format.

However, converting an exponent using fabs works for the first two, but not the last one, as fabs removes the minus sign (ergo making the value positive and not negative as it should be).

My questions are thus:

1) Is there a way to convert exponents into absolutes which would include signed values?

[fabs cannot do this]

OR

2) Is there a way [or function(s)] to compare one exponent to another (must be able to do ==, !=, >, <, >=, <=)?

OR

3) Is there a way to extract the two values from the exponent.

EG: "-1.45e-04" [Value1 = -1.45, Value2 = -4].

Answers for questions 1 and/or 2 are greatly preferred as 3 is a work around that may have issues with implementation (however, it's there in-case 1 and 2 don't have any suitable answers).

[Side-note: C++ methods can be used, although avoidance of stream is preferred ]

Thank you

int main(void)
{
    //Not the actual program, but simple enough
    char Arr[100];
    double T1, T2;

    sprintf(Arr,"-1.45e004");
    T1 = atof(Arr);

    printf("%f\n",fabs(T1)); //Fails to show the minus sign

    return 0;
}

The overall goal can be achieved thus having any of the three questions answered:

Either: 1) Direct comparison (using a function) between the two exponents in the given format to see if they are the same, not the same, greater, less than (etc) for sorting of the greatest exponent to the least exponent (not contained in the program as how the sorting is implement is not relevant: only the checking needs to be resolved).

2) Indirect comparison, by converting it into another type that can be directly compared.

3) Direct comparison using an awkward work around by comparing the two numbers in the exponent separately.

[Background details]

The actual program spans 7 header files and 1 cpp, so I cannot display a particular segment given it's intertwined.

It task is thus: files downloaded from the ACE satellite are parsed as arguments, loaded into memory, c开发者_开发问答onverted into their appropriate types. The stored types are then sorted and prepared (current stage) to render a graph (not yet implemented).

At the moment, I am dealing with exponents (stored in the ACE satellite text files in the format given above). These exponents need to be scanned through to find the greatest exponent and the least exponent, so the graph can be correctly spaced between the two. After this, each exponent will be compared to see if it is greater (higher on the graph) or lesser than (lower on the graph) a given set of numbers.

For that task, I need comparisons between exponents. Given I'm inexperienced with them, I decided to ask here.


It's unclear why your are calling fabs() in this line:

printf("%f\n",fabs(T1)); //Fails to show the minus sign

That's what fabs() does, it makes negative numbers positive. Perhaps you want this:

printf("%f\n",T1);

Comparison of two floating point numbers can be done directly:

double x = 12.345e67;
double y = 6.543e-2;
if (x > y) {
    puts("x is greater than y");
}


It seems you need to read What Every Computer Scientist Should Know About Floating-Point Arithmetic, to at least help you with the vocabulary.

Perhaps you can compute the exponent using:

const double exp = log(value) / log(10.0);

Your question is hard to understand, it's not well-defined what it means to "check" a floating point number, what it is that you are trying to determine?

UPDATE: To compare numbers, just do it. All of your three sample values are just legal floating-point numbers and can be directly compared using the standard build-in operators.


I think what you want to do is to extract the coefficient and base parts from a number expressed in scientific notation. There is no standard library function to do this, but you can write one easily:

static int
extract_coeff_and_base (double d, char *coeff, char *base)
{
  char buffer[50];
  size_t i;
  size_t len;

  sprintf (buffer, "%E\n", d);
  len = strlen (buffer);
  i = strcspn (buffer, "E");
  if (i < len)
    {
      memcpy (coeff, buffer, i);
      coeff[i] = 0;
      memcpy (base, buffer + i + 1, len - i);
      base[len - i] = 0;
      return 0;
    }
  return 1;
}

Usage:

int
main (int argc, char **argv)
{
  double d = atof (argv[1]);
  char coeff[20];
  char base[20];

  if (extract_coeff_and_base (d, coeff, base) == 0)
    {
      printf ("coefficient=%s, base=%s\n", coeff, base);
    }
  return 0;
}

Tests:

$ ./test.exe 1.45e004
coefficient=1.450000, base=+04

$ ./test.exe 1.45e-04
coefficient=1.450000, base=-04

$ ./test.exe -1.45e004
coefficient=-1.450000, base=+04


You should find what you're looking for in this example:

#include <stdlib.h>
#include <stdio.h>
#include <math.h>

const char *nums[] = {"1.45e004", "1.45e-04", "-1.45e004", NULL};

int main() {
  const char **numstring = nums;
  while (*numstring != NULL) {
    double num = strtod(*numstring, NULL);
    double sign = copysign(1.0, num);
    double exponent = trunc(log10(sign * num));
    double mantissa = num / pow(10, exponent);
    printf("%s -> %g, mantissa=%f, exponent=%f\n", *numstring, num, mantissa, exponent);
    numstring++;
  }
  return 0;
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜