Nが2の何乗かを調べる

C++11から標準数学ライブラリに入ったstd::log2()関数を使えば、Nが2の何乗かを取得できます。

#include <iostream>
#include <cmath>

int main()
{
    std::cout << std::log2(4.0) << std::endl;
    std::cout << std::log2(8.0) << std::endl; // 8は2の3乗
    std::cout << std::log2(16.0) << std::endl; // 16は2の4乗
    std::cout << std::log2(32.0) << std::endl;
    std::cout << std::log2(64.0) << std::endl;
    std::cout << std::log2(128.0) << std::endl;
    std::cout << std::log2(256.0) << std::endl;

    std::cout << std::log2(24.0) << std::endl;
    int x = 24;
    if (x <= 0 || (x & (x - 1)) != 0) { // xが2の乗数か判定
        std::cout << "24 is not power of 2" << std::endl;
    }
}

出力:

2
3
4
5
6
7
8
4.58496
24 is not power of 2

修正履歴

  • 2016/12/26 19:20 : 2の乗数かの判定に、std::modf()を使用していましたが、
double integral_part;
if (std::modf(std::log2(24.0), &integral_part) != 0) {
    std::cout << "24 is a not power of 2" << std::endl;
}

@haxeさんに教えていただいて、以下のように修正しました。

int x = 24;
if ((x & (x - 1)) != 0) {
    std::cout << "24 is not power of 2" << std::endl;
}
  • 2016/12/26 21:06 : uskzさんからの指摘を受け、例としてxstd::numeric_limits::min()の場合に2の乗数と判定されてしまうため、暫定対処として正の値かどうかのチェックを追加しました。
  • 2016/12/26 23:24 : uskzさんからの指摘を受け、2の乗数と判定するコードに0を許可していたところを、許可しないよう修正しました。