Подправить код. Представление числа в памяти компьютера

102
09 июля 2021, 07:10

Задача: На языке C/C++ написать программу, которая запрашивает целое число (положительное, отрицательное или ноль), разрядность типа данных и его вид – знаковый или беззнаковый. На выходе программы должно быть представление заданного числа в памяти компьютера. В программе необходимо предусмотреть проверку корректности входных данных.

Вот код:

#include <iostream>
#include <math.h>
#include <vector>
#include <algorithm>
using namespace std;
int main()
{
    setlocale(0, "");
    int num = 0, razr = 0, issig = 0, x = 1, i = 0, num1 = 0;
    vector <int> bin; //тут хранится двоичный вид числа
    cout << "Введите число: ";
    cin >> num;
    num1 = num;
    cout << "Введите разрядность: ";
    cin >> razr;
    cout << "0 - беззнаковый тип, 1 - знаковый: ";
    cin >> issig;
    while (pow(2, x) <= abs(num)) x++; //считает количество занятых битов
    if (razr * 8 < x) cout << "Ошибка" << endl;
    else
    {
        if (issig == 0 && num < 0) cout << "Ошибка" << endl;
        else
        {
            bin.resize(x);
            for (int i = 0; i < x; ++i) //перевод в двоичную систему
            {
                bin[i] = abs(num % 2);
                num = num / 2;
            }
            bin.resize(razr * 8, 0); //добавление нулей
            reverse(bin.begin(), bin.end());
            if (issig == 0) //вывод беззнакового числа
            {
                for (int k = 0; k < bin.size(); k++) cout << bin[k];
            }
            else //вывод знакового числа
            {
                if (num1 >= 0) //знаковое число положительное
                {
                    for (int k = 0; k < bin.size(); k++) cout << bin[k];
                }
                else //знаковое число отрицательное
                {
                    for (int k = 0; k < bin.size(); k++) //обратный код
                    {
                        if (bin[k] == 0) bin[k] = 1;
                        else bin[k] = 0;
                    }
                    for (int k = 0; k < bin.size(); k++) cout << bin[k] << endl;

                    if (bin[bin.size() - 1] == 0) bin[bin.size() - 1] = 1; //если обратный код окнчивается на 0 
                    else //если обратный код оканчивается на 1
                    {
                        reverse(bin.begin(), bin.end());
                        int i = 0;
                        for (int k = 0; k < bin.size(); k++)
                        {
                            if (bin[k] == 0 && i == 0) { i = k; bin[k] = 1; }
                        }
                        for (int k = 0; k < i; ++k)
                        {
                            bin[k] = 0;
                        }
                        reverse(bin.begin(), bin.end());
                    }
                    for (int k = 0; k < bin.size(); k++) cout << bin[k]; //вывод дополнительного кода
                }
            }
        }
    }
    system("pause");
    return 0;
}

Всё ли правильно? Если нет, то помогите исправить, пожалуйста :) Заранее спасибо.

Answer 1

Зачем Вы реализовываете то, что есть в std

Если Вы говорите "На выходе программы должно быть представление заданного числа в памяти компьютера." - то это hex

Вот Вам решение задачи(исключительно взятое из описания)

#include <iostream>
#include <limits>
#include <bitset>

int main() {
    int number{0};
    while(!(std::cin >> number)) {
        std::cin.clear();
        std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
        std::cout << "Invalid input.  Try again: " << std::endl;
    }
    std::cout << std::dec << "dec : " << number << "\n"
              << std::hex << "hex : " << number << "\n" 
              << std::dec << "bin : " << std::bitset<sizeof(number) * 8>(number)
              << std::endl;
    return 0;
}
Answer 2

Если мы говорим о реальном представлении в памяти, то ваш метод не подойдет. Вы оперируете типами данных, а они уже адаптированы компилятором под конкретную платформу и реальное положение вещей искажают (как минимум ваш способ не учитывает endianness, т.е. порядок следования байт в стандартных типах данных, превышающих по размеру один байт).

#include <iostream>
#include <cstdlib>
#include <climits>
int main(int argc, char **argv)
{
    int num;
    unsigned char *ptr = reinterpret_cast<unsigned char *>(&num);
    std::cin >> num;
    for (int i = 0; i < sizeof(num); ++i) {
        for (int j = CHAR_BIT - 1; j >= 0; --j) {
            std::cout << ((ptr[i] >> j) & 1);
        }
    }
    std::cout << std::endl;
    return EXIT_SUCCESS;
}

Как видите, для того, чтобы увидеть представления многобайтного типа в памяти, приходится прибегать к реинтерпретации этого типа в однобайтовый с последующим выводом бит.

Также ваше число всегда хранится в типе int. Зачем в таком случае вводится разрядность и знаковость? Для этих целей еще можно использовать шаблоны, это сильно сэкономит вам время.

P.S.: Задача крайне синтетическая. Я так понимаю, она была поставлена в рамках учебной программы? В реальном применении я бы вам крайне не советовал использовать подходы, которые имеют хоть какое-то отношение к реальному представлению чисел в памяти. Это не нужно, а, зачастую, и опасно.

READ ALSO
Устранение Memory Leak

Устранение Memory Leak

Я начинающий програмист, использующий С++(с надеждой в дальнейшем попасть в GameDev)Так вот, для собеседования была написана игра и хотелось устранить...

95
Как открыть скачанный .ехе файл?

Как открыть скачанный .ехе файл?

Используя библиотеки QNetworkReply и QNetworkAccessManager я скачалexe файл, но не понимаю как его открыть

111