Форум программистов, компьютерный форум, киберфорум
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 10, средняя оценка - 4.60
BeginerMan
49 / 48 / 5
Регистрация: 17.11.2012
Сообщений: 427
#1

Как сохранить float в переменной типа char? - C++

01.05.2016, 20:43. Просмотров 1698. Ответов 76
Метки нет (Все метки)

Всем здрасьте.
Как можно записать float в char ?
И как потом float вытащить из char, если он будет находится примерно посередине ну или в начале?

C++
1
2
3
4
5
6
7
8
float x;
char str[100]
// Запих x в str
//...
// Вытащить float ?
str[0-40] = // ... 
str[41] = //  если я знаю, что float начинается с 41 символа, к примеру
str[45-99] = //....
0
Лучшие ответы (1)
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
01.05.2016, 20:43
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Как сохранить float в переменной типа char? (C++):

Переменной d присвоить первую цифру после запятой некоторой переменной x типа float - C++
Нужно целой переменной d присвоить первую цыфру после комы некоторой переменной x типа float Скажите, пожалуйста, с чего начать и по...

Как получить адрес переменной типа unsigned char? - C++
Всем привет! Как получить адрес переменной типа unsigned char? Всё ерунда получается #include <iostream> using namespace std; ...

Преобразование типа char в тип float - C++
При считывании из файла чисел (каждое число расположено на новой строке, целая часть от дробной отделяется точкой). Использую функцию...

проблема с переменной типа char - C++
int count(char a){ int c=0; int words=0; while(a!='\0'){ if(a==' ')++words; } return words; } очень примитивный вопрос... ...

Вывод переменной типа char - C++
Переменная x типа char. x = 65; cout << x; Так выводиться "A". x = 64; cout << x+1;

Вывод адреса переменной типа char - C++
Всем привет! Хочу задать вопрос... есть код: #include <iostream> int main() { char ch = 'h'; char* p = &ch;

76
ValeryS
Модератор
6785 / 5193 / 497
Регистрация: 14.02.2011
Сообщений: 17,421
02.05.2016, 09:50 #16
вот еще вариантик
C++
1
2
3
4
5
6
7
8
9
10
union MyFloat
{
float flt;
char chr[sizeof(float)]
}
................
MyFloat var;
var.flt=1.0; // записали float 
for(int i=0;i<sizeof(flt);i++)// выдаем все байты
 printf("%x ",var.chr[i]);
1
cordfield
44 / 44 / 15
Регистрация: 04.05.2014
Сообщений: 188
02.05.2016, 10:13 #17
vxg, код может не работать на linux и/или с компилятором gcc и включённой оптимизацией (-O3). Когда оптимизация включена, преобразования указателей, типы которых несовместимы друг с другом, компилятор будет выполнять неправильно (нарочно и обычно не выводя предупреждений об этом). То есть, поведение предложенного программного кода будет неопределено. Подробности по ссылке, которую привёл hoggy
0
vxg
Модератор
3208 / 2011 / 230
Регистрация: 13.01.2012
Сообщений: 7,790
02.05.2016, 10:48 #18
cordfield, моё понимание языка побуждает меня сделать вывод что такое поведение некорректно
0
cordfield
44 / 44 / 15
Регистрация: 04.05.2014
Сообщений: 188
02.05.2016, 11:24 #19
vxg, по факту такое поведение есть, и я с ним сталкивался. Проблема решается добалением флага компилятора -fno-strict-aliasing, который запрещает подобные оптимизации.
0
hoggy
6798 / 2984 / 514
Регистрация: 15.11.2014
Сообщений: 6,741
Завершенные тесты: 1
02.05.2016, 12:44 #20
Цитата Сообщение от ValeryS Посмотреть сообщение
вот еще вариантик
я так и не понял, содержит ли такой код UB,
или нет.

Цитата Сообщение от cordfield Посмотреть сообщение
который запрещает подобные оптимизации.
нафиг нам эффективность.
нафиг нам оптимизации.
да здравствуют тормоза!
0
ValeryS
Модератор
6785 / 5193 / 497
Регистрация: 14.02.2011
Сообщений: 17,421
02.05.2016, 13:29 #21
Цитата Сообщение от hoggy Посмотреть сообщение
я так и не понял, содержит ли такой код UB,
код не атомарный
представь что один поток достает char-ы достал парочку, в это время другой поток переписывает float следующие char-ы могут быть из нового значения

Добавлено через 1 минуту
Цитата Сообщение от hoggy Посмотреть сообщение
memcpy(&ret,&src,sizeof(src));
тоже не атомарный
0
hoggy
6798 / 2984 / 514
Регистрация: 15.11.2014
Сообщений: 6,741
Завершенные тесты: 1
02.05.2016, 13:42 #22
Цитата Сообщение от ValeryS Посмотреть сообщение
код не атомарный
атомарность не причем.

если я правильно понял,
то нельзя записать один мембер,
а читать другой.

хотя в с++11 вроде какие то оговорки появились, что можно,
если у них "common initial sequence"

но в данной ситуации это не тот случай.
0
vxg
Модератор
3208 / 2011 / 230
Регистрация: 13.01.2012
Сообщений: 7,790
02.05.2016, 20:36 #23
hoggy, инвалидская оптимизация уродуюшая 100% легальный код, зашибись подарочек, ну будем знать, спс
0
hoggy
6798 / 2984 / 514
Регистрация: 15.11.2014
Сообщений: 6,741
Завершенные тесты: 1
02.05.2016, 21:02 #24
Цитата Сообщение от vxg Посмотреть сообщение
оптимизация уродуюшая 100% легальный код
в том то и дело, что код нелегальный.
оптимизации не вредят легальному коду.
0
vxg
Модератор
3208 / 2011 / 230
Регистрация: 13.01.2012
Сообщений: 7,790
02.05.2016, 21:13 #25
hoggy, этот код легальный. memcmp - легальная? А где в ней все эти страшные модификаторы ? Нет.
0
hoggy
6798 / 2984 / 514
Регистрация: 15.11.2014
Сообщений: 6,741
Завершенные тесты: 1
02.05.2016, 21:18 #26
Цитата Сообщение от vxg Посмотреть сообщение
этот код легальный
код, который нарушает алиасинг нелегальный.
код, который использует конструкции не имеющие гарантий - нелегальный.
Цитата Сообщение от vxg Посмотреть сообщение
memcmp - легальная?
memcpy легальна.
Цитата Сообщение от vxg Посмотреть сообщение
А где в ней все эти страшные модификаторы
не понял вопроса.
0
cordfield
44 / 44 / 15
Регистрация: 04.05.2014
Сообщений: 188
02.05.2016, 21:45 #27
vxg, технически данная оптимизация компилятора легальна исходя из стандарта C++. Но даже Линус Торвальдс жаловался на такое поведение. Стандарт допускает подобное, но не предписывает компилятору так себя вести. С точки зрения разработчиков компилятора - это как поиск лазеек в законе, чтобы программистам жизнь мёдом не казалась.
0
IGPIGP
Комп_Оратор)
Эксперт по математике/физике
6908 / 3185 / 313
Регистрация: 04.12.2011
Сообщений: 8,818
Записей в блоге: 5
02.05.2016, 22:18 #28
В примере из
https://habrahabr.ru/post/114117/
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <stdio.h>
 
typedef unsigned int DWORD;
typedef unsigned short WORD;
 
inline DWORD SwapWords ( DWORD val )
{
      WORD * p = (WORD*) &val;
      WORD t;
      t = p[0];
      p[0] = p[1];
      p[1] = t;
      return val;
}
 
int main()
{
      printf ( "%d\n", SwapWords(1) );
      return 0;
}
как я понял, компилятор не пишет по указателю p так как уверен, что на значении val это никак отразиться не может. Умный.
У меня MVS и я не могу это проверить, но верю.
Однако когда берётся указатель на отдельную память, соответствующего ему типа (и туда ничего больше не указывает!) и туда пишется значение полученное от разыменования указателя полученного приведением от другого типа, то о какой оптимизации тут может идти речь? Или таки может? Не ужели такой код не будет вести себя предсказуемо:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <iostream>
using namespace std;
int main(int argc, char* argv[])
{
const size_t storage_size=6;
unsigned long long strange_storage[storage_size];
double arr_fl[]={1.234, 5.678, 123.34e25, 34, -0.3131, +33434.2};
for( size_t i=0; i<storage_size; ++i){
strange_storage[i]=*reinterpret_cast<unsigned long long*>(arr_fl+i);
cout<<strange_storage[i]<<"\tis\t"<<*reinterpret_cast<double*>(strange_storage+i)<<endl;
}
    system("pause");
return 0;
}
?
0
vxg
Модератор
3208 / 2011 / 230
Регистрация: 13.01.2012
Сообщений: 7,790
02.05.2016, 22:30 #29
hoggy, если легальная функция оперирующая указателями на память по адресам которых хранится не тот тип что указан в указателях и эти указатели не объявлены рестрикт то чем это отличается от простого кода без всей этой лабуды?
0
grizlik78
Эксперт С++
1974 / 1467 / 122
Регистрация: 29.05.2011
Сообщений: 3,037
02.05.2016, 22:46 #30
Преобразования типов действительно опасная штука, но не стоит нагонять панику, совместимость char* с другими типами никто не отменял.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <iostream>
 
using namespace std;
 
double const e_const = 2.7182818284590451;
double e_var;
 
template<typename T>
void test(void *v)
{ 
    e_var = 3.14159;
    for (unsigned i = 0; i < sizeof(double)/sizeof(T); ++i)
        *((T*)v + i) = *((T*)&e_const + i);
    cout << e_var << endl;
}
 
 
int main()
{
    test<int>(&e_var);
    test<char>(&e_var);
}
Если скомпилировать эту программу с помощью GCC с ключом -O0 или -O1, то программа 2 раза ожидаемо напечатает число e, если же скомпилировать с ключами -O2 или -O3, то программа напечатает один раз число пи (ну или вправе напечатать) и один раз число e (поскольку обращение через char* легально к любым данным).
0
02.05.2016, 22:46
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
02.05.2016, 22:46
Привет! Вот еще темы с ответами:

Использование переменной типа char в цикле for - C++
Ребята, подскажите пожалуйста, как использовать 8-ми битную переменную в цикле for? Неправильный пример - for(char i = 0; i &lt; N; i++)

Сравнение строки в структуре с переменной типа char - C++
Есть некая функция Х которая возвращает кол-во строк структуры Poezda a, строка a.StNazn в которой равна введеному с клавиатуры c и создает...

"Значение типа float* нельзя использовать для инициализации сущности типа float" - C++
#include &lt;math.h&gt; #include&lt;iostream&gt; #include &lt;iomanip&gt; #include&lt;conio.h&gt; using namespace std; ...

Использование знака пробел при вводе переменной типа char[] - C++
Доброго времени суток! При идентификации переменных при применении знака пробел, все, что идет до него &quot;уходит&quot; в первую переменную,...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
30
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru