99 / 52 / 27
Регистрация: 21.05.2012
Сообщений: 1,170
1

Преобразование int в float (битовый перенос)

30.05.2017, 18:16. Показов 5984. Ответов 18

Ребят, нигде в интернете не нашел ответа
Битовые сдвиги с float не работают
Нужно побитово перенести биты INT в float
Так что бы трансформация:
C++
1
2
3
4
5
int I(0x8fa4c756); // Для примера
float F;
I >> F; // Перегруженные битовые переносы из I в F
I << F; // и из F в I;
cout << hex << "0x" << a;
Вывела результат: 0x8fa4c756
(требуется это для генерации случайных дробных чисел)

Как правильно организовать подобную перегрузку?
может через переопределение адресов в динамической памяти?
И если я правильно знаю, то Числа половинной точности в С++ нет.

Число одинарной точности в битовом виде:
Миниатюры
Преобразование int в float (битовый перенос)  
__________________
Помощь в написании контрольных, курсовых и дипломных работ, диссертаций здесь
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
30.05.2017, 18:16
Ответы с готовыми решениями:

Как происходит преобразование int<<float<int
Как происходит преобразование int&lt;&lt;float&lt;int int n=222222222; float f=(float)n; n=(int)f;...

ОШИБКА [Error] cannot convert 'int*' to 'float*' for argument '1' to 'void Syma(float*,int*,int)
Какая то проблема с указателями,незнаю,не хочет щитать суму парних чисел в второй...

Преобразование int в float
Добрый день! int x = 20110511; double a = x; cout&lt;&lt;x&lt;&lt;' '&lt;&lt;a&lt;&lt;'\n'; Результат: 20110511...

Функции float average(int arrray[],int from,int to)
Напишите код функции float average(int arrray,int from,int to). Возвращаемым значением функции...

18
Форумчанин
Эксперт CЭксперт С++
8190 / 5040 / 1437
Регистрация: 29.11.2010
Сообщений: 13,453
30.05.2017, 18:28 2
Цитата Сообщение от eXPonent Посмотреть сообщение
требуется это для генерации случайных дробных чисел
Это сводится к генерации двух целых СЧ.
При поддержке С++11 можно использовать std::uniform_real_distribution<>
1
Заблокирован
30.05.2017, 18:29 3
Что число на картинике, по-моему не соответствует тому, что написано там(0.15625). Я насчитал 2,097152*10123. Где правда?
0
99 / 52 / 27
Регистрация: 21.05.2012
Сообщений: 1,170
30.05.2017, 18:39  [ТС] 4
Цитата Сообщение от MrGluck Посмотреть сообщение
Это сводится к генерации двух целых СЧ
Да, это я понимаю
но все равно, хочется реализовать перегрузку, что бы заглянуть внутрь float
Тогда даже при генерации случайных чисел, для float используя банальный
Цитата Сообщение от nonedark2008 Посмотреть сообщение
Внутри rand() сидит обычный линейный конгруэнтный генератор.
Мы получим, неплохое распределение, принимая во внимание погрешность float

Цитата Сообщение от Programmist5 Посмотреть сообщение
число на картинике
Из англоязычной wiki

Добавлено через 4 минуты
Для float не важно используем ли мы манипуляторы
C++
1
2
3
4
float f(0x2664);
cout << dec << f << endl;
cout << hex << f << endl;
cout << oct << f << endl;
Получаем одинаковый результат в трех случаях

Цитата Сообщение от Programmist5 Посмотреть сообщение
Также будет нарушена целостность данных
Мне важен именно сам побитный перенос
0
1269 / 1026 / 470
Регистрация: 25.12.2016
Сообщений: 3,333
30.05.2017, 18:44 5
Лучший ответ Сообщение было отмечено eXPonent как решение

Решение

Цитата Сообщение от eXPonent Посмотреть сообщение
Нужно побитово перенести биты INT в float
Если я правильно понял, то нужно что-то вроде:
C++
1
F = *reinterpret_cast<float*>(&I);
1
99 / 52 / 27
Регистрация: 21.05.2012
Сообщений: 1,170
30.05.2017, 18:59  [ТС] 6
Написал так:
C++
1
2
3
4
5
// 0011 1110 0010 0000 0000 0000 0000 0000
int I(0x3E200000);
float f;
f = *reinterpret_cast<float*>(&I);
cout << f << endl;
Получил как на картинке
Миниатюры
Преобразование int в float (битовый перенос)  
0
99 / 52 / 27
Регистрация: 21.05.2012
Сообщений: 1,170
30.05.2017, 19:08  [ТС] 7
reinterpret_cast < > ( )

Приводит друг к другу указатели, которые друг от друга не зависят, не меняя константности

Оператор reinterpret_cast является жестко машинно-зависимым. Чтобы безопасно использовать оператор reinterpret_cast, следует хорошо понимать, как именно реализованы используемые типы, а также то, как компилятор осуществляет приведение

Рассмотрим следующий пример приведения
C++
1
2
int * p = ...;
double * d = reinterpret_cast<int *>(p);
Эта инструкция ни во что не компилируется, как и const_cast. Здесь не происходит вызова никакой функции. Это просто указание системе типов, что теперь у нас другой тип

В данном случае следует помнить, что фактическм типов объекта, адрес которого содержит указатель d, является int, а не символьный массив. Любая попытка применения указателя d там, где необходим обычный символьный указатель, вероятнее всего, потерпит неудачу именно во время выполнения. Например, его использование для инициализации объекта типа string приведет к ошибке во время выполнения. Это хороший пример, который служит для демонстрации того, почему явные приведения отнюдь небезопасны. Проблема заключается в том, что при изменении типа компилятор не выдаст никаких предупреждений или сообщений об ошибке. Компилятор не способен выяснить, адрес какого именно значения фактически хранит указатель. Отследить такие ошибки иногда чрезвычайно трудно, особенно если приведение указателя к другому типу происходит в одном файле, а используется указатель - в другом.
0
Заблокирован
30.05.2017, 19:13 8
А как он это число перевел из битового представления, имеется ввиду в десятичное, что-то я никак понять не могу?(Число имеется ввиду то, что на картинке.)
0
99 / 52 / 27
Регистрация: 21.05.2012
Сообщений: 1,170
30.05.2017, 19:16  [ТС] 9
Цитата Сообщение от Programmist5 Посмотреть сообщение
Что число на картинике, по-моему не соответствует тому, что написано там (0.15625). Я насчитал 2,097152*10123. Где правда?
1) Для вычисления показателя степени из восьмиразрядного поля порядка вычитается смещение порядка равное 12710 = 7F16 = 011111112 (то есть, 011111002 - 011111112 = 12410 - 12710 = -310).
2) Так как в нормализованной двоичной мантиссе целая часть всегда равна единице, то в поле мантиссы записывается только её дробная часть.
3) Для вычисления мантиссы к единице добавляется дробная часть мантиссы из 23-х разрядного поля дробной части мантиссы 1,010000000000000000000002.
4) Число равно произведению мантиссы со знаком на двойку в степени порядка = 1,012*210-310 = 1012*210-510 = 510*210-510 = 0,1562510.
1
Заблокирован
30.05.2017, 20:29 10
Е-мое, блин, как сложно считается, раньше вроде проще было или всегда так было?
0
99 / 52 / 27
Регистрация: 21.05.2012
Сообщений: 1,170
30.05.2017, 21:01  [ТС] 11
Это делается для более равномерного распределения числовых значений, на определенных промежутках
При этом получения наибольшего и наименьшего из возможных чисел
Не теряя точности вычислений
0
С чаем беда...
Эксперт CЭксперт С++
9993 / 5345 / 1461
Регистрация: 18.10.2014
Сообщений: 12,864
30.05.2017, 21:02 12
Лучший ответ Сообщение было отмечено eXPonent как решение

Решение

Цитата Сообщение от likehood Посмотреть сообщение
Если я правильно понял, то нужно что-то вроде:
C++
1
F = *reinterpret_cast<float*>(&I);
Это нарушение strict aliasing.

Правильно просто

C++
1
2
// static_assert(sizeof F == sizeof I);
std::memcpy(&F, &I, sizeof F);
или через union, хотя такое использование union формально разрешено только в С.
3
99 / 52 / 27
Регистрация: 21.05.2012
Сообщений: 1,170
30.05.2017, 21:06  [ТС] 13
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Это нарушение strict aliasing
Тогда для чего служит reinterpret_cast !?
0
зомбяк
1562 / 1211 / 344
Регистрация: 14.05.2017
Сообщений: 3,925
30.05.2017, 22:20 14
eXPonent, для более сложных случаев, например при принудительном преобразовании указателя с типом базового класса к указателю на класс-наследник, если нам однозначно известно, что этот указатель на самом деле указывает на класс-наследник. Когда более безопасный dinamic_cast потребовал бы задействования RTTI. И вообще, везде, где memcpy выполнять было бы бессмысленно или вредно.

https://ru.wikipedia.org/wiki/... rpret_cast
0
99 / 52 / 27
Регистрация: 21.05.2012
Сообщений: 1,170
30.05.2017, 23:12  [ТС] 15
Цитата Сообщение от TRam_ Посмотреть сообщение
И вообще, везде, где memcpy выполнять было бы бессмысленно или вредно.
А в этом случае?
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
C++
1
2
// static_assert(sizeof F == sizeof I);
std::memcpy(&F, &I, sizeof F);
или через union, хотя такое использование union формально разрешено только в С.
0
С чаем беда...
Эксперт CЭксперт С++
9993 / 5345 / 1461
Регистрация: 18.10.2014
Сообщений: 12,864
30.05.2017, 23:16 16
Цитата Сообщение от eXPonent Посмотреть сообщение
Тогда для чего служит reinterpret_cast !?
reinterpret_cast может использоваться для переинтерпретации памяти, но только в ряде четко оговоренных случаев. Например, любой тип данных можно переинтерпретировать как массив из unsigned char. Переинтерпретация между int и float в список таких оговоренных случаев не входит.

Также reinterpret_cast выполнять преобразования между указателными и целочисленными типами (результат такого преобразования определяется реализацией). reinterpret_cast позволяет выполнять преобразования между несвязанными указательными типами (с целью последующего обратного преобразования).

И т.п.
0
52 / 30 / 13
Регистрация: 21.05.2017
Сообщений: 109
30.05.2017, 23:27 17
Цитата Сообщение от TRam_ Посмотреть сообщение
ев, например при принудительном преобразовании указателя с типом базового класса к указателю на класс-наследник, если нам однозначно известно, что этот указатель на самом деле указывает на класс-наследник
С этим справится static_cast.
0
99 / 52 / 27
Регистрация: 21.05.2012
Сообщений: 1,170
30.05.2017, 23:43  [ТС] 18
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Это нарушение strict aliasing
Означает ли это, что подобное применение это UB ?
0
С чаем беда...
Эксперт CЭксперт С++
9993 / 5345 / 1461
Регистрация: 18.10.2014
Сообщений: 12,864
31.05.2017, 01:46 19
Цитата Сообщение от TRam_ Посмотреть сообщение
например при принудительном преобразовании указателя с типом базового класса к указателю на класс-наследник, если нам однозначно известно, что этот указатель на самом деле указывает на класс-наследник.
reinterpret_cast не сумеет правильно выполнить такое преобразование в общем случае (например, в условиях множественного наследования). Явные преобразования указателей вниз по иерархии в С++ делает именно static_cast, а не reinterpret_cast.
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
31.05.2017, 01:46
Помогаю со студенческими работами здесь

Почему при умножении разнотипных переменных (например, float и int) получается int?
Почему при умножении разнотипных переменных (float price и int unit) получается int? Это же не...

Необъявленный идентификатор, преобразование "int" в "float"
#define _CRT_SECURE_NO_WARNINGS #include &lt;stdio.h&gt; #include &lt;conio.h&gt; #define N 50 #define M 50...

Int в Float
Доброго времени суток. у меня уже второй раз возник вопрос по поводу перевода Int в Float...

Int в float
Как перевести допустим int v =1 в float b = 0.1? Добавлено через 5 минут Закройте тему


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

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

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2022, CyberForum.ru