Разница между ~ и - - PullRequest
0 голосов
/ 19 мая 2018

Так что я возился с кодированием Хаффмана и заметил кое-что, что, как мне кажется, я должен был уже знать, но, к сожалению, не знаю.

Вопрос в названии и связан с этим методом:

void BinWriter::writeBit(bool b) {
    A ^= (-b^A)&(1UL << n++); // A is of type char

    if (n == 8) {
        ofd.write((char*)&A, 1);
        n = 0;
    }
}

Если я напишу ~b вместо -b, результаты будут сильно отличаться.Почему это?Разве ~ не является оператором отрицания?Чем он отличается от - в этом случае?

Кроме того, Visual Studio (2017) также предупреждает меня, что оба эти оператора «небезопасны» для типов bool, почему это так?

1 Ответ

0 голосов
/ 19 мая 2018

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

#include <iostream>
int main()
{
    std::cout << std::boolalpha;
    std::cout << "~: " << ~true << ", " << ~false << "\n";
    std::cout << "-: " << -true << ", " << -false << "\n";
    std::cout << "!: " << !true << ", " << !false << "\n";
}

напечатает

~: -2, -1
-: -1, 0
!: false, true

Обратите внимание, что ! является единственным из этих операторов, который фактически определен для bool, тогда какдва других целочисленных преобразования (с false, превращающимися в 0 и true в 1).

-b^A тогда означает «сохранить все биты одинаково, если b равно false,и переверните их все, если b равно true ", тогда как ~b^A означает" Перевернуть все биты все время, но последний только, если b равен false "- совершенно другая семантика!

...