2015-09-30 2 views
0

У меня есть шестнадцатеричный номер. string, и я хочу преобразовать его в float. Может ли кто-нибудь предложить какую-либо идею? Я искал здесь, на этом форуме, и я получил одно сообщение, в котором упоминалось следующее решение. Я понял, что первая строка преобразуется в шестнадцатеричный номер, а затем hex no преобразуется в float. Но я не понял, как это происходит float_data = *((float*)&hexvalue);. И этот код также не работает с этим методом.Преобразование шестнадцатеричного значения в float в C

Исправление 1: Я думаю, что я не упоминал здесь четко. Прошу прощения. Это шестнадцатеричное значение 39 39 2e 30 35 при преобразовании в ascii, то оно дает 99.05. И мне нужен этот ascii как float no. Ниже мой код:

#include <stdlib.h> 
#include <string.h> 
#include <stdio.h> 
int main() 
{ 
    char *my_data; 
    double float_data; 
    unsigned int hexvalue; 
    my_data = malloc (100); 
    my_data =strcpy(my_data, "39 39 2e 30 35"); 
    sscanf (my_data, "%x", &hexvalue); 
    float_data = *((float*)&hexvalue); 
    printf ("the floating n. is %f", float_data); 
    free (my_data); 
    return 0; 
} 
+0

Каков ожидаемый результат? –

+1

Это любопытно; существует несколько систем, где число с плавающей запятой составляет 5 байтов. Что вы должны делать? Где десятичная точка? Преобразование одного байта в 'float' вряд ли принесет полезное значение. 'Malloc()' и 'strcpy()' кажутся излишними. Возможно, вы разделили много кода и переделали его; строки управления памятью являются излишними, но, возможно, более объяснимыми (MCVE - [Как создать минимальный, полный и проверенный пример?] (http://stackoverflow.com/help/mcve)). –

ответ

2

Сканирование с использованием "%hhx" в массив символов, добавьте пустой символ, а затем преобразовать в float используя atof() или strtod().

int main(void) { 
    unsigned char uc[5+1]; 
    sscanf("39 39 2e 30 35", "%hhx%hhx%hhx%hhx%hhx", &uc[0], &uc[1], &uc[2], &uc[3], &uc[4]); 
    uc[5] = 0; 
    float f = atof(uc); 
    printf("%f\n", f); 
    return 0; 
} 

Выход

99.050003 

[править] Выпускается с С99, С scanf():

hh Указывает, что следующий d, i, o, u, x, X или n Спецификатор преобразования применяется к аргументу с t ype указатель на signed char или unsigned char. C11dr §7.21.6.2 11

+0

Большое спасибо. Это сработало .. :) – learningpal

+0

Не могли бы вы объяснить, что означает спецификатор формата '% hhx'? – learningpal

+0

@learningpal Ответ обновлен. – chux

1

float_data = *((float*)&hexvalue); считает &hexvalue как указатель на float, а затем прочитать данные из где &hexvalue точек, как float.

Код продукта май Работа, в зависимости от окружающей среды.

#include <stdlib.h> 
#include <string.h> 
#include <stdio.h> 
int main() 
{ 
    char *my_data; 
    double float_data; 
    unsigned int hexvalue[4]; 
    unsigned char floatdata_hex[4]; 
    int i; 
    my_data = malloc (100); 
    strcpy(my_data, "39 39 2e 30 35"); /* the assignment isn't needed */ 
    /* the original code will read only one hex value, not four or five */ 
    sscanf (my_data, "%x%x%x%x", &hexvalue[0], &hexvalue[1], &hexvalue[2], &hexvalue[3]); /* read to int */ 
    for (i = 0; i < 4; i++) floatdata_hex[i] = hexvalue[i]; /* and convert them to char later */ 
    float_data = *((float*)floatdata_hex); 
    /* the value may be too small to display by %f */ 
    printf ("the floating n. is %.15g", float_data); 
    free (my_data); 
    return 0; 
} 
+4

'float_data = * ((float *) floatdata_hex);' нарушает правило строгой алиасии, и поэтому это неопределенное поведение. – mch

+0

Спасибо большое @MikeCAT: ваш код работает. Извините, я исказил вопрос. Но ваш код объясняет концепцию. – learningpal

1

Этот код будет выполнять новое преобразование, поддерживая произвольную длину ввода.

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

double ascii_string_to_float(const char *str) 
{ 
    double ret = 0.0; 
    char *work1; 
    char *work2; 
    char *tok, *out; 
    size_t len = strlen(str); 
    work1 = malloc(len + 1); 
    work2 = malloc(len + 1); 
    if (work1 == NULL || work2 == NULL) 
    { 
     if (work1 != NULL) free(work1); 
     if (work2 != NULL) free(work2); 
     exit(1); 
    } 
    strcpy(work1, str); 
    out = work2; 
    tok = strtok(work1, " "); 
    do { 
     int tmp; 
     sscanf(tok, "%x", &tmp); 
     *(out++) = tmp; 
    } while ((tok = strtok(NULL, " ")) != NULL); 
    *out = '\0'; 
    sscanf(work2, "%lf", &ret); 
    free(work1); 
    free(work2); 
    return ret; 
} 

int main(void) 
{ 
    const char *my_data = "39 39 2e 30 35"; 
    double float_data; 
    float_data = ascii_string_to_float(my_data); 
    printf("the floating n. is %f", float_data); 
    return 0; 
} 

Проверка ошибок не производится, поэтому добавьте их, если необходимо.

+0

Спасибо большое .. :) – learningpal

Смежные вопросы