2016-04-19 9 views
0

私は次のコードを持っている:C反復までの非常に大きな数に - コンパイラはに関する警告unsigned int型

#include <stdio.h> 
#define POWER 10000000000000000000 

int main() 
{ 
    int i; 
    for (i = 0; i < POWER; i++) 
    { 
     .... 
    } 
    return 0; 
} 

コンパイラは私に次の警告与える:

EX1を。 c:33:19:警告:整数定数が大きすぎて符号なし[デフォルトで有効] ex1.c:33:2:警告:この小数定数はISO C90でのみ符号なし[デフォルトで有効]

iをすべての値で実行して、それがPOWERに達するまで、どのように反復することができますか?私はiunsigned intと宣言しようとしましたが、警告が残っています。

+1

あなたが本当にループにしたいん '10000000000000000000'回? (長いi = 0; i ++)は技術的に同じ(無限ループ) –

+0

@DmitryBychenko私は非常に大きな数を反復しようとしているので、何回も繰り返す必要があります。 – Marievi

+3

'#define POWER 10000000000000000000' - >>' #define POWER 10000000000000000000ULL'と 'int i;' '' '' unsigned long long i; ' – joop

答えて

4

定数10000000000000000000は、それを表すのに64ビットを必要とします。 16進数では、0x8ac7230489e80000です。 符号なし 64ビットタイプで表現できますが、符号付き 64ビットタイプではありません。

C99以降、すべての整数定数は符号付きの型で、最初はint,long intまたはlong long intの値が入ります。

C90(まだlong long intを持っていなかった)は、異なる規則を有していた。 C90では、接尾辞のない10進整数定数は、タイプint,long intまたはunsigned long intです。

gccのデフォルトモードは-std=gnu90で、C90標準とGNU固有の拡張機能をサポートしています。 64ビットシステムの場合、longunsigned longは64ビットです。 C90ルールの下では、定数はunsigned longです(unsigned longが少なくとも64ビットであると仮定します)。 C99以降の規則では、64ビットより広い整数型がないと仮定すると、それは制約違反です。 (gccバージョン5はデフォルトを-std=gnu11に変更しました)

明らかにC90ルールで動作しているコンパイラは、コンパイラが動作している標準のエディションによって、10000000000000000000の意味が異なることを警告しています。

あなたは次のように変更して、あなたのプログラム「仕事」を作ることができます。

#define POWER 10000000000000000000ULL // suffix to specify the type 
... 
for (unsigned long long = 0; i < POWER; i ++) 
... 

しかし、それはプログラムが有効になりますが、それは現実的なことはありません。1ナノ秒あたりの反復では、そのループが終了するのに3世紀以上かかるでしょう。私自身の合理的に現代的なコンピュータは、空のforのループを約1.6ナノ秒で1回実行します。あなたが解決しようとしている問題が何であれ、それを解決する別の方法を見つけるか、それをより小さな問題に減らすことを提案します。そのループを実行する最速の方法は、ハードウェアが高速になるために数十年待ってから、次にをコンパイルして実行することです。

(これは、ループの本体は非自明である前提としています。ループの本体は何もしない場合、コンパイラは完全にループを離れて最適化することがあります。)

+0

"C90ルールでは、定数の型はunsigned longです。"あなたはこれについて確信を持っていますか? C++では、10進リテラルは決して符号なし型に変換されません。私はCでもそれほど確かではない。 – Bathsheba

+0

@Bathsheba:はい、私は確信しています。私はちょうど私のC90標準(ISO/IEC 9899:1990(E))のコピーをチェックしました。 –

+0

この場合、upvote! – Bathsheba

-1

値が10000000000000000000(私が右に数えるならば10^19)は割り当てに64ビットが必要ですが、これは8バイトです。タイプintは4バイトを使用しているため、その番号を保存できないため、警告が表示されています。 unsigned intでは、格納できる正の最大数は倍になりますが、まだ十分ではない4,294,967,295です。 intを使用する場合は、反復ループを使用できます。 pはPOWERの立方根のvaueとint又はunsigned intあろう

for(i=0;i<p;i++){ 
     for(j=0;j<p;j++){ 
      for(k=0<p;k++){ 
      /*loop*/ 
      } 
     } 
    } 

(この場合立方根の19%3として有効ではありません!= 0、pはintではないであろう、その

+0

"' int '型が4バイトを使用しているため、その番号を格納できないため警告が表示されます。 - >いいえ' 10000000000000000000'は 'long long'に収まらないので警告が発生しています。 (C99)または 'unsigned long'(C90)である。 'int'の範囲は問題ではありません。 – chux

関連する問題