Почему мы не можем использовать оператор '~' на float - PullRequest
2 голосов
/ 16 апреля 2020

Недавно я столкнулся с оператором '~' в c. Из того, что я собрал, он просто переворачивает все биты данного числа и, таким образом, меняет его значение. Поэтому я поиграл с этим и написал следующий код:

Первая программа

#include <stdio.h>

int main(int argc, char *argv[]){
    int x = 100;
    printf("%d\n", x);
    x = ~x;
    printf("signed value = %d\nunsigned value = %u\n", x, x);
    return 0;
}

с выводом:

100
signed value = -101
unsigned value = 4294967195

Но тогда, Я пытался сделать то же самое с помощью float:

Вторая программа

#include <stdio.h>

int main(int argc, char *argv[]){
    float x = 100;
    printf("%f\n", x);
    x = ~x;
    printf("new value = %f\n", x);
    return 0;
}

, но я получаю ошибку:

tests.c:6:6: error: wrong type argument to bit-complement
  x = ~x;

Итак Я провел небольшое исследование и выяснил, что мы не можем использовать оператор '~' для чисел с плавающей точкой. Это правда? Если это так, то мой вопрос почему?

1 Ответ

0 голосов
/ 17 апреля 2020

Неинтересный и неудовлетворительный ответ - потому что так указан язык:

6.5.3.3 Унарная арифметика c операторы

Ограничения

1 Операнд унарного оператора + или - должен иметь арифметический тип c; оператора ~, целочисленный тип ; оператора !, скалярный тип.

C 2011 Онлайн-черновик

Акцент мой.

Но, почему был указан язык таким образом? Почему допускается только оператор int для оператора ~?

Ну, несколько возможных причин. Во-первых, это не такая уж обычная операция (по крайней мере, по моему личному опыту) - немногие люди, работающие со значениями с плавающей запятой, ужасно заинтересованы в побитовом манипулировании этими значениями. Может быть какая-то проблемная область, в которой он часто используется, но я не видел его за 30 с лишним лет программирования. Если кому-то действительно нужно это сделать, они просто набирают каламбур или отображают число с плавающей точкой на целочисленный тип или массив unsigned char и выполняют там битовые манипуляции, а затем возвращаются к исходному типу с плавающей точкой.

Два формата с плавающей запятой исторически были довольно переменными - хотя сегодня, похоже, все сходились на IEEE 754, еще в 70-х и 80-х разные платформы делали свое дело с плавающей запятой.

Три, помните, что C компилируется в нативный код - хотя современный x86 имеет нативные инструкции для побитовой манипуляции с типами с плавающей запятой, я уверен, что это не относится к аппаратному обеспечению в начало 70-х годов. Вероятно, в сгенерированном коде было достаточно потери производительности, чтобы это не стоило усилий.

...