Перевод строки в double

372
15 июля 2017, 08:41

Как перевести строку типа
string s = "000000000000f8bf"
в значение double? Я знаю как прочитать с файла такое значение, и правильно перевести. А как со строкой не могу понять(может потому что конец рабочего дня). Пример программы которая записывает в файл 50 double чисел в бинарном формате и потом удачно считывает файл и такие значения прекрасно переводит в double.

#include <stdio.h>
#include <malloc.h>
#define FILENAME "b.txt"
int main(void)
{
    register int i;
    FILE *fp;
    double balance[101];
    /* открытие на запись */
    if ((fp = fopen(FILENAME, "wb")) == NULL) {
        printf("Cannot open file.");
        return 1;
    }
    for (i = 0; i < 101; i++) balance[i] = -25 + 0.5 * i;
    /* сохранение за раз всего массива balance */
    fwrite(balance, sizeof balance, 1, fp);
    fclose(fp);
    /* обнуление массива */
    for (i = 0; i<101; i++) balance[i] = 0.0;
    /* открытие для чтения */
    if ((fp = fopen(FILENAME, "rb")) == NULL) {
        printf("cannot open file");
        return 1;
    }
    /* чтение за раз всего массива balance */
    fread(balance, sizeof balance, 1, fp);
    /* вывод содержимого массива */
    for (i = 0; i<101; i++) printf("%f  ", balance[i]);
    fclose(fp);
    return 0;
}
double f; *((unsigned long long*)&f) = strtoull(s.c_str(),0,16);

@Harry Этот код к сожалению работает не корректно. Есть предположения ошибка из за порядка следования байтов(big-endian/little-endian).
@Vladimir Если запустить пример, то вы увидите, как записываются числа double в файл. И как они корректно считываются. Вот что будет записано в файл:

0000 0000 0000 39c0 0000 0000 0080 38c0
0000 0000 0000 38c0 0000 0000 0080 37c0
0000 0000 0000 37c0 0000 0000 0080 36c0
0000 0000 0000 36c0 0000 0000 0080 35c0
0000 0000 0000 35c0 0000 0000 0080 34c0
0000 0000 0000 34c0 0000 0000 0080 33c0
0000 0000 0000 33c0 0000 0000 0080 32c0
0000 0000 0000 32c0 0000 0000 0080 31c0
0000 0000 0000 31c0 0000 0000 0080 30c0
0000 0000 0000 30c0 0000 0000 0000 2fc0
0000 0000 0000 2ec0 0000 0000 0000 2dc0
0000 0000 0000 2cc0 0000 0000 0000 2bc0
0000 0000 0000 2ac0 0000 0000 0000 29c0
0000 0000 0000 28c0 0000 0000 0000 27c0
0000 0000 0000 26c0 0000 0000 0000 25c0
0000 0000 0000 24c0 0000 0000 0000 23c0
0000 0000 0000 22c0 0000 0000 0000 21c0
0000 0000 0000 20c0 0000 0000 0000 1ec0
0000 0000 0000 1cc0 0000 0000 0000 1ac0
0000 0000 0000 18c0 0000 0000 0000 16c0
0000 0000 0000 14c0 0000 0000 0000 12c0
0000 0000 0000 10c0 0000 0000 0000 0cc0
0000 0000 0000 08c0 0000 0000 0000 04c0
0000 0000 0000 00c0 0000 0000 0000 f8bf
0000 0000 0000 f0bf 0000 0000 0000 e0bf
0000 0000 0000 0000 0000 0000 0000 e03f
0000 0000 0000 f03f 0000 0000 0000 f83f
0000 0000 0000 0040 0000 0000 0000 0440
0000 0000 0000 0840 0000 0000 0000 0c40
0000 0000 0000 1040 0000 0000 0000 1240
0000 0000 0000 1440 0000 0000 0000 1640
0000 0000 0000 1840 0000 0000 0000 1a40
0000 0000 0000 1c40 0000 0000 0000 1e40
0000 0000 0000 2040 0000 0000 0000 2140
0000 0000 0000 2240 0000 0000 0000 2340
0000 0000 0000 2440 0000 0000 0000 2540
0000 0000 0000 2640 0000 0000 0000 2740
0000 0000 0000 2840 0000 0000 0000 2940
0000 0000 0000 2a40 0000 0000 0000 2b40
0000 0000 0000 2c40 0000 0000 0000 2d40
0000 0000 0000 2e40 0000 0000 0000 2f40
0000 0000 0000 3040 0000 0000 0080 3040
0000 0000 0000 3140 0000 0000 0080 3140
0000 0000 0000 3240 0000 0000 0080 3240
0000 0000 0000 3340 0000 0000 0080 3340
0000 0000 0000 3440 0000 0000 0080 3440
0000 0000 0000 3540 0000 0000 0080 3540
0000 0000 0000 3640 0000 0000 0080 3640
0000 0000 0000 3740 0000 0000 0080 3740
0000 0000 0000 3840 0000 0000 0080 3840
0000 0000 0000 3940 
Answer 1

Если речь идет о переинтерпретации 64-битного целого, записанного в шестнадцатеричном формате ASCII строке, то

std::string s = "000000000000f8bf";
uint64_t u = strtoull(s.c_str(), NULL, 16);
double d;
static_assert(sizeof u == sizeof d);
memcpy(&d, &u, sizeof d);

О порядке байтов (little-endian? big-endinan?), однако, автор вопроса ни слова не сказал.

Если строка "000000000000f8bf" получена путем copy-and-paste из дампа бинарного файла как файла 64-битных целых, то на little-endian машине порядок байтов придется сначала развернуть

std::reverse((unsigned char *) &u, (unsigned char *) &u + sizeof u);

Если же дамп бинарного файла был сделан как файла 32-битных целых или как файла 16-битных целых, то разворот придется делать более хитрый - разворачивать придется последовательные четверки байтов в первом случае и последовательные пары байтов во втором. (Опять же, что это за дамп автор вопроса сообщать отказывается.)

READ ALSO
Помогите задать pattern validation

Помогите задать pattern validation

Нужно чтобы могли быть введены только русские или английские буквы в верхнем и нижнем регистре, а также символы пробел или дефис

357
JS событие .on(&ldquo;click&rdquo;) в паре с .filter .attr (оптимизация)

JS событие .on(“click”) в паре с .filter .attr (оптимизация)

Есть код, который добавляет переменную id в URL браузера при клике на кнопку

284
Неправильно переключаются checkbox-ы

Неправильно переключаются checkbox-ы

Есть два чекбоксаОдин сразу отмечен, второй нет

245
форматирование текста (javascript)

форматирование текста (javascript)

здравствуйте, в функцию поступает такой текст:

260