問題タブ [integer-promotion]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c - unsigned への昇格は、結果または各オペランドで行われますか?
以下
2147483647U > -2147483647 - 1
では、unsigned への変換/昇格のために false と評価されます。
私の質問は、それがどのように促進されるかということです。
減算演算が最初に実行され、結果が符号なしに昇格されるか、それとも各オペランドが代わりに符号なしに昇格されますか?
符号付きの場合は 4 ビット [-8,7]、符号なしの場合は [0,15] の例:
7U > -7 -1
これは (unsigned)(-7) + (unsigned)(-1) = (9U) + (15U) = 24U になります
。7U > 24U
どちらが偽かということになります。
それとも、偽の
-7-1 = -8 = 8U
Soがありますか7U > 8U
c++ - この関数呼び出しがあいまいなのはなぜですか?
私は標準を読んでいて、キャストなしではこのコードが解決されない理由を理解しようとしています。
これがそれが言うことです:
4.13 整数変換ランク [conv.rank]
すべての整数型には、次のように定義された整数変換ランクがあります。
— 符号なし整数型のランクは、対応する符号付き整数型のランクと等しくなければなりません。
— char のランクは、signed char および unsigned char のランクと等しくなければなりません。
特に、私のジミーをざわめかせるのは、符号なしの整数型ではなく、符号なしの char だけであるということです。私の推測では、変換によって char が unsigned 型に昇格されています。これは本当ですか?
c++ - C++ - uchar のないビット単位では int が生成されます
unsigned char ではなくビット単位で適用する場合の C++ の動作には驚かされます。
、またはのバイナリ値01010101b
を取ります。8ビット表現ではなくビットごとに適用すると、 、または.0x55
85
10101010b
0xAA
170
ただし、上記を C++ で再現することはできません。次の単純なアサーションは失敗します。
0x55
、0xAA
、および~0x55
(uchar として)の値を次のコードで出力しました。そして、ビット単位の not が期待どおりに機能しないことがわかります。
出力される数値~0x55
は と等しく11111111111111111111111110101010b
、これは の 32 ビット ビット単位ではありません0x55
。そのため、入力を に明示的にキャストしても、~
演算子は 32 ビット整数で動作していunsigned char
ます。何故ですか?
別のテストを適用して、~
演算子が返す型を確認しました。int
そして、それは入力上にあることが判明しましたunsigned char
:
次のコンパイラ エラーが発生します。これは、結果の型が であることを示しますint
。
私は何を間違っていますか?または、C++ を から生成するにはどうすればよい0xAA
です~0x55
か?
完全なコードはこちら
c - unsigned int a = -1 のビット表現
unsigned int x =-1;
unsigned int に負の整数を割り当てることはできますか?のビット表現は何ですか?
出力:
同じ
そして、どのように可能ですか、xは署名されていません
出力:
真実
c - 統合昇格/変換: 結果の型の名前を気にする必要があるのはなぜですか?
私は整数昇格の C99 規則と整数型の通常の算術変換に頭を悩ませようとしてきました。いくつかのニューロンを燃やした後、私は独自の一連のルールを思いつきました。これははるかに単純ですが、公式のものと同等であると私は信じています。
更新:この質問の目的のために、「物理タイプ」を次のように定義することから始めます
定義: 2 つの整数型は、サイズと符号が同じであれば、同じ物理型です。
この定義に何か問題があると思われる場合は、おそらく質問 2 の打撃に対する適切な答えが得られます。
簡素化されたプロモーション/コンバージョン ルール
型ランキング: 2 つの整数型 T1 と T2 の中で、「最高」は次のとおりです。
- どちらか大きい方
- サイズが同じ場合、符号のない方
- いずれにせよ物理的に同じであるため、サイズと署名が同じであれば、いずれかです。
積分昇格: 型 T の値を昇格する必要があります
昇格(T) = ベスト(T, int)
整数型の通常の算術変換: 型 T1 および T2 で二項演算子を評価する前に、引数を次の適切な共通型に変換する必要があります。
common(T1, T2) = best(T1, T2, int)
警告: 私のルールは正しい物理型を与えると信じていますが、単一の型が異なる名前を持つ場合、正しい型名を提供しない可能性があります。たとえば、システムでint==long
は、公式ルールは次のように述べています。
common(unsigned int, long) = unsigned long
一方、私のルールunsigned int
ではそうです(とにかく物理的に同じです)。しかし、名前はそれほど重要ではないので、これは問題にはなりません。それとも彼らはしますか?
この長い前奏曲の後、本当の質問が来ます。これには 2 つの要素があります。
質問 1: 私のルールは正しいですか?
公式のものを何度か読みましたが、それでもわかりにくいと思います。したがって、私は何かを誤解している可能性があります。私が間違っている場合は、公式ルールと私のルールで異なる型が生成される例を示してください。つまり、物理的に同じである異なるタイプだけでなく、異なる物理タイプです。
実世界の例が優先されます。何も見つからない場合、仮説的な C 環境が説得力のある十分な詳細 (関連する型のサイズなど) で記述されていれば、理論的な例で問題ありません。
ここで私が正しければ、2 番目の質問が適切になります。
質問 2: 昇格/変換された型の名前を気にする必要があるのはなぜですか?
もし私が正しければ、明白な疑問は「なぜ標準化委員会の人々はこれほど複雑なルールを書いたのか?」ということです。彼らは私が考えることができる唯一の答えは、プロモーション/変換によって生成された物理的なタイプだけでなく、それらのタイプに名前を付ける適切な方法も指定したかったということです. しかし、なぜ彼らは気にしたのですか?これらの型は、コンパイラによって内部的にのみ使用されます。それらが物理的に何であるかを理解している限り、どのように名前を付けるかは問題ではありません。この推論に何か問題がありますか? T1 と T2 が物理的に同じであるにも関わらず、T2 ではなく T1 に自動的に昇格または変換されるかどうかを知ることが重要である状況を考えられますか? 繰り返しになりますが、実世界の例が優先されますが、それ以外の場合は、十分に詳細な理論的な例で十分です。
根拠
(2014 年 11 月 10 日にいくつかのコメントに対応するためにセクションを追加)
これらのトピックを検索するとき、算術演算子の動作、より具体的にはそれらの演算子によって返される結果のコンテキストで議論されているのを常に見てきました。たとえば、-1L < 1U
long が int より実際に長いシステムでは true ですが、そうでない場合は false であるため、この式には問題があります。この種の問題を理解することは良いことだと思いますが、理解するために複雑なルールセットが必要になることは悪いことです。したがって、同じ結果を確実に与える、より単純なルールセットを構築するためのこの努力。
私は、私のルールが、実際のルールが十分に単純であると考える人にとって役に立たないことを十分に理解しています. 私はまた、公式ルール以外に頼ることは本質的に悪いという意見を表明する人々を理解しており、丁重に同意しません。それにもかかわらず、私のルールは、私以外の誰も助けない場合、その有用性を持っています.
私の個人的な偏見について: 物理学者として、私はシンプルさを非常に高く評価しています。私は、究極の真実ではない、あるいはそうであるように意図されていない理論を扱うことに慣れていますが、適用範囲の限界を理解している限り、それらは非常に有用であり、安全に使用できることが証明されています. どのような状況でも、最良の理論は最も完全なものではありません。それは、依然として適用可能な最も単純な理論です。たとえば、単純な振り子の周期を計算するために量子重力を使用することはありません。この質問をここに投稿するのは、上記の規則の適用範囲の限界について専門家の意見を得ようとする試みです。
これまでのところ、私が持っているものは次のとおりです。
- varargs ケース (tanks、mafso) は、これらのルールが少なくとも原則として適用されない C99 の唯一の状況のようです。
_Generic
キーワード (ありがとう、Pascal Cuoq) は、C11 の機能であるため、範囲外です。- C++11
auto
キーワード。これはさらに範囲外ですが、エイリアシング ルールに関する (そうでなければ無関係な) 懸念をテーブルにもたらすという点で興味深いものです。
c - 符号付き/符号なしの int、short、および char
次のコードの出力を理解しようとしています: http://phrack.org/issues/60/10.html
参考までにここに引用します:
私のマシンで得られる出力は次のとおりです。
ここに私の理解があります: -
代入 s=l、c=l により、s と c が int に昇格され、それぞれ l の最後の 16 ビット (0xbeef) と最後の 8 ビット (0xef) を持つことになります。
Printf は、上記の各値 (l、s、および c) を符号なし整数として解釈しようとします (%x がフォーマット指定子として渡されるため)。出力から、符号拡張が行われたことがわかります。%x は unsigned int を表しているのに、なぜ s と c の印刷中に符号拡張が行われたのでしょうか? s の出力は 0x0000beef であり、c の出力は 0x000000ef であってはなりませんか?
c++ - 「通常の算術変換」と「整数昇格」は同じものですか?
「通常の算術変換」と「整数昇格」は同じものですか? int
「通常の算術変換」は式のオペランドを同じ型にするために使用され、「整数昇格」はtoより小さい型を昇格させるために使用されることを読みましたint
が、MSDNではこれらの概念は両方とも「通常の算術変換」のみ。