Нужно сохранить float в строку, без потери точности, портабельно (вариант, непортабельно для PC, Win32, VC 8), причем с возможностью прочесться обратно. Human-readability строки не нужно, нужно только чтобы были "нормальные символы" (hex, наверное все же, 0-9, A-F; хотя, может и 7-bit ASCII пойдет, посмотрим).
Подскажите пожалуйста, какой способ наиболее кошерный.
Здравствуйте, Tuo_Bellas, Вы писали:
T_B>Нужно сохранить float в строку, без потери точности, портабельно (вариант, непортабельно для PC, Win32, VC 8), причем с возможностью прочесться обратно. Human-readability строки не нужно, нужно только чтобы были "нормальные символы" (hex, наверное все же, 0-9, A-F; хотя, может и 7-bit ASCII пойдет, посмотрим).
T_B>Подскажите пожалуйста, какой способ наиболее кошерный.
Если на всех твоих платформах float хранится в IEEE floating-point standard (а сейчас вообще встречаются платформы где это не так?), то преобразовывай в BASE64.
Здравствуйте, saproj, Вы писали:
T_B>>Нужно сохранить float в строку, без потери точности, портабельно (вариант, непортабельно для PC, Win32, VC 8), причем с возможностью прочесться обратно. Human-readability строки не нужно, нужно только чтобы были "нормальные символы" (hex, наверное все же, 0-9, A-F; хотя, может и 7-bit ASCII пойдет, посмотрим).
T_B>>Подскажите пожалуйста, какой способ наиболее кошерный.
S>Если на всех твоих платформах float хранится в IEEE floating-point standard (а сейчас вообще встречаются платформы где это не так?), то преобразовывай в BASE64.
Есть кусок кода? Или нужно мега-библиотеку подключать для этого?
Здравствуйте, Tuo_Bellas, Вы писали:
T_B>Всем привет!
T_B>Нужно сохранить float в строку, без потери точности, портабельно (вариант, непортабельно для PC, Win32, VC 8), причем с возможностью прочесться обратно. Human-readability строки не нужно, нужно только чтобы были "нормальные символы" (hex, наверное все же, 0-9, A-F; хотя, может и 7-bit ASCII пойдет, посмотрим).
T_B>Подскажите пожалуйста, какой способ наиболее кошерный.
можно что нить а-ля Base64
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Забанили по IP, значит пора закрыть эту страницу.
Всем пока
Здравствуйте, saproj, Вы писали:
S>Здравствуйте, Tuo_Bellas, Вы писали:
T_B>>Нужно сохранить float в строку, без потери точности, портабельно (вариант, непортабельно для PC, Win32, VC 8), причем с возможностью прочесться обратно. Human-readability строки не нужно, нужно только чтобы были "нормальные символы" (hex, наверное все же, 0-9, A-F; хотя, может и 7-bit ASCII пойдет, посмотрим). T_B>>Подскажите пожалуйста, какой способ наиболее кошерный. S>Если на всех твоих платформах float хранится в IEEE floating-point standard (а сейчас вообще встречаются платформы где это не так?), то преобразовывай в BASE64.
Base64 это мощно А чем это хуже?
Здравствуйте, Tuo_Bellas, Вы писали:
T_B>Всем привет!
T_B>Нужно сохранить float в строку, без потери точности, портабельно (вариант, непортабельно для PC, Win32, VC 8), причем с возможностью прочесться обратно. Human-readability строки не нужно, нужно только чтобы были "нормальные символы" (hex, наверное все же, 0-9, A-F; хотя, может и 7-bit ASCII пойдет, посмотрим).
T_B>Подскажите пожалуйста, какой способ наиболее кошерный.
T_B>Спасибо, T_B>Tuo_Bellas.
Если чтение и запись будут осуществлятся на одной платформе, то можно конвертить float в массив байт, а потом этот массив перекодировать в больший массив с разрешенными символами.
Здравствуйте, Vain, Вы писали:
V>Здравствуйте, saproj, Вы писали:
S>>Здравствуйте, Tuo_Bellas, Вы писали:
T_B>>>Нужно сохранить float в строку, без потери точности, портабельно (вариант, непортабельно для PC, Win32, VC 8), причем с возможностью прочесться обратно. Human-readability строки не нужно, нужно только чтобы были "нормальные символы" (hex, наверное все же, 0-9, A-F; хотя, может и 7-bit ASCII пойдет, посмотрим). T_B>>>Подскажите пожалуйста, какой способ наиболее кошерный. S>>Если на всех твоих платформах float хранится в IEEE floating-point standard (а сейчас вообще встречаются платформы где это не так?), то преобразовывай в BASE64. V>Base64 это мощно А чем это хуже? V>
...
V>
Тем что не портабельно.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Забанили по IP, значит пора закрыть эту страницу.
Всем пока
Здравствуйте, Vain, Вы писали:
T_B>>>Нужно сохранить float в строку, без потери точности, портабельно (вариант, непортабельно для PC, Win32, VC 8), причем с возможностью прочесться обратно. Human-readability строки не нужно, нужно только чтобы были "нормальные символы" (hex, наверное все же, 0-9, A-F; хотя, может и 7-bit ASCII пойдет, посмотрим). T_B>>>Подскажите пожалуйста, какой способ наиболее кошерный. S>>Если на всех твоих платформах float хранится в IEEE floating-point standard (а сейчас вообще встречаются платформы где это не так?), то преобразовывай в BASE64. V>Base64 это мощно А чем это хуже? V>[ccode] V>void ConvertToString(char* str,float f) { V> int* pi = (int*)&f;
После этой строки можно уже прекращать чтение .
V> sprintf(str,"%08X",*pi);
Плохое решение. На разных платформах int может быть little-endian или big-endian.
CC>Тем что не портабельно.
впрочем и с Base64 тоже нифига не портабельно. Тут я и сам ступил.
Вообще ИМХО без потери и портабельно можно сделать только если для сохранения ручками разбирать float на целочисленные варианты значений мантиссы и экспоненты. Ну и собирать при чтении обратно. Причем код сбора/разбора должен быть зависим от представления float на данной платформе.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Забанили по IP, значит пора закрыть эту страницу.
Всем пока
Здравствуйте, Tuo_Bellas, Вы писали:
S>>Если на всех твоих платформах float хранится в IEEE floating-point standard (а сейчас вообще встречаются платформы где это не так?), то преобразовывай в BASE64.
T_B>Есть кусок кода? Или нужно мега-библиотеку подключать для этого?
Готовую функцию, которая преобразовывает, найти несложно. Но по-моему гораздо интереснее написать самому. Там все очень просто: каждые 6 битов исходной последовательности являются индексом, по которому из массива "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" берется символ. И для 4-байтового float в конце последовательности нужно добавить "хвост" из двух '='.
Здравствуйте, saproj, Вы писали:
S>Здравствуйте, CreatorCray, Вы писали:
CC>>>Тем что не портабельно. CC>>впрочем и с Base64 тоже нифига не портабельно. S>Почему?
Потому, что если иметь в виду портабельность в общем смысле (а не на конкретный список платформ) то представление float все таки бывает разное. К примеру: попадался как то проц для встраиваемых систем в котором float был 48 бит.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Забанили по IP, значит пора закрыть эту страницу.
Всем пока
Здравствуйте, CreatorCray, Вы писали:
CC>>>впрочем и с Base64 тоже нифига не портабельно. S>>Почему? CC>Потому, что если иметь в виду портабельность в общем смысле (а не на конкретный список платформ) то представление float все таки бывает разное. К примеру: попадался как то проц для встраиваемых систем в котором float был 48 бит.
В своем сообщении я сразу оговорил следующее важное условие.
Если на всех твоих платформах float хранится в IEEE floating-point standard
А преобразовывать через int непортабельно даже при выполнении этого условия.
Tuo_Bellas wrote:
> Нужно сохранить float в строку, без потери точности, портабельно > (вариант, непортабельно для PC, Win32, VC 8), причем с возможностью > прочесться обратно. Human-readability строки не нужно, нужно только > чтобы были "нормальные символы" (hex, наверное все же, 0-9, A-F; хотя, > может и 7-bit ASCII пойдет, посмотрим).
Что-то не совсем понял. А чем банальное
double d1,d2;
d1=...;
sprintf(str, "%.100e", d1);
sscanf(buff, "%le", &d2);
assert(d1 == d2);// по идее будет выполнятся, пока точность double на данной платформе меньше 100.
не подойдёт?
Posted via RSDN NNTP Server 2.0
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Здравствуйте, saproj, Вы писали:
S>Здравствуйте, Tuo_Bellas, Вы писали:
S>>>Если на всех твоих платформах float хранится в IEEE floating-point standard (а сейчас вообще встречаются платформы где это не так?), то преобразовывай в BASE64.
T_B>>Есть кусок кода? Или нужно мега-библиотеку подключать для этого?
S>Готовую функцию, которая преобразовывает, найти несложно. Но по-моему гораздо интереснее написать самому. Там все очень просто: каждые 6 битов исходной последовательности являются индексом, по которому из массива "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" берется символ. И для 4-байтового float в конце последовательности нужно добавить "хвост" из двух '='.
Здравствуйте, Константин Л., Вы писали:
S>>Готовую функцию, которая преобразовывает, найти несложно. Но по-моему гораздо интереснее написать самому. Там все очень просто: каждые 6 битов исходной последовательности являются индексом, по которому из массива "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" берется символ. И для 4-байтового float в конце последовательности нужно добавить "хвост" из двух '='.
КЛ>там все по-другому
Здравствуйте, Tuo_Bellas, Вы писали:
T_B>Всем привет!
T_B>Нужно сохранить float в строку, без потери точности, портабельно (вариант, непортабельно для PC, Win32, VC 8), причем с возможностью прочесться обратно. Human-readability строки не нужно, нужно только чтобы были "нормальные символы" (hex, наверное все же, 0-9, A-F; хотя, может и 7-bit ASCII пойдет, посмотрим).
T_B>Подскажите пожалуйста, какой способ наиболее кошерный.
Здравствуйте, kan_izh, Вы писали:
>> Нужно сохранить float в строку, без потери точности, портабельно >> (вариант, непортабельно для PC, Win32, VC 8), причем с возможностью >> прочесться обратно. Human-readability строки не нужно, нужно только >> чтобы были "нормальные символы" (hex, наверное все же, 0-9, A-F; хотя, >> может и 7-bit ASCII пойдет, посмотрим). _>Что-то не совсем понял. А чем банальное _>
_>double d1,d2;
_>d1=...;
_>sprintf(str, "%.100e", d1);
_>sscanf(buff, "%le", &d2);
_>assert(d1 == d2);// по идее будет выполнятся, пока точность double на данной платформе меньше 100.
_>
_>не подойдёт?
В этом случае будут искажаться специальные значения. Сделай такое присваивание значения переменной d1 и assert будет срабатывать:
saproj wrote:
>> > Нужно сохранить float в строку, без потери точности, портабельно
... > _>sprintf(str, "%.100e", d1);
... > В этом случае будут искажаться специальные значения. Сделай такое > присваивание значения переменной d1 и assert будет срабатывать: > > d1=1.123; > d1/=0;
Да, согласен, но спецзначения можно специально обработать (а это, вообще говоря, далеко не всегда нужно), их всего
несколько штук. Зато портабельно, без всяких извращений типа base64 и надежды на определённый формат бинарного
представления в памяти.
Posted via RSDN NNTP Server 2.0
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Здравствуйте, kan_izh, Вы писали:
>>> > Нужно сохранить float в строку, без потери точности, портабельно _>... >> _>sprintf(str, "%.100e", d1); _>... >> В этом случае будут искажаться специальные значения. Сделай такое >> присваивание значения переменной d1 и assert будет срабатывать: >> >> d1=1.123; >> d1/=0; _>Да, согласен, но спецзначения можно специально обработать (а это, вообще говоря, далеко не всегда нужно), их всего _>несколько штук. Зато портабельно, без всяких извращений типа base64 и надежды на определённый формат бинарного _>представления в памяти.
Зависит от задачи, конечно. Не зная точно какая задача нет смысла спорить. Но думаю, что вполне можно назвать извращением передачу 100 с лишним байт вместо 8 (float) или 12 (double) теряя при этом некоторые значения.
Здравствуйте, saproj, Вы писали:
V>>Base64 это мощно А чем это хуже? V>>[ccode] V>>void ConvertToString(char* str,float f) { V>> int* pi = (int*)&f; S>После этой строки можно уже прекращать чтение . V>> sprintf(str,"%08X",*pi); S>Плохое решение. На разных платформах int может быть little-endian или big-endian.
Я может чего то непонял? Тебе так и так придётся будет подгонять float и int k разным платформам, так что пример нормальный, просто надо додумать дальше своей головой
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]
> Зависит от задачи, конечно. Не зная точно какая задача нет смысла > спорить. Но думаю, что вполне можно назвать извращением передачу 100 с > лишним байт вместо 8 (float) или 12 (double) теряя при этом некоторые > значения.
100 я написал для простоты, при необходимости можно заюзать numeric_limits<>::digits (или что-то около того) и посчитать
точное кол-во — минимальное и без потерь точности.
Posted via RSDN NNTP Server 2.0
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Здравствуйте, saproj, Вы писали:
S>Зависит от задачи, конечно. Не зная точно какая задача нет смысла спорить. Но думаю, что вполне можно назвать извращением передачу 100 с лишним байт вместо 8 (float) или 12 (double) теряя при этом некоторые значения
С каких это пор у float 8 байт? А 12-байтный где взяли?.
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]
Здравствуйте, Vain, Вы писали:
S>>Зависит от задачи, конечно. Не зная точно какая задача нет смысла спорить. Но думаю, что вполне можно назвать извращением передачу 100 с лишним байт вместо 8 (float) или 12 (double) теряя при этом некоторые значения V>С каких это пор у float 8 байт? А 12-байтный где взяли?.
float и double 4 и 8 байт соотвественно. Речь о другом. Читайте всю ветку.
Здравствуйте, saproj, Вы писали:
S>Здравствуйте, Константин Л., Вы писали:
S>>>Готовую функцию, которая преобразовывает, найти несложно. Но по-моему гораздо интереснее написать самому. Там все очень просто: каждые 6 битов исходной последовательности являются индексом, по которому из массива "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" берется символ. И для 4-байтового float в конце последовательности нужно добавить "хвост" из двух '='.
КЛ>>там все по-другому
S>Что именно по-другому?
Здравствуйте, saproj, Вы писали:
S>>>Зависит от задачи, конечно. Не зная точно какая задача нет смысла спорить. Но думаю, что вполне можно назвать извращением передачу 100 с лишним байт вместо 8 (float) или 12 (double) теряя при этом некоторые значения V>>С каких это пор у float 8 байт? А 12-байтный где взяли?. S>float и double 4 и 8 байт соотвественно. Речь о другом. Читайте всю ветку
ну, на какой платформе ты видел такие типы?
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
Если на всех твоих платформах float хранится в IEEE floating-point standard
S>А преобразовывать через int непортабельно даже при выполнении этого условия.
А как ты собираешься превращать float в строку бит?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, Tuo_Bellas, Вы писали:
T_B>Нужно сохранить float в строку, без потери точности, портабельно (вариант, непортабельно для PC, Win32, VC 8), причем с возможностью прочесться обратно. Human-readability строки не нужно, нужно только чтобы были "нормальные символы" (hex, наверное все же, 0-9, A-F; хотя, может и 7-bit ASCII пойдет, посмотрим).
Ну, можно воспользоваться тем сокровенным знанием, что float — это двоичное плавающее число. С неизвестной разрядностью и т.д. и т.п.
float f;
int sign = (f<0) ? -1 : (f>0) ? : +1 : 0;
if(f<0) f = -f;
// постусловие: f>=0int power = 0;
while(f>=1.0) { f/=2; ++power; }
while(f<0.5) { f*=2; --power; }
// постусловие: 0.5<=f<1.0long mantissa = 0;
// вот тут надо подумать, как грамотно найти мантиссу.
// может быть, завести известное число float g и методом последовательных приближений приравнять его к f
// одновременно заполняя mantissa