2016-08-09 5 views
3

関数g1()g2()は同じロジックを持ちますが、入力タイプはサイズが異なります。なぜ彼らは負の和に対して異なる結果を返しますか?混合符号整数の計算は可変サイズに依存します

/*BINFMTCXX: -Wall -Werror -Wextra -std=c++11 
*/ 

#include <stdio.h> 
#include <stdint.h> 

char g1(int32_t a, uint32_t b) { return a+b<9; } // fails when a+b is negative 
char g2(int16_t a, uint16_t b) { return a+b<9; } // works if no overflow 

int main() 
    { 

    for (int a=-2, b=0; a<=2; a++) 
     { 
     fprintf(stderr,"a=%+d, b=%d, g1=%+d, g2=%+d %s\n", a, b, g1(a,b), g2(a,b), g1(a,b)==g2(a,b)?"":"!"); 
     } 

    return 0; 
    } 

私はそれを実行すると、それはa+bが負の場合g1()が失敗したことを示しています

$ ./mixed_sign_math_per_size.cpp 
a=-2, b=0, g1=+0, g2=+1 ! 
a=-1, b=0, g1=+0, g2=+1 ! 
a=+0, b=0, g1=+1, g2=+1 
a=+1, b=0, g1=+1, g2=+1 
a=+2, b=0, g1=+1, g2=+1 

結果は、CおよびC++で同じです。

+0

*入力タイプのサイズが違う*もっと重要なのは、型がこれらの型のサイズではなく、符号付き/符号なしであると思いませんか? – PaulMcKenzie

+0

@PaulMcKenzie:はい、入力タイプには記号が混在しています。しかし、これは 'g1()'と 'g2()'の違いではありません。 – nobar

+1

http://stackoverflow.com/questions/2280663/in-ac-expression-where-unsigned-int-and-signed-int-are-present-which-type-「g1」、負の数非常に大きな符号なしの数値に変換されます。 'g2'では、両方とも' int'に変換され、両方の入力を損なうことなく十分な範囲を持っています。 –

答えて

3

usual arithmetic conversionsの結果、g2の体の両方のabは、その機能が完璧にうまく機能する理由である、intに昇格されています。 intのそれよりも低いランクを持っていません(uint32_tのでg1については

は、何のプロモーションは行われず、非常に最後の箇条書き(11.5.5)が適用されます。どちらのオペランドも、符号なしタイプに変換されます。aでは、アンダーフローが発生し、9よりもはるかに大きな値を生成します。したがって、g11true)を返します。

+0

あなたが参照しているものが "10.5.5"であるとわかりません。あなたのリンクは5.11でした。 – nobar

+0

@nobar私は悪いですが、私は地元の旧式のドラフトを見ていました。 (11.5.5)は、第11段落の第5の箇条書きの第5の箇条書きです。 – Columbo

+0

これは、IMOでは少し不明です。「a」と「b」は「通常の算術変換」によって変換されませんが、「整数プロモーション "(これが最初に起こる)。少なくとも、それは標準の正確な言葉の私の理解だろう。 –

関連する問題