Язык Си. Тема: поля бит

Условие задачи: найти и вывести целое число, в 2 раза меньше заданного (с клавиатуры), не выполняя деления и не используя операцию взятия остатка от деления. Написал простенький код, но не знаю, как без деления остатка найти дробную часть числа. Буду благодарен всем, кто сможет подсказать (1 человек мне говорил, что можно просто перевести число в биты и отрезать младший бит).

Код:

#include <stdio.h>
#include <locale.h>

struct field
{
    unsigned int lastbit : 1;
};

int main()
{
    setlocale(LC_ALL, "ru");
    struct field* pointer;
    int k, r;
    float m, n, s;
    printf("Введите исходное число: ");
    scanf_s("%d", &k);
    pointer = (struct field*)&k;
    if (pointer->lastbit)
        r = 1;
    else
        r = 0;
    n = (float)r / 2;
    m = k >> 1;
    s = m + n;
    printf("Уменьшенное в 2 раза число: %g", s);
    return 0;
}

Ответы (3 шт):

Автор решения: Harry

Думаю, имеется в виду целочисленное деление. Тогда

unsigned int x = ....;

unsigned int r = x&1;   // Остаток от деления x на 2

unsigned int q = x>>1;  // Результат деления x на 2
→ Ссылка
Автор решения: gbg
#include <iostream>
#include <cstdint>   //чтобы использовать числа с гарантированной разрядностью
using namespace std;

int main() 
{
    int32_t in;  //всегда отдавайте предпочтение числам
                 //с известной битовой длиной,
                 //если не хотите проблем с переносимостью
    cin >> in;
    //всегда используйте константы, где это возможно
    const bool negative = in < 0;  //флаг того, что число отрицательно
    const uint32_t a    = negative ? - in : //если число отрицательно, 
                                       //будем работать только с его модулем
    const uint32_t half = a >> 1;      //поделили пополам
    const bool odd      = a & 0x1;     //определили, нечетное ли оно
    cout << (negative ? '-':' ') << half << '.' << (odd ? '5' : '0') << endl;
    return 0;
}

https://ideone.com/H8rjAU

→ Ссылка
Автор решения: wololo

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

Остаток от деления — это просто самый младший бит.
Целую часть от деления можно получить сдвинув биты вправо на одну позицию.

int val = ...;
    
int rem_part = val & 1;
int int_part  = val >> 1;

Нахождение остатка работает для любого значения типа int. Хотя для отрицательных значений остаток получается положительным.
Нахождение целой части работает только для неотрицательных значений типа int, т.к. согласно стандарту языка результат сдвига вправо отрицательных значений является implementation-defined.

Для отрицательных величин можно, например, занулить знаковый бит, затем сдвинуть на одну позицию вправо, и, наконец, установить два старших бита в единицы. Получившееся целочисленное значение будет представлять результат деления, округлённый в сторону минус бесконечности.
Если отрицательную величину необходимо округлить в сторону нуля, то просто прибавим остаток от деления.

int val = ...;

int rem_part = val & 1;
int int_part;
if (val >= 0)
    int_part = val >> 1;
else
{
    int_part = val & INT_MAX;
    int_part = int_part >> 1;
    int_part = int_part | INT_MIN | (INT_MAX - (INT_MAX >> 1));
    int_part = int_part + rem_part;
    rem_part = -rem_part;
}

Пример работы для целых чисел из отрезка [-5; 5]:

val: -5,    int_part: -2,    rem_part: -1,    int_part*2+rem_part: -5
val: -4,    int_part: -2,    rem_part:  0,    int_part*2+rem_part: -4
val: -3,    int_part: -1,    rem_part: -1,    int_part*2+rem_part: -3
val: -2,    int_part: -1,    rem_part:  0,    int_part*2+rem_part: -2
val: -1,    int_part:  0,    rem_part: -1,    int_part*2+rem_part: -1
val:  0,    int_part:  0,    rem_part:  0,    int_part*2+rem_part:  0
val:  1,    int_part:  0,    rem_part:  1,    int_part*2+rem_part:  1
val:  2,    int_part:  1,    rem_part:  0,    int_part*2+rem_part:  2
val:  3,    int_part:  1,    rem_part:  1,    int_part*2+rem_part:  3
val:  4,    int_part:  2,    rem_part:  0,    int_part*2+rem_part:  4
val:  5,    int_part:  2,    rem_part:  1,    int_part*2+rem_part:  5
→ Ссылка