型の数を否定したいときはstd::size_t、通常は を行います-static_cast<int>(number)。ただし、番号が に収まらない可能性があることは理解していintます。それで、私の質問は、これを行うための安全なポータブル方法は何ですか?
4 に答える
これを行うための安全なポータブルな方法はありません。
size_t符号なしタイプです。の最大値を保持するのに十分な大きさの符号付き整数型があるという保証はありませんsize_t。
否定している値が大きすぎないと想定できる場合は、long long(コンパイラがサポートしている場合)またはlong(サポートしていない場合)に変換できます。
size_t s = some_value;
long long negative_s = -(long long)s;
オーバーフローが心配な場合は、変換を行う前にstoの値を比較できます。LLONG_MAX
安全な方法は、変数が対応する符号付きタイプに適合するかどうかをチェックします。
typedef std::size_t my_uint;
typedef typename std::make_signed<my_uint>::type my_int;
my_uint n = /* ... */;
if (n > std::numeric_limits<my_int>::max()) { /* Error! */ }
my_int m = -static_cast<my_int>(n);
あなたがする必要が#include <limits>あり<type_traits>ます。
(または、すべてを1行にまとめます:)
if (n > std::numeric_limits<typename std::make_signed<decltype(x)>::type>::max()) { /* Error! */ }
は、の範囲の半分の値しか記述できないため、std::size_tを使用して上半分の範囲の値を否定できないという固有の問題があると思います。たとえば、 255の値がある場合、-255の値を取得することはできません...のようなより大きなタイプが必要になります。がプラットフォームの最大の統合コンテナである場合、の符号を指定するための追加のフラグ変数などのカスタムデータ型を指定せずに、これらの値を「負の」形式で記述することはできません。値。もちろん、それはもはや「ポータブル」ではありません...std::ssize_tstd::ssize_tstd::size_tunsigned charsigned charsigned shortstd::size_tstruct
-static_cast<int>(number)安全です; の結果は、static_castに収まらない場合は実装によって定義されintます。
結果が適合しないかどうかを検出するには:
(number <= std::numeric_limits<int>::max()) ? -static_cast<int>(number) : ...