Перевод из десятичной системы с двоичную С++
#include <iostream>
#include <cmath>
using namespace std;
void Translation(int& Number) {
int a = 2;
int i = 0;
while (Number > pow(a, i))
{
i++;
}
int* arr = new int[i];
for (int j = 0; j < i; j++) {
if (Number % 2 == 0) {
arr[j] = 0;
Number /= 2;
}
if (Number % 2 == 1) {
arr[j] = 1;
Number /= 2;
}
}
for (int j = i - 1; j >= 0; j--) {
cout << arr[j] << " ";
}
}
int main()
{
int Number;
cin >> Number;
Translation(Number);
}
Не могу понять, почему у меня неправильно переводит из дясятичной в двоичную. Условно, 10, у меня выводится как "0011". Предполагаю, проблема в цикле for в функции Translation.
Ответы (3 шт):
Самая главная ваша ошибка — что вы после проверки на четность проверяете на нечетность изменившееся число. Смотрите сами для 10 — в первом if вы получаете 5, и тут же идете во второй блок if...
Давайте немного подправим...
#include <iostream>
#include <cmath>
using namespace std;
void Translation(int& Number)
{
int i = 0;
while (Number >= (1<<i)) // 1<<i — то же, что и 2 в степени i
{
i++;
}
int* arr = new int[i];
for (int j = 0; j < i; j++)
{
arr[j] = Number%2;
Number /= 2;
}
for (int j = i - 1; j >= 0; j--) {
cout << arr[j] << " ";
}
}
int main()
{
int Number;
cin >> Number;
Translation(Number);
}
Но я бы предпочел использовать строки, а не массивы. Например, у вас из-за динамически выделяемого массива, который вы не удаляете — утечка памяти. Далее, у вас функция делает два дела: переводит число в другую систему и выводит его. При нормальном проектировании каждая функция должна заниматься своим единственным делом. Так что вот как вариант:
#include <iostream>
#include <cmath>
#include <string>
using namespace std;
string Translation(int Number)
{
if (Number == 0) return "0";
string r;
while(Number)
{
r = char('0' + Number%2) + r;
Number /= 2;
}
return r;
}
int main()
{
int Number;
cin >> Number;
cout << Translation(Number);
}
Для чистых Си можно использовать битовый сдвиг, темболее он работает правильно как с singed так и unsigned интом.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define BITS_IN_INT sizeof(int) * 8
void toBitset(int in, char *out) {
int c, d, t;
t = 0;
if (out == NULL) {
exit(EXIT_FAILURE);
}
for (c = BITS_IN_INT-1 ; c >= 0 ; c--) {
d = in >> c;
*(out+t) = (d & 1) ? '1' : '0';
t++;
}
*(out+t) = '\0';
}
int main()
{
const unsigned size = BITS_IN_INT + 1;
char buffer[size];
memset(buffer, 0, size);
int value;
scanf("%d+", &value);
toBitset(value, buffer);
printf("%s\n", buffer);
return 0;
}
На плюсах вообще не стоит заморачиваться там есть bitset, который в себе содержит полный пакет для работы с битовыми опирациями.
#include <bitset>
int n = 12345; // the number we’ll print out in binary
std::cout << std::bitset<32>(n);
И да... Кончайте эту ересть с делением инта на 2, это не к чему хорошему не приведёт! Как со стороны скорости так и со стороны багов.
Сама идея деления на 2 изначально неверная. Битовый сдвиг - вот что тут нужно. К тому же достаточно написать один шаблон на все целочисленные типы, кроме bool:
#include <string>
#include <iostream>
#include <concepts>
#include <limits>
#include <cstdint>
template<typename T>
concept binreppable = std::integral<T> && !std::same_as<T,bool>;
template<binreppable T>
std::string binrep(T number) {
std::string rep;
rep.reserve(sizeof(T)*8 + 1);
for (int shift = sizeof(T)*8-1; shift >= 0; --shift)
rep.push_back(((number >> shift) & 1) ? '1' : '0');
return rep;
}
int main() {
std::cout
<< binrep(10) << std::endl
<< binrep(0b10) << std::endl
<< binrep(010) << std::endl
<< binrep(0x10) << std::endl
<< binrep(std::numeric_limits<std::int8_t>::max()) << std::endl
<< binrep(std::numeric_limits<std::uint8_t>::max()) << std::endl
<< binrep(std::numeric_limits<std::int16_t>::max()) << std::endl
<< binrep(std::numeric_limits<std::uint16_t>::max()) << std::endl
<< binrep(std::numeric_limits<std::uint32_t>::max()) << std::endl
<< binrep(std::numeric_limits<std::int32_t>::max()) << std::endl
<< binrep(std::numeric_limits<std::uint64_t>::max()) << std::endl
<< binrep(std::numeric_limits<std::int64_t>::max()) << std::endl;
return 0;
}
Таким образом, длина бинарного представления будет соответсовать битовому размеру самого числа. А концепт в шаблоне не даст передать недопустимый тип (C++20).