"unsigned long long int"型の変数の値が負のとき

メモ。

test.cc

#include <iostream>
#include <iomanip>
#include <limits> 

int main()
{
    unsigned long long int a = 1;
    unsigned long long int b = 2;
    unsigned long long int c = -1;

    std::cout << std::setw(20) << std::right <<  "1 - 2 = " << a - b << std::endl;
    std::cout << std::setw(20) << std::right <<  "-1 = " << c << std::endl; 
    std::cout << std::setw(20) << std::right <<  "ULLONG_MAX = " << ULLONG_MAX << std::endl;
    return 0;
}

実行

$ g++ test.cc
$ ./a.out
            1 - 2 = 18446744073709551615
               -1 = 18446744073709551615
       ULLONG_MAX = 18446744073709551615

負数は2の補数で表現されるので、2進数だと-1は全ビットが1となる。
その値の型をunsignedにすると、当然ながら最上位ビットも通常の値と解釈されるので、その型のMAX値と同値となる。
上記のtest.ccでは、"unsigned long long int"型の「-1」と"unsigned long long int"型のMAX値を表すULLONG_MAXが同じ値であることを示した。

ULLONG_MAXの定義は /usr/include/i386/limits.h に書かれている

$ grep ULLONG_MAX /usr/include/i386/limits.h
#define ULLONG_MAX      0xffffffffffffffffULL   /* max unsigned long long */
#define UQUAD_MAX       ULLONG_MAX