string::npos
何かに気付いたが、ウェブ上でその説明を見つけることができなかった。
(string::npos == ULONG_MAX)
そして
(string::npos == -1)
本当です。
だから私はこれを試しました:
(18446744073709551615 == -1)
これも事実です。
どうしてそれが可能ですか?バイナリ会話が原因ですか?
18,446,744,073,709,551,615
記載されているこの番号18,446,744,073,709,551,615
は、実際には2^64 − 1
です。ここで重要なことは、2^64-1
は本質的に0ベースの2^64
です。符号なし整数の最初の桁は、0
ではなく、1
です。したがって、最大値が1
の場合、2つの可能な値があります:0
、または1
(2)。
すべてのビットがオンになっている64ビットバイナリの2^64 - 1
を見てみましょう。
1111111111111111111111111111111111111111111111111111111111111111b
-1
64ビットバイナリの+1
を見てみましょう。
0000000000000000000000000000000000000000000000000000000000000001b
One's Compliment(OCP)で負にするには、ビットを反転します。
1111111111111111111111111111111111111111111111111111111111111110b
コンピューターはほとんどOCPを使用せず、Two's Compliment(TCP)を使用します。 TCPを取得するには、OCPに追加します。
1111111111111111111111111111111111111111111111111111111111111110b (-1 in OCP)
+ 1b (1)
-----------------------------------------------------------------
1111111111111111111111111111111111111111111111111111111111111111b (-1 in TCP)
「しかし、待って」と尋ねます。TwosCompliment -1
が、
1111111111111111111111111111111111111111111111111111111111111111b
そして、バイナリ2^64 - 1
が
1111111111111111111111111111111111111111111111111111111111111111b
それから彼らは平等です!そして、それはあなたが見ているものです。符号付き64ビット整数と符号なし64ビット整数を比較しています。 C++では、コンパイラは署名された値を符号なしの値に変換します。
技術的な修正 コメントのdavmacに感謝 の場合、signed
である-1
から同じサイズのunsigned
型への変換が実際に指定されています言語であり、アーキテクチャの機能ではありません。以上のことから、上記の答えは、2つの賛辞をサポートしているが、信頼できる結果を保証する仕様に欠けているArch /言語を理解するのに役立つかもしれません。
string::npos
はconstexpr static std::string::size_type string::npos = -1;
として定義されます(または、クラス定義内でconstexpr static size_type npos = -1;
になるが、それは本当に無関係です)。
符号なしの型に変換される負の数値のラップアラウンド(std::string::size_type
は基本的にstd::size_t
、これは符号なし)は、規格によって完全に明確に定義されています。 -1
は、符号なし型の表現可能な最大値にラップします。これは、あなたの場合は18446744073709551615
です。 std::size_t
のサイズは実装定義であるため、正確な値は実装定義であることに注意してください(ただし、問題のシステムで可能な最大の配列のサイズを保持できます)。
C++標準(ドキュメント番号:N3337またはドキュメント番号:N4296)によれば、std::string::npos
は次のように定義されます
static const size_type npos = -1;
ここで、std :: string :: size_typeは、符号なし整数型です。したがって、std :: string :: nposが-1に等しいという素晴らしいことはありません。初期化子はstd::string::npos
のタイプに変換されます。
この方程式は
(string::npos == ULONG_MAX) is true,
それは、型std::string::npos
が使用される実装unsigned long
に型を持つことを意味します。この型は通常、size_t
型に対応しています。
この方程式では
(18446744073709551615 == -1)
左のリテラルには、そのような大きなリテラルを格納するのに適した符号なし整数型があります。したがって、符号ビットを伝搬することにより、右オペランドもこの符号なしの型に変換されます。左のオペランドはそれ自体が型の最大値を表すため、それらは等しくなります。
これはすべて、符号付きオーバーフローと、負の数が2の補数として格納されるという事実です。つまり、負の数の絶対値を取得するには、すべてのビットを反転させて1を追加します。 8ビットの比較を行うときの意味255と-1は同じバイナリ値11111111を持ちます。同じことがより大きな整数にも当てはまります