次の2の累乗に切り上げ


189

次の2のべき乗の数を返す関数を書きたいのですが。たとえば、入力が789の場合、出力は1024になるはずです。ループを使用せずにビット演算子を使用するだけでこれを実現する方法はありますか?


4
可能な解決策については、こちらを参照してください
Stefan

4
明確にするために、最も近い2の累乗(つまり、65は64を与えますが、100は128を与えます)またはそれよりも上の(つまり、65は128を与え、したがって100も与えます)を必要としますか?
Kim Reece、

1
彼らはこれに一致する複数の質問です。たとえば、次のようにstackoverflow.com/questions/364985/...
ヤンDroneaud


7
@Nathanあなたのリンクはこの質問より8ヶ月遅れています。
ジョセフクインジー2014年

回答:


148

Bit Twiddling Hacksを確認してください。2を底とする対数を取得し、それに1を加える必要があります。32ビット値の例:

次の2のべき乗に切り上げる

unsigned int v; // compute the next highest power of 2 of 32-bit v

v--;
v |= v >> 1;
v |= v >> 2;
v |= v >> 4;
v |= v >> 8;
v |= v >> 16;
v++;

他の幅への拡張は明白であるはずです。


11
多くのプロセッサーには先行ゼロをカウントする特別な命令があり、これを使用してlog2を非常に効率的に計算できるため、これは最も効率的なソリューションではありません。en.wikipedia.org/wiki/Find_first_setを
Simon

7
@Simon:ポータブルなソリューションです。すべてのアーキテクチャに共通の効率的なアルゴリズムはありません
phuclv 2013

5
数値自体が2の累乗である場合はどうなりますか?
Litherum 2013

5
このスレッドはまだよく参照されていますが、この回答(および他のほとんど)は非常に古くなっています。CPUには、これを助けるための命令があります(実際には、その時点ですでにですか?)。From:jameshfisher.com/2018/03/30/round-up-power-2.html uint64_t next_pow2(uint64_t x) { return x == 1 ? 1 : 1<<(64-__builtin_clzl(x-1)); }そして32ビットのuint32_t next_pow2(uint32_t x) { return x == 1 ? 1 : 1<<(32-__builtin_clz(x-1)); }場合:これは、GCC(およびClangだと思いますか?)を使用している場合ですが、時間をかけてすべてのオプションをコピーして貼り付けるのではなく、CLZの呼び出しを見つけます。
MappaM

2
@MappaMこの回答は依然として関連性が高く、それを実行するための最適なポータブルな方法です。64ビットバージョンx > UINT32_MAXは、ブランチレスでない場合、未定義の動作をします。また、GCCとClangは-mtune=genericデフォルトで(ほとんどのディストリビューションと同様に)使用するため、コードはlzcntx86_64 の命令に展開されません-march=native。そのため、提案された交換は、移植不可能でバグが多く、(通常)遅くなります。
クレイグバーンズ

76
next = pow(2, ceil(log(x)/log(2)));

これは、xを取得するために2で発生させた数値を見つけることによって機能します(数値の対数を取り、目的の基数の対数で除算します。詳細については、ウィキペディアを参照してください)。次に、それをceilで切り上げて、最も近い整数のパワーを取得します。

これは、他の場所でリンクされているビットごとのメソッドよりも汎用的な(つまり、遅い!)メソッドですが、数学について知っておくと良いでしょう。


3
C99からは、ツールでサポートされている場合は、log2を使用することもできます。GCCとVSは次のようには見えません:(
Matthew Read

2
括弧がない... next = pow(2、ceil(log(x)/ log(2)));
Matthieu Cormier 2012

13
ただし、フロート精度には注意してください。 log(pow(2,29))/log(2)= 29.000000000000004なので、結果は2 29を返す代わりに 2 30になります。これがlog2関数が存在する理由だと思いますか?
エンドリス

48
これのコストはおそらく少なくとも200サイクルであり、それも正しくありません。なぜこれは非常に多くの賛成票を持っているのですか?
Axel Gneiting 2015

4
@SuperflyJonしかし、ビット単位の演算子について言及しており、特に明記しない限り、正しさは質問によって暗示されると思います。
BlackJack

50
unsigned long upper_power_of_two(unsigned long v)
{
    v--;
    v |= v >> 1;
    v |= v >> 2;
    v |= v >> 4;
    v |= v >> 8;
    v |= v >> 16;
    v++;
    return v;

}

62
あなたがそれを(あなたがそれを発見したのでなければ)それを帰因させたならば、素晴らしいでしょう。それはハックページを少しいじるから来ています。
フローリン

3
これは32ビットの数値用ですか?64ビットの拡張?
ジョナサンレフラー

ジョナサン、あなたは上半分のためにそれをする必要があり、それがゼロなら、あなたは下半分のためにそれをします。
フローリン

5
@ florin、vが64ビット型の場合、16の後に「c | = v >> 32」を追加することはできませんか?
エヴァンテラン

3
特定のビット幅でのみ機能するコードでは、最小幅タイプではなく固定幅タイプを使用する必要があります。この関数はを受け取って返す必要がありuint32_tます。
クレイグバーンズ

50

私もこれはうまくいくと思います:

int power = 1;
while(power < x)
    power*=2;

そして答えはpowerです。


19
公平に質問すると、ループはありません。しかし、他のいくつかの関数と同じくらい賢いですが、パフォーマンスに影響されないコードの場合、迅速かつ容易に理解され、正しいことが検証された答えが常に私にとって有利です。
Tim MB

2
これは最も近い2の累乗を返すわけではありませんが、その累乗はXよりすぐに大きくなります。それでも非常に良い
CoffeDeveloper

1
乗算する代わりに、ビット単位の「マジック」を代わりに使用できますpower <<= 1
vallentin

5
@Vallentinコンパイラによって自動的に最適化される必要があります。
MarkWeston 2017年

4
xが大きすぎる(つまり、次の2の累乗を表すのに十分なビットがない)場合は、無限ループに注意してください。
アルバン

36

GCCを使用している場合は、Lockless Inc.によるnext_pow2()関数の最適化を確認することをお勧めします。このページでは、組み込み関数builtin_clz()(カウントリーディングゼロ)を使用し、後でx86(ia32)を直接使用する方法について説明します。別の回答gamedevサイトへリンクでbsr説明されているのと同じように、アセンブラー命令(ビットスキャンリバース)。このコードは、前の回答で説明されているコードよりも高速な場合があります

ちなみに、アセンブラ命令と64ビットデータ型を使用しない場合は、これを使用できます。

/**
 * return the smallest power of two value
 * greater than x
 *
 * Input range:  [2..2147483648]
 * Output range: [2..2147483648]
 *
 */
__attribute__ ((const))
static inline uint32_t p2(uint32_t x)
{
#if 0
    assert(x > 1);
    assert(x <= ((UINT32_MAX/2) + 1));
#endif

    return 1 << (32 - __builtin_clz (x - 1));
}

3
これは、xに等しいORより大きい2の最小の累乗を返すことに注意してください。(x -1)をxに変更すると、xより大きい2の小さいべき乗を返すように関数が変更されます。
ギヨーム

2
_BitScanForwardVisual C ++で使用できます
KindDragon

次も使用できます__builtin_ctz()
MarkP '31 / 03/31

@MarkP __builtin_ctz()は、2のべき乗以外の数値を次の2のべき乗に切り上げるのに役立ちません
Yann Droneaud

2
回答に、他のコンパイラ用の組み込みのビット単位関数のWikipediaリストへのリンクを追加して                                ください:en.wikipedia.org/wiki/Find_first_set#Tool_and_library_support 64ビットバージョンも提供してください。私は、次のC ++ 11機能を提案:              constexpr uint64_t nextPowerOfTwo64 (uint64_t x) { return 1ULL<<(sizeof(uint64_t) * 8 - __builtin_clzll(x)); }
olibre

15

もう1つ、サイクルを使用していますが、算術演算よりもはるかに高速です。

2つの累乗の「フロア」オプション:

int power = 1;
while (x >>= 1) power <<= 1;

2つの累乗「ceil」オプション:

int power = 2;
x--;    // <<-- UPDATED
while (x >>= 1) power <<= 1;

更新

コメントで述べたように、 ceil、その結果がどこに間違っているのかありました。

ここに完全な機能があります:

unsigned power_floor(unsigned x) {
    int power = 1;
    while (x >>= 1) power <<= 1;
    return power;
}

unsigned power_ceil(unsigned x) {
    if (x <= 1) return 1;
    int power = 2;
    x--;
    while (x >>= 1) power <<= 1;
    return power;
}

2
x2の累乗である場合、結果は正しくありません。入力が2の累乗であるかどうかをテストするマイクロが必要です。#define ISPOW2(x) ((x) > 0 && !((x) & (x-1)))
pgplus1628

@zorksylarをより効率的にするにはif (x == 0) return 1; /* Or 0 (Which is what I use) */ x--; /* Rest of program */
yyny

良い解決策!しかし、これpower of two "ceil" optionは正しくありません。たとえばx = 2、結果を次のよう2にする必要がある場合4
MZD

10

署名されていないタイプの場合、Bit Twiddling Hacksに基づいて構築します。

#include <climits>
#include <type_traits>

template <typename UnsignedType>
UnsignedType round_up_to_power_of_2(UnsignedType v) {
  static_assert(std::is_unsigned<UnsignedType>::value, "Only works for unsigned types");
  v--;
  for (size_t i = 1; i < sizeof(v) * CHAR_BIT; i *= 2) //Prefer size_t "Warning comparison between signed and unsigned integer"
  {
    v |= v >> i;
  }
  return ++v;
}

コンパイラはコンパイル時に反復回数を知っているため、実際にはループはありません。


4
質問はC.程度であることに注意してください
martinkunev

@martinkunev UnsignedTypeを置き換えて手動で処理するだけです。Cプログラマーがstd::is_unsigned<UnsignedType>::valueアサーションを無視してこの単純なテンプレートを拡張できると確信しています。
user877329 2017年

2
@ user877329確かに、誰かがCにそれを翻訳したいだけの場合には、同様のJavascriptで答えを持っていいだろう
martinkunev

JavaScriptの@martinkunev UnsignedType?とにかく、このソリューションは、UnsignedTypeに対してそれを行う方法を示しており、偶然に[UnsignedTypeのオブジェクトのビット数のようなものではなく、sizeof(v)* CHAR_BIT]ではなくC ++で記述されています。
user877329 2017年

9

IEEE floatの場合、このようなことを行うことができます。

int next_power_of_two(float a_F){
    int f = *(int*)&a_F;
    int b = f << 9 != 0; // If we're a power of two this is 0, otherwise this is 1

    f >>= 23; // remove factional part of floating point number
    f -= 127; // subtract 127 (the bias) from the exponent

    // adds one to the exponent if were not a power of two, 
    // then raises our new exponent to the power of two again.
    return (1 << (f + b)); 
}

整数ソリューションが必要で、インラインアセンブリを使用できる場合、BSRはx86で整数のlog2を提供します。設定されている正しいビットの数をカウントします。これは、その数のlog2とまったく同じです。CLZなど、他のプロセッサーにも同様の命令(多くの場合)があり、コンパイラーによっては、作業を行うための組み込み関数が利用できる場合があります。


これは...(私は丸め整数のみにしたい)、これを試してみます本家の質問に関連していない興味深いものです
のNaveen

フロートに関するウィキペディアの記事を読んだ後、それに思いついた。その上、整数精度で平方根を計算するために使用しました。また、いいですが、もっと無関係です。
Jasper Bekkers、2009年

これは、厳密なエイリアシング規則に違反します。一部のコンパイラでは機能しないか、警告が表示される場合があります。
martinkunev 2017

6

質問にもかかわらずcここに私の5セントのタグが付けられています。幸運なことに、C ++ 20にはstd::ceil2and が含まれますstd::floor2ここを参照)。これはconsexprテンプレート関数であり、現在のGCC実装はビットシフトを使用しており、任意の整数の符号なし型で機能します。



5
/*
** http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog
*/
#define __LOG2A(s) ((s &0xffffffff00000000) ? (32 +__LOG2B(s >>32)): (__LOG2B(s)))
#define __LOG2B(s) ((s &0xffff0000)         ? (16 +__LOG2C(s >>16)): (__LOG2C(s)))
#define __LOG2C(s) ((s &0xff00)             ? (8  +__LOG2D(s >>8)) : (__LOG2D(s)))
#define __LOG2D(s) ((s &0xf0)               ? (4  +__LOG2E(s >>4)) : (__LOG2E(s)))
#define __LOG2E(s) ((s &0xc)                ? (2  +__LOG2F(s >>2)) : (__LOG2F(s)))
#define __LOG2F(s) ((s &0x2)                ? (1)                  : (0))

#define LOG2_UINT64 __LOG2A
#define LOG2_UINT32 __LOG2B
#define LOG2_UINT16 __LOG2C
#define LOG2_UINT8  __LOG2D

static inline uint64_t
next_power_of_2(uint64_t i)
{
#if defined(__GNUC__)
    return 1UL <<(1 +(63 -__builtin_clzl(i -1)));
#else
    i =i -1;
    i =LOG2_UINT64(i);
    return 1UL <<(1 +i);
#endif
}

未定義の動作の領域に進入したくない場合、入力値は1から2 ^ 63の間でなければなりません。このマクロは、コンパイル時に定数を設定する場合にも役立ちます。


これはおそらく最悪の解決策です(64ビット定数にULLサフィックスがありません)。これにより、すべてのケースで入力ごとに32個のテストが生成されます。whileループを使用する方が良いので、常により高速または同じ速度になります。
xryl669

1
しかし...入力が定数の場合、これはプリプロセッサによって評価されるため、実行時にZERO演算が行われます。
Michael

4

完全を期すために、ここでは沼地標準Cでの浮動小数点実装を示します。

double next_power_of_two(double value) {
    int exp;
    if(frexp(value, &exp) == 0.5) {
        // Omit this case to round precise powers of two up to the *next* power
        return value;
    }
    return ldexp(1.0, exp);
}

1
ランダムなブラウザー、このコメントを読んだ場合は、このコードを選択してください。これは明らかに最良の答えであり、特別な指示はなく、少しいじる必要はなく、効率的で移植可能な標準的なコードです。他の誰もそれを支持しなかった理由を推測します^^
CoffeDeveloper '25年

5
ランダムなブラウザー。これは、特殊な浮動小数点ハードウェアがない場合、非常に遅くなります。x86では、ビットtwiddlingを使用して、このコードの周りに円を描くことができます。rep bsr ecx,eax; mov eax,0; cmovnz eax,2; shl eax,cl約25倍高速です。
ヨハン

4

整数入力用のC / C ++の効率的なMicrosoft(Visual Studio 2017など)固有のソリューション。最上位の1ビットの場所を確認する前にデクリメントすることにより、入力が2の累乗の値と正確に一致するケースを処理します。

inline unsigned int ExpandToPowerOf2(unsigned int Value)
{
    unsigned long Index;
    _BitScanReverse(&Index, Value - 1);
    return (1U << (Index + 1));
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

#if defined(WIN64) // The _BitScanReverse64 intrinsic is only available for 64 bit builds because it depends on x64

inline unsigned long long ExpandToPowerOf2(unsigned long long Value)
{
    unsigned long Index;
    _BitScanReverse64(&Index, Value - 1);
    return (1ULL << (Index + 1));
}

#endif

これにより、次のようなIntelプロセッサ用に5つほどのインライン化された命令が生成されます。

dec eax
bsr rcx, rax
inc ecx
mov eax, 1
shl rax, cl

どうやら、Visual Studio C ++コンパイラは、これをコンパイル時の値に対して最適化するようにコード化されていませんが、そこには多くの命令があるようではありません。

編集:

1の入力値で1(2の0乗)が必要な場合、上記のコードを少し変更しても、分岐のないストレートスルー命令が生成されます。

inline unsigned int ExpandToPowerOf2(unsigned int Value)
{
    unsigned long Index;
    _BitScanReverse(&Index, --Value);
    if (Value == 0)
        Index = (unsigned long) -1;
    return (1U << (Index + 1));
}

あと数個の命令を生成します。コツは、インデックスをcmove命令が後に続くテストで置き換えることができるということです。


小さな間違い:1対1を返すはずですが、そうではありません。
0kcats 2018

ありがとう。それが開発されたアプリケーションでは、1が入力されたときに2の1乗を明示的に必要としました。1は、想像以上に多くの命令を生成せずに、条件付きの特殊なケースと見なすことができます。
NoelC、

1の入力値に1を返し、バージョン含めるように答えを更新しました
NoelC

3

x86では、sse4ビット操作命令を使用して高速化できます。

//assume input is in eax
popcnt edx,eax
lzcnt ecx,eax
cmp edx,1
jle @done       //popcnt says its a power of 2, return input unchanged
mov eax,2
shl eax,cl
@done: rep ret

cでは、一致する組み込み関数を使用できます。


役に立たないがすごい!
マルコ

3

これがCの私の解決策です。これが役に立てば幸いです!

int next_power_of_two(int n) {
    int i = 0;
    for (--n; n > 0; n >>= 1) {
        i++;
    }
    return 1 << i;
}

0

多くのプロセッサアーキテクチャはlog base 2、非常によく似た動作をサポートしています– count leading zeros。多くのコンパイラには、そのための組み込み関数があります。https://en.wikipedia.org/wiki/Find_first_setを参照してください


最上位のセットビット(= bsr)を見つけることや、先行ゼロをカウントすることではありません。彼は最も近い2の累乗に切り上げたいと考えています。「1を減算してからbsrを実行し、1を左にシフトする」という答えはそれを行います。
Flo

0

あなたが良いコンパイラを持っていると仮定すると、それはこの時点で私の前にそれの手前で少しいじくることができますが、とにかくこれはうまくいきます!!!

    // http://graphics.stanford.edu/~seander/bithacks.html#IntegerLogObvious
    #define SH1(v)  ((v-1) | ((v-1) >> 1))            // accidently came up w/ this...
    #define SH2(v)  ((v) | ((v) >> 2))
    #define SH4(v)  ((v) | ((v) >> 4))
    #define SH8(v)  ((v) | ((v) >> 8))
    #define SH16(v) ((v) | ((v) >> 16))
    #define OP(v) (SH16(SH8(SH4(SH2(SH1(v))))))         

    #define CB0(v)   ((v) - (((v) >> 1) & 0x55555555))
    #define CB1(v)   (((v) & 0x33333333) + (((v) >> 2) & 0x33333333))
    #define CB2(v)   ((((v) + ((v) >> 4) & 0xF0F0F0F) * 0x1010101) >> 24)
    #define CBSET(v) (CB2(CB1(CB0((v)))))
    #define FLOG2(v) (CBSET(OP(v)))

以下のテストコード:

#include <iostream>

using namespace std;

// http://graphics.stanford.edu/~seander/bithacks.html#IntegerLogObvious
#define SH1(v)  ((v-1) | ((v-1) >> 1))  // accidently guess this...
#define SH2(v)  ((v) | ((v) >> 2))
#define SH4(v)  ((v) | ((v) >> 4))
#define SH8(v)  ((v) | ((v) >> 8))
#define SH16(v) ((v) | ((v) >> 16))
#define OP(v) (SH16(SH8(SH4(SH2(SH1(v))))))         

#define CB0(v)   ((v) - (((v) >> 1) & 0x55555555))
#define CB1(v)   (((v) & 0x33333333) + (((v) >> 2) & 0x33333333))
#define CB2(v)   ((((v) + ((v) >> 4) & 0xF0F0F0F) * 0x1010101) >> 24)
#define CBSET(v) (CB2(CB1(CB0((v)))))
#define FLOG2(v) (CBSET(OP(v))) 

#define SZ4         FLOG2(4)
#define SZ6         FLOG2(6)
#define SZ7         FLOG2(7)
#define SZ8         FLOG2(8) 
#define SZ9         FLOG2(9)
#define SZ16        FLOG2(16)
#define SZ17        FLOG2(17)
#define SZ127       FLOG2(127)
#define SZ1023      FLOG2(1023)
#define SZ1024      FLOG2(1024)
#define SZ2_17      FLOG2((1ul << 17))  // 
#define SZ_LOG2     FLOG2(SZ)

#define DBG_PRINT(x) do { std::printf("Line:%-4d" "  %10s = %-10d\n", __LINE__, #x, x); } while(0);

uint32_t arrTble[FLOG2(63)];

int main(){
    int8_t n;

    DBG_PRINT(SZ4);    
    DBG_PRINT(SZ6);    
    DBG_PRINT(SZ7);    
    DBG_PRINT(SZ8);    
    DBG_PRINT(SZ9); 
    DBG_PRINT(SZ16);
    DBG_PRINT(SZ17);
    DBG_PRINT(SZ127);
    DBG_PRINT(SZ1023);
    DBG_PRINT(SZ1024);
    DBG_PRINT(SZ2_17);

    return(0);
}

出力:

Line:39           SZ4 = 2
Line:40           SZ6 = 3
Line:41           SZ7 = 3
Line:42           SZ8 = 3
Line:43           SZ9 = 4
Line:44          SZ16 = 4
Line:45          SZ17 = 5
Line:46         SZ127 = 7
Line:47        SZ1023 = 10
Line:48        SZ1024 = 10
Line:49        SZ2_16 = 17

0

私は2の最も低いパワーを取得しようとして、この関数を作成しました。それがあなたを助けるかもしれません.2の最も近い上位数を得るには、最も近い下位数に2を掛けるだけです

int nearest_upper_power(int number){
    int temp=number;
    while((number&(number-1))!=0){
        temp<<=1;
        number&=temp;
    }
    //Here number is closest lower power 
    number*=2;
    return number;
}

0

Excelに対するPaul Dixonの回答を採用した、これは完全に機能します。

 =POWER(2,CEILING.MATH(LOG(A1)/LOG(2)))

0

@YannDroneaudのバリアントはx==1、x86プレートフォーム、コンパイラ、gccまたはclangに対してのみ有効です。

__attribute__ ((const))
static inline uint32_t p2(uint32_t x)
{
#if 0
    assert(x > 0);
    assert(x <= ((UINT32_MAX/2) + 1));
#endif
  int clz;
  uint32_t xm1 = x-1;
  asm(
    "lzcnt %1,%0"
    :"=r" (clz)
    :"rm" (xm1)
    :"cc"
    );
    return 1 << (32 - clz);
}

0

入力が定数式の場合、これを定数式にするために使用しているのは次のとおりです。

#define uptopow2_0(v) ((v) - 1)
#define uptopow2_1(v) (uptopow2_0(v) | uptopow2_0(v) >> 1)
#define uptopow2_2(v) (uptopow2_1(v) | uptopow2_1(v) >> 2)
#define uptopow2_3(v) (uptopow2_2(v) | uptopow2_2(v) >> 4)
#define uptopow2_4(v) (uptopow2_3(v) | uptopow2_3(v) >> 8)
#define uptopow2_5(v) (uptopow2_4(v) | uptopow2_4(v) >> 16)

#define uptopow2(v) (uptopow2_5(v) + 1)  /* this is the one programmer uses */

たとえば、次のような式:

uptopow2(sizeof (struct foo))

定数にうまく還元されます。



0

それを浮動小数点数に変換してから、正規化されたIEEE表現を示す.hex()を使用します。

>>> float(789).hex() '0x1.8a80000000000p+9'

次に、指数を抽出して1を追加します。

>>> int(float(789).hex().split('p+')[1]) + 1 10

そして2をこの累乗します。

>>> 2 ** (int(float(789).hex().split('p+')[1]) + 1) 1024


この回答はPythonであることに注意してください
David Wallace

0
import sys


def is_power2(x):
    return x > 0 and ((x & (x - 1)) == 0)


def find_nearest_power2(x):
    if x <= 0:
        raise ValueError("invalid input")
    if is_power2(x):
        return x
    else:
        bits = get_bits(x)
        upper = 1 << (bits)
        lower = 1 << (bits - 1)
        mid = (upper + lower) // 2
        if (x - mid) > 0:
            return upper
        else:
            return lower


def get_bits(x):
    """return number of bits in binary representation"""
    if x < 0:
        raise ValueError("invalid input: input should be positive integer")
    count = 0
    while (x != 0):
        try:
            x = x >> 1
        except TypeError as error:
            print(error, "input should be of type integer")
            sys.exit(1)
        count += 1
    return count

-1

OpenGL関連のものに必要な場合:

/* Compute the nearest power of 2 number that is 
 * less than or equal to the value passed in. 
 */
static GLuint 
nearestPower( GLuint value )
{
    int i = 1;

    if (value == 0) return -1;      /* Error! */
    for (;;) {
         if (value == 1) return i;
         else if (value == 3) return i*4;
         value >>= 1; i *= 2;
    }
}

8
「for」はループです。
フローリン

1
フロリン:そうです。ここではループとして使われていますね。
Tamas Czinege 2009年

9
DrJokepu-フロリンはここでOPがループのない解決策を求めたと言っていたと思います
Eli Bendersky 2009年

-1

1行テンプレートが必要な場合。ここにあります

int nxt_po2(int n) { return 1 + (n|=(n|=(n|=(n|=(n|=(n-=1)>>1)>>2)>>4)>>8)>>16); }

または

int nxt_po2(int n) { return 1 + (n|=(n|=(n|=(n|=(n|=(n-=1)>>(1<<0))>>(1<<1))>>(1<<2))>>(1<<3))>>(1<<4)); }

これはCまたはC ++での未定義の動作であり、エラーが発生します。nシーケンスポイントなしで複数回変更することは無効です。あなたはそれn-=1が最初に起こるべきであるかのようにそれを書きましたが、ここでの唯一の保証は、n後に新しい値が含まれ;、括弧がそれを変更しないことです。
sam hocevar

さらに、それは私の目を出血させます。
ドナルフェロー
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.