1

sizeof演算子を使用して、特定のデータ型で表現できる2の最大累乗を計算する方法はC / C ++にありますか?

たとえば、私が持っているとしましょうunsigned short int。その値の範囲は0との間65535です。unsigned short intしたがって、缶に含めることができる2の最大累乗はです32768

これを関数に渡すunsigned short intと、(現時点では)次のようなアルゴリズムがあります。

if (ushortParam > 32768) {
    ushortParam = 32768; // Bad hardcoded literals
}

ただし、将来的には、変数タイプを変更して、2の累乗を組み込むようにしたいと思うかもしれません。sizeof()を使用して、次のことを実現できるタイプに依存しない式はありますか?

if (param > /*Some function...*/sizeof(param) )
{
    param = /*Some function...*/sizeof(param);
}

パラメータが浮動小数点の精度を必要としないことに注意してください-整数のみ。

4

4 に答える 4

4

そのパラメータサイズの変数の最上位ビットを設定すると、2の最大乗が得られます。

1 << (8*sizeof(param)-1)
于 2012-10-20T11:17:06.757 に答える
3

どうですか:

const T max_power_of_two = (std::numeric_limits<T>::max() >> 1) + 1;
于 2012-10-20T11:17:51.517 に答える
2

特定の整数型で表現できる2の最大の累乗を取得するには、演算子limits.hの代わりに使用できます。sizeof例えば:

#include <stdlib.h>
#include <stdio.h>
#include <limits.h>

int main() {

  int max   = INT_MAX;
  int hmax  = max>>1;
  int mpow2 = max ^ hmax;

  printf("The maximum representable integer is %d\n",max);
  printf("The maximum representable power of 2 is %d\n",mpow2);
  return 0;
}

正の整数の右シフトが常に定義されているため、これは常に機能するはずです。標準のCセクション6.5.7.5(ビット単位のシフト演算子)からの引用:

E1 >> E2の結果は、E1がシフトされたE2ビット位置です。E1が符号なし型である場合 、またはE1が符号付き型で非負の値である場合、結果の値は、 E1の商を数量で割ったものの整数部であり、2の累乗はE2です。

の使用sizeofが必須の場合は、次を使用できます。

1 << (CHAR_BIT*sizeof(param)-1)

符号なし整数型の場合:

1 << (CHAR_BIT*sizeof(param)-2)

符号付き整数型の場合。上記の行は、パディングビットのない整数型の場合にのみ機能します。これらのラインが機能することを保証する標準Cの部分は、セクション6.2.6.2にあります。特に:

unsignedchar以外のunsignedintegerタイプの場合、オブジェクト表現のビットは、値ビットとパディングビットの2つのグループに分割されます(後者のいずれかである必要はありません)。N個の値ビットがある場合、各ビットは1から2N-1までの2の異なる累乗を表すため、そのタイプのオブジェクトは、純粋なバイナリ表現を使用して0から2N-1までの値を表すことができます。これは、値表現と呼ばれます。

次の場合に最初のメソッドが機能することを保証します。

符号付き整数型の場合、オブジェクト表現のビットは、値ビット、パディングビット、および符号ビットの3つのグループに分割されます。パディングビットは必要ありません。正確に1つの符号ビットが必要です。

..。

符号ビットがゼロである符号付き整数型の有効な(非トラップ)オブジェクト表現は、対応する符号なし型の有効なオブジェクト表現であり、同じ値を表すものとします。

2行目が正しい答えを与える理由を説明します。

于 2012-10-20T13:01:21.970 に答える
0

受け入れられた答えはおそらくPosixプラットフォームで機能しますが、一般的なC /C++ではありません。CHAR_BITが8であると想定し、タイプを指定せず、タイプにパディングビットがないと想定します。

以下は、任意/すべての符号なし整数型のより一般的なバージョンであり、ヘッダーや依存関係などを含める必要はありません。

#define MAX_VAL(UNSIGNED_TYPE) ((UNSIGNED_TYPE) -1)

#define MAX_POW2(UNSIGNED_TYPE) (~(MAX_VAL(UNSIGNED_TYPE) >> 1))

#define MAX_POW2_VER2(UNSIGNED_TYPE) (MAX_VAL(UNSIGNED_TYPE) ^ (MAX_VAL(UNSIGNED_TYPE) >> 1))

#define MAX_POW2_VER3(UNSIGNED_TYPE) ((MAX_VAL(UNSIGNED_TYPE) >> 1) + 1)

標準では、C90でさえ、-1を符号なし型にキャストすると、その型が表すことができる最大値が常に得られることが保証されています。そこから、上記のすべてのビット演算子が明確に定義されます。

http://c0x.coding-guidelines.com/6.3.1.3.html

6.3.1.3符号付きおよび符号なし整数

682整数型の値を_Bool以外の整数型に変換する場合、新しい型で表現できる場合は変更されません。

683それ以外の場合、新しいタイプが符号なしの場合、値が新しいタイプの範囲内になるまで、新しいタイプで表すことができる最大値より1つ多い値を繰り返し加算または減算することにより、値が変換されます。

684それ以外の場合、新しいタイプは署名され、値を表すことができません。

685結果が実装定義であるか、実装定義のシグナルが発生します。

符号なしタイプの最大値は、2の累乗より1小さい値であり、すべての値ビットが設定されています。上記の式の結果、最上位ビットのみが設定されます。これは、型が表すことができる2の最大累乗です。

http://c0x.coding-guidelines.com/6.2.6.2.html

6.2.6.2整数型

593 unsignedchar以外のunsignedintegerタイプの場合、オブジェクト表現のビットは、値ビットとパディングビットの2つのグループに分割されます(後者のいずれかである必要はありません)。

594 N個の値のビットがある場合、各ビットは1から2 ^(N-1)の間で2の異なる累乗を表す必要があります。そのため、そのタイプのオブジェクトは、純粋なバイナリ表現。

595これは値表現として知られるものとします。

596パディングビットの値は指定されていません。

于 2017-09-26T15:37:38.633 に答える