C Проверка или преобразование показателей
У меня есть показатели в представленном формате: "1.45e004" или "1.45e-04" или "-1.45e004".
[обратите внимание на знак минус в третьем]
Проверка (==,! =,>, <, <=,>= И т. Д.) Не работает с показателями [неверно или результаты не возвращаются] в их текущем формате.
Однако преобразование показателя степени с использованием fabs работает для первых двух, но не для последнего, поскольку fabs удаляет знак минуса (следовательно, значение становится положительным, а не отрицательным, как должно быть).
Мои вопросы таковы:
1) Есть ли способ конвертировать показатели в абсолюты, которые будут включать в себя знаковые значения?
[Фабс не может этого сделать]
ИЛИ ЖЕ
2) Есть ли способ [или функция (и)] сравнить один показатель степени с другим (должен уметь делать ==,! =,>, <,>=, <=)?
ИЛИ ЖЕ
3) Есть ли способ извлечь два значения из показателя степени.
Например: "-1,45e-04" [Значение1 = -1,45, Значение2 = -4].
Ответы на вопросы 1 и / или 2 очень предпочтительны, так как 3 - обходной путь, который может иметь проблемы с реализацией (однако, в случае 1 и 2 нет подходящих ответов).
[Примечание: могут использоваться методы C++, хотя предпочтительнее избегать потока]
Спасибо
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;
}
Общая цель может быть достигнута, таким образом, ответ на любой из трех вопросов:
Либо: 1) Прямое сравнение (с использованием функции) между двумя показателями в данном формате, чтобы увидеть, являются ли они одинаковыми, не одинаковыми, большими, меньшими (и т. Д.) Для сортировки наибольшего показателя по наименьшему показателю (не содержащиеся в программе сведения о том, как реализована сортировка, не имеют значения: необходимо разрешить только проверку).
2) Косвенное сравнение путем преобразования его в другой тип, который можно сравнивать напрямую.
3) Прямое сравнение, используя неловкое решение, сравнивая два числа в показателе степени отдельно.
[Детали фона]
Реальная программа охватывает 7 заголовочных файлов и 1 cpp, поэтому я не могу отобразить конкретный сегмент, если он переплетен.
Задача такова: файлы, загруженные со спутника ACE, анализируются как аргументы, загружаются в память, преобразуются в соответствующие им типы. Затем сохраненные типы сортируются и подготавливаются (текущий этап) для отображения графика (еще не реализован).
В данный момент я имею дело с показателями (хранятся в спутниковых текстовых файлах ACE в формате, указанном выше). Эти показатели должны быть просканированы, чтобы найти наибольший показатель и наименьший показатель, чтобы график можно было правильно распределить между ними. После этого каждый показатель будет сравниваться, чтобы определить, больше ли он (выше на графике) или меньше (ниже на графике) данного набора чисел.
Для этой задачи мне нужны сравнения между показателями. Поскольку я неопытен с ними, я решил спросить здесь.
4 ответа
Непонятно почему ты звонишь fabs()
в этой строке:
printf("%f\n",fabs(T1)); //Fails to show the minus sign
Это то что fabs()
делает, это делает отрицательные числа положительными. Возможно, вы хотите это:
printf("%f\n",T1);
Сравнение двух чисел с плавающей запятой может быть сделано напрямую:
double x = 12.345e67;
double y = 6.543e-2;
if (x > y) {
puts("x is greater than y");
}
Кажется, вам нужно прочитать " Что должен знать каждый учёный-компьютерщик" об арифметике с плавающей точкой, чтобы хотя бы помочь вам с лексикой.
Возможно, вы можете вычислить показатель степени, используя:
const double exp = log(value) / log(10.0);
Ваш вопрос трудно понять, он недостаточно четко определен, что значит "проверять" число с плавающей запятой, что вы пытаетесь определить?
ОБНОВЛЕНИЕ: Чтобы сравнить числа, просто сделайте это. Все ваши три значения выборки являются просто допустимыми числами с плавающей запятой и могут напрямую сравниваться с помощью стандартных встроенных операторов.
Я думаю, что вы хотите сделать, это извлечь коэффициент и базовые части из числа, выраженного в научной записи. Для этого нет стандартной библиотечной функции, но вы можете легко ее написать:
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;
}
Использование:
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;
}
тесты:
$ ./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
Вы должны найти то, что вы ищете в этом примере:
#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;
}