Форум программистов, компьютерный форум CyberForum.ru

Хитрости с указателями - C++

Восстановить пароль Регистрация
 
Рейтинг: Рейтинг темы: голосов - 11, средняя оценка - 4.91
DiabloRossi
2 / 2 / 0
Регистрация: 09.02.2011
Сообщений: 49
27.02.2011, 12:48     Хитрости с указателями #1
Всем ку.
Требуется небольшой хелп.
Сама задача проста. суть ее такова:
Нужно вывести двоичное представление числа с плавающей точкой.
Т.е. мы вводим 0.0256, он нам выводит то, что хранится в памяти в двоичном виде.
Ну и + пара оговорок в условиях задачи, что нельзя использовать дополнительные переменные, а можно только побитовые операции, типа операции сдвига.
Короче говоря, вот в чем проблема:
Переменные с плавающей точкой у нас обычно хранятся в типах float и double, я лично использую float. Но для этих типов нельзя использовать побитовый сдвиг.
В этом-то проблема и состоит.
Я знаю, как-то можно решить эту проблему через указатели в теории. Т.е. мы обманываем компилятор и говорим ему, что это не указатель на тип float, а вообще указатель на int, и сдвигаем.
Но как при этом реализовать программу без использования лишних переменных, и как в практике реализуется это "обмануть компилятор" без понятия.
Может кто подскажет?
программа-то сама полюбому строчек на 10)
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
27.02.2011, 12:48     Хитрости с указателями
Посмотрите здесь:

Проблема с указателями. C++
задача с Указателями C++
C++ помогите с указателями
C++ Проблема с указателями
C++ Непонятка с указателями
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
lemegeton
 Аватар для lemegeton
2910 / 1339 / 133
Регистрация: 29.11.2010
Сообщений: 2,720
27.02.2011, 13:54     Хитрости с указателями #2
Быдыщ?
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <cstdio>
 
typedef unsigned int IntegerType;
int main(int argc, char *argv[]) {
  float number = 127.001;
 
  if (sizeof(IntegerType) < sizeof(number)) {
    printf("On your platform sizeof IntegerType is less than "
           "size of float. Please change definition of IntegerType.\n");
    return 1;
  }
 
  for (int i = sizeof(number) * 8 - 1;  i >=0; --i)
    printf("%d", (*(IntegerType*)(&number) & (1 << i)) >> i);
  printf("\n");
 
  return 0;
}
DiabloRossi
2 / 2 / 0
Регистрация: 09.02.2011
Сообщений: 49
27.02.2011, 14:48  [ТС]     Хитрости с указателями #3
Цитата Сообщение от lemegeton Посмотреть сообщение
Быдыщ?
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <cstdio>
 
typedef unsigned int IntegerType;
int main(int argc, char *argv[]) {
  float number = 127.001;
 
  if (sizeof(IntegerType) < sizeof(number)) {
    printf("On your platform sizeof IntegerType is less than "
           "size of float. Please change definition of IntegerType.\n");
    return 1;
  }
 
  for (int i = sizeof(number) * 8 - 1;  i >=0; --i)
    printf("%d", (*(IntegerType*)(&number) & (1 << i)) >> i);
  printf("\n");
 
  return 0;
}
О, отлично..
Теперь пара вопросов по коду, если вы не против.
Вообще прога работает и так:
C++
1
2
3
4
5
6
7
8
9
10
11
#include <cstdio>
 
int main(int argc, char *argv[]) {
  float number = 127.001;
 
  for (int i = sizeof(number) * 8 - 1;  i >=0; --i)
    printf("%d", (*(int*)(&number) & (1 << i)) >> i);
  printf("\n");
 
  return 0;
}
Зачем в проге вот это:
C++
1
2
3
4
5
  if (sizeof(IntegerType) < sizeof(number)) {
    printf("On your platform sizeof IntegerType is less than "
           "size of float. Please change definition of IntegerType.\n");
    return 1;
  }
А также не против был бы, если бы вы объяснили, почему это именно так:
C++
1
int i = sizeof(number) * 8 - 1
Я так понимаю это мы берем кол-во элементов, умножаем на 8(ибо по 8 бит каждая цифра представится), зачем вычитаем 1? Вычитаем, потому что "." нас не интересует?
И как работает вот это:
C++
1
(*(IntegerType*)(&number) & (1 << i)) >> i
мы берем указатель на число флоат, приводим к типу int, а вот дальше для меня загадка)
C++
1
& (1 << i)) >> i
Добавлено через 20 минут
До кучи, еще вопрос)
Вот так перестает работать, после ввода вылетает, почему?
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
#include <cstdio>
 
int main(int argc, char *argv[]) {
 
    float number;
    printf("Enter you value:\n");
    scanf("%f", number);
 
    for (int i = sizeof(number) * 8 - 1;  i >=0; --i)
    printf("%d", (*(int*)(&number) & (1 << i)) >> i);
 
    return 0;
}
И еще, если в вашем варианте вместо числа 127.001, поставить число -127.001
он переведет правильно, но знак минус тоже выведет, так и должно быть?)
Ma3a
Эксперт C++
612 / 456 / 31
Регистрация: 28.01.2011
Сообщений: 605
27.02.2011, 14:52     Хитрости с указателями #4
вместо scanf("%f", number); должно быть scanf("%f", &number); потому он и ругается, что вы неинициализированную переменную передаете
DiabloRossi
2 / 2 / 0
Регистрация: 09.02.2011
Сообщений: 49
27.02.2011, 14:55  [ТС]     Хитрости с указателями #5
Так, с этим разобрался, да)
совсем об этом забыл.
lemegeton
 Аватар для lemegeton
2910 / 1339 / 133
Регистрация: 29.11.2010
Сообщений: 2,720
27.02.2011, 22:55     Хитрости с указателями #6
Цитата Сообщение от DiabloRossi Посмотреть сообщение
Зачем в проге вот это:
Это проверка, что представляемый тип по размеру (количеству чаров) совпадает с флоатом.
Цитата Сообщение от DiabloRossi Посмотреть сообщение
И еще, если в вашем варианте вместо числа 127.001, поставить число -127.001
он переведет правильно, но знак минус тоже выведет, так и должно быть?)
Я не случайно взял в качестве приводимого типа unsigned int. Кстати, в цикле переменная i должна быть такого же типа.

Если коротенько, то просто проходим по всем битам числа с 31 (потому что 4 байта умножить на 8 бит минус 1) по 0 (отсюда и минус 1, потому что с нуля считаем).
Каждую итерацию цикла формируется число со всеми нулями и одной единицей в i-том разряде (1 << i). При операции & (битовое "И") с исходным числом, представленным, как целое беззнаковое число получится либо то же самое сформированное число, либо ноль. Сдвиг обратно на то же количество разрядов ( >> i) дает как раз единицу или ноль в первом разряде, то бишь обычное число 1 или 0, которое и выводится.

Вы уж меня извините, но мне откровенно лень разжевывать битовые операции еще подробней и, похоже, у вас слегка некорректные представления о том, как представлены числа в бинарной СС.
Yandex
Объявления
27.02.2011, 22:55     Хитрости с указателями
Ответ Создать тему
Опции темы

Текущее время: 20:27. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru