2010-03-11 4 views
2

Я делаю некоторый ввод/вывод между C++ и программой python (только значения с плавающей запятой). Python имеет приятную функцию преобразования значений с плавающей запятой в шестнадцатеричные числа и обратно, как вы можете видеть в этом ссылка:easy hex/float conversion

http://docs.python.org/library/stdtypes.html#additional-methods-on-float

существует простой способ в C++, чтобы на что-то подобное? и преобразовать вывод python обратно в C++ double/float? Таким образом, у меня не возникло бы проблемы с ошибками округления при обмене данными между двумя процессами ...

thx для ответов!

+0

«Ошибки округления» представляют собой младшие разряды без значимых значений. Они (а) десятичные для двоичных проблем; они также могут быть (б) ненужными битами, оставшимися после деления и умножения неразумно. Простое прохождение «сырых» значений поплавка вокруг вас может не очень помочь, если ваши числовые методы являются необоснованными. –

+1

вы правы .... Но я не могу избавиться от ошибки (b) в моей симуляции (мои симуляции просто для себя работают и оказались точными). Теперь мне нужно обмениваться некоторой информацией между различными симуляциями и зачем вводить ошибку, когда это можно сделать иначе? – user290494

ответ

5

По этой ссылке вы предоставили в вашем вопросе (Additional Methods on Float):

Этот синтаксис аналогичен синтаксису , указанной в разделе 6.4.4.2 стандарта C99, а также синтаксиса, используемого в Java 1.5 и далее. В частности, выход float.hex() может использоваться как шестнадцатеричное с плавающей точкой в ​​буквальном C или Java кода и шестнадцатеричных строк производится с помощью % C в формат символа или в Java Double.toHexString принимаются float.fromhex().

Пример:

#include <cstdio> 

int main() { 
    float f = 42.79; 
    printf("%.2f == %a\n", f, f); 
    fscanf(stdin, "%a", &f); 
    printf("%.2f == %a\n", f, f); 
} 

Выполнить это:

$ g++ *.cpp && (python -c'print 12.34.hex()' | ./a.out) 

Выход:

42.79 == 0x1.5651ecp+5 
12.34 == 0x1.8ae148p+3 
+0

привет, я пытался запустить ту же программу, но я получил 42.79 == 0x1.5651ecp + 5 0.00 == 0x0p + 0. Мои выходы python 0x1.8ae147ae147aep + 3, как-то C++ не читали это правильно. Вы знаете, почему? Большое спасибо. –

+0

, даже если я просто побежал ./a.out и введите 0x1.5651ecp + 5, он все равно произвел 0.00 == 0x0p + 0 –

+0

@Qiang Li: Каковы ваши компиляторы, ОС, * точные * команды, которые вы используете? – jfs

1

Документов там говорят, что %a делает это в C.

1

Вы очень ошибается, если вы считаете, что это решит все ваши проблемы. Обозначение в шестнадцатеричной форме в точности эквивалентно исходному поплавку. Он просто использует другое представление.

+1

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

+0

@ Daniel: В этом случае ему может быть лучше использовать что-то вроде 'gmp', если строковое представление так важно. –

+0

Thx для подсказки gmp Я тоже не знал эту библиотеку. Его интересная альтернатива. Но для моей простой проблемы это, вероятно, немного переборщило. – user290494

1

У C++ нет каких-либо библиотечных подпрограмм для преобразования hex в плавающую точку. Одна из причин заключается в том, что внутреннее представление с плавающей точкой не стандартизировано (хотя многие компиляторы используют стандарт IEEE).

Я рекомендую хранить в формате ASCII, который переносится через платформы. Вы можете написать свою собственную библиотеку (или найти другую), которая преобразует формат IEEE (в шестнадцатеричном виде) во внутреннее представление.

2

Можете ли вы отправить необработанные двоичные данные между двумя вместо строк? Пакет стандартной библиотеки Python может распаковать необработанные данные в плавающий объект Python.

+0

эй круто ... Я не знал об этой функции python. Я определенно займусь этим. – user290494

1

Если вы на платформе системы, чья библиотека C поддерживает C99, вы можете просто используйте printf() и scanf() с %a спецификатор формата.Для чтения в таких значениях, вы можете также использовать C99 strtod(), strtof() и strtold() функции:

float value = strtof(string, NULL, 0); 

При желании вы можете заменить NULL с char **, чтобы получить обратно указатель на конец последовательности преобразованных символов, и 0 с известной базой для строкового представления (если вы установите базовое значение равным нулю, оно выведет базу из формата, будет обрабатывать шестнадцатеричные поплавки python просто отлично, а также обрабатывать нормальную с плавающей запятой с десятичной запятой)

Если ваш поставщик компилятора/библиотеки выбрал не заботиться о C99 (MSVC, basicall y), вам, вероятно, не повезло, пока эти функции не включены в стандарт C++ (я считаю, что они находятся в проекте C++ 0x, но я не совсем уверен).

0

C++ 11 предлагает зЬй :: hexfloat: IO manipulators including hexfloat

Если вы можете использовать C++ 11, то hexfloat является довольно простой в использовании.