Форум программистов, компьютерный форум, киберфорум
Наши страницы
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
Tsegorah
1 / 1 / 0
Регистрация: 02.03.2014
Сообщений: 97
1

Тип float нельзя сдвигать?

06.04.2017, 21:08. Просмотров 373. Ответов 11
Метки нет (Все метки)

Пытаюсь сделать так:
C++
1
2
3
4
5
6
7
8
9
float data[21];
...
    f.open("primerus_bit.txt", ios_base::out | ios_base::trunc | ios::binary);
    for (int i = 0; i < 21; i++) {
        for (int j = 0; j < 32; j++)
            f << ((data[i]<<j)&0x00000001) ? "1" : "0";
        f << endl;
    }
    f.close();
Синтаксис подсвечивается с ошибкой, что "выражение должно относиться к целочисленному типу или типу перечисления без области видимости". А мне нужно символы 0 или 1 записать в файл в соответствии со значениями бит floatа. Как быть?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
06.04.2017, 21:08
Ответы с готовыми решениями:

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

Ошибка преобразования: значение типа "float *" нельзя присвоить сущности типа "float"
Помогите исправить.Значение типа &quot;float *&quot; нельзя присвоить сущности типа float...

Тип данных float
1) Какое масимальное целое может содержать float? 2) Точность дробной части у...

Тип данных float
Подскажите в каких случаях используют тип данных float. Гугл ничего не дал,...

Тип float в массиве
Доброго времени суток! Объявил float a ; Но при выводе консоль выводит...

11
TheCalligrapher
С чаем беда...
Эксперт CЭксперт С++
4772 / 2429 / 679
Регистрация: 18.10.2014
Сообщений: 4,148
06.04.2017, 21:19 2
Цитата Сообщение от Tsegorah Посмотреть сообщение
Тип float нельзя сдвигать?
Нельзя. Как вы его собрались сдвигать?

Цитата Сообщение от Tsegorah Посмотреть сообщение
Как быть?
Подобрать целочисленный тип, размер которого совпадает с размером типа float и объявить переменную этого типа

C++
1
2
unsigned int i_data;
static_assert(sizeof i_data == sizeof *data);
Скопировать значение типа float в переменную i_data при помощи memcpy

C++
1
memcpy(&i_data, &data[i], sizeof i_data);
Далее анализировать уже значение i_data.

Почему у вас в коде сдвиг влево вместо сдвига вправо - не ясно.

---

Можно вместо memcpy воспользоваться union

C++
1
2
3
4
5
6
union IntFloat { unsigned int i; float f; } u;
static_assert(sizeof u.i == sizeof u.f);
 
...
u.f = data[i];
// И далее анализируем `u.i`
но формально такой способ легален только в С, а не в С++.
1
Evg
Эксперт CАвтор FAQ
19288 / 7147 / 528
Регистрация: 30.03.2009
Сообщений: 20,000
Записей в блоге: 30
06.04.2017, 21:42 3
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
но формально такой способ легален только в С
Это точно? Мне казалось, что в Си это так же некорректно. Это так называемые strict aliasing rules, хотя в стандарте чёрным по белому таких слов нет
0
TheCalligrapher
С чаем беда...
Эксперт CЭксперт С++
4772 / 2429 / 679
Регистрация: 18.10.2014
Сообщений: 4,148
06.04.2017, 21:55 4
Цитата Сообщение от Evg Посмотреть сообщение
Это точно? Мне казалось, что в Си это так же некорректно. Это так называемые strict aliasing rules, хотя в стандарте чёрным по белому таких слов нет
По-моему эта тема всплывает уже в сотый раз. Явное разрешение на использование union для "type punning" было добавлено в Technical Corrigendum 3 для стандарта C99 в процессе разрешения Defect Reports №257 и №283. Использование union для этой цели официально разрешено в С и компиляторы не имеют права применять правила strict aliasing внутри union.

Вообще-то даже оригинальный C89/90 говорит: "With one exception, if a member of a union object is accessed after a value has been stored in a different member of the object, the behavior is implementation-defined." Т.е. даже в C89/90 поведение не является неопределенным, а определяется реализацией.
5
Max Dark
шКодер самоучка
1968 / 1745 / 860
Регистрация: 09.10.2013
Сообщений: 3,854
Записей в блоге: 6
Завершенные тесты: 2
06.04.2017, 22:02 5
Немного шаблонной магии
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include <iostream>
#include <cstdint>
 
template<typename T>
struct size_tool {
    enum { size = sizeof(T) };
    union type {
        T orig;
        int8_t array[size];
    };
};
 
int main() {
    using sz_tool = size_tool<float>;
    
    std::cout << sizeof(size_tool<float>::type) << std::endl;
    std::cout << sizeof(size_tool<double>::type) << std::endl;
    
    sz_tool::type test;
    test.orig = 3.14f;
    
    for (auto part : test.array) {
        for(size_t i = 1; i <= (1 << 8); i <<= 1) {
            std::cout << bool(part & i);
        }
    }
    
    return 0;
}
0
rikimaru2013
C++ Game Dev
2472 / 1141 / 348
Регистрация: 30.11.2013
Сообщений: 3,709
06.04.2017, 22:08 6
Max Dark, запись в одну переменную, чтение с другой. Разве не UB это сударь?
1
Tsegorah
1 / 1 / 0
Регистрация: 02.03.2014
Сообщений: 97
06.04.2017, 22:32  [ТС] 7
Что значит строка
C++
1
static_assert(sizeof i_data == sizeof *data);
? У меня без неё работает всё, а на неё ругается среда.
И ещё, почему в моё коде в файл не записывается символ конца строки?
C++
1
2
3
4
5
6
7
8
9
    fstream f2("primerus_bit.txt", ios_base::out | ios_base::trunc | ios::binary);
    for (int i = 0; i < 21; i++) {
        for (int j = 0; j < 32; j++) {
            memcpy(&i_data, &data[i], sizeof i_data);
            f2 << ((i_data >> 32 - j) & 0x00000001) ? "1" : "0";
        }
        f2 << endl;
    }
    f2.close();
0
TheCalligrapher
С чаем беда...
Эксперт CЭксперт С++
4772 / 2429 / 679
Регистрация: 18.10.2014
Сообщений: 4,148
06.04.2017, 23:09 8
Цитата Сообщение от Tsegorah Посмотреть сообщение
а на неё ругается среда
Как именно она ругается? Почему не процитировано сообщение об ошибке?

Цитата Сообщение от Tsegorah Посмотреть сообщение
не записывается символ конца строки?
Что значит "не записывается"? У вас файл открыт в бинарном режиме, что означает, что символ \n будет туда записан именно как единственный символ \n, без трансляции в системно-зависимое соглашение о формате символа конца строки. Т.е. на Windows, например, записан будет именно и только символ 10, а не требуемое Windows сочетание CR-LF (13-10, \r\n). Откройте файл в бинарном просмотрщике и убедитесь, что все туда прекрасно записывается.

Если вы открыли файл в бинарном режиме, то записывать туда правильный системно-зависимый конец строки - ваша задача. Но возникает вопрос: а с чего это вдруг вы его открывали в бинарном режиме? Зачем?
0
Tsegorah
1 / 1 / 0
Регистрация: 02.03.2014
Сообщений: 97
07.04.2017, 22:20  [ТС] 9
Для самопроверки написал программу, которая из файла float-ов делает файл строк с символами '0' и '1', а затем перегоняет обратно во float-ы. Исходный и итоговый файлы должны совпадать, но они разные. Где ошибка? Видимо, только последняя часть с записью в файл не работает, так как data и data2 совпадают.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#include "stdafx.h"
#include <string>
#include <fstream>
#include <iostream>
using namespace std;
 
int main()
{
    setlocale(LC_ALL, "rus");
    fstream f, f2;
    float data[1024], data2[1024];
    unsigned int i_data;
    char c;
    string s;
    //static_assert(sizeof i_data == sizeof *data);
 
    //чтение single
    f.open("infile.txt", ios_base::in);
    for (int i = 0; i < 1024; i++)
        f.read((char*)&data[i], sizeof(data[0]));
    f.close();
 
    //запись bit
    f.open("rez.txt", ios_base::out | ios_base::trunc);
    for (int i = 0; i < 1024; i++) {
        memcpy(&i_data, &data[i], sizeof i_data);
        for (int j = 0; j < 32; j++) {
            f << ((i_data >> 31 - j) & 0x00000001) ? "1" : "0";
        }
        f << endl;
    }
    f.close();
 
    //чтение bit
    f.open("rez.txt", ios_base::in);
    for (int i = 0; i < 1024; i++) {
        i_data = 0;
        for (int j = 0; j < 32; j++) {
            f >> c;
            i_data = i_data << 1;
            if (c == '1')
                i_data = i_data | 1;
        }
        memcpy(&data2[i], &i_data, sizeof i_data);
    }
    f.close();
 
    //запись single
    f.open("outfile.txt", ios_base::out | ios_base::trunc);
    for (int i = 0; i < 1024;i++)
        f.write((char*)&data2[i], sizeof(data2[0]));
    f.close();
    
    int ma = 0;
    for (int i = 0; i < 1024; i++)
        if (abs(data[i] - data2[i])>ma)
            ma = abs(data[i] - data2[i]);
    cout << ma << endl;
    system("pause");
    return 0;
}
0
Вложения
Тип файла: txt infile.txt (4.0 Кб, 2 просмотров)
Тип файла: txt outfile.txt (4.0 Кб, 0 просмотров)
TheCalligrapher
С чаем беда...
Эксперт CЭксперт С++
4772 / 2429 / 679
Регистрация: 18.10.2014
Сообщений: 4,148
07.04.2017, 22:37 10
Цитата Сообщение от Tsegorah Посмотреть сообщение
C++
1
2
3
f.open("infile.txt", ios_base::in);
...
f.open("outfile.txt", ios_base::out | ios_base::trunc);
Вот именно здесь надо открывать файлы, как бинарные. Расширение .txt сбивает с толку, ибо никакие они у вас не текстовые.
1
Tsegorah
1 / 1 / 0
Регистрация: 02.03.2014
Сообщений: 97
07.04.2017, 23:01  [ТС] 11
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Вот именно здесь надо открывать файлы, как бинарные.
Заработало, спасибо.
А почему? f.read и f.write не просто копируют биты файла в переменную, а как-то преобразуют их в зависимости от режима открытия?
0
TheCalligrapher
С чаем беда...
Эксперт CЭксперт С++
4772 / 2429 / 679
Регистрация: 18.10.2014
Сообщений: 4,148
07.04.2017, 23:10 12
Цитата Сообщение от Tsegorah Посмотреть сообщение
А почему? f.read и f.write не просто копируют биты файла в переменную, а как-то преобразуют их в зависимости от режима открытия?
Таковы правила. Если файл открыт в текстовом режиме, то производится распознавание и преобразование символов конца строки как при чтении, так и при записи. Это выполняется на самом нижнем уровне. т.е. даже сишные fread и fwrite так себя ведут.
0
07.04.2017, 23:10
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
07.04.2017, 23:10

Почему 5/9=0, если тип float?
Объектно-ориентированное программирование в С++ Лафоре Р. 3 глава, упрожнение...

Тип памяти переменной float
Доброго время суток всем! помоги найти ответ на вопрос, что за тип памяти...

тип float и вывод остатка через a % b
Можно ли вывести остаток таким способом, если тип всех переменных FLOAT. ...


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

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

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