web-dev-qa-db-ja.com

Cで1,000,000,000を1000 * 1000 * 1000と書くのはなぜですか?

Appleが作成したコードには、次の行があります。

CMTimeMakeWithSeconds( newDurationSeconds, 1000*1000*1000 )

1,000,000,0001000*1000*1000として表現する理由はありますか?

どうして1000^3ではないのですか?

134
SpaceDog

乗法で定数を宣言する1つの理由は、実行時のパフォーマンスに影響を与えずに、読みやすさを向上させることです。また、作家が数について乗法的に考えていたことを示すため。

このことを考慮:

double memoryBytes = 1024 * 1024 * 1024;

明らかに次の点より優れています。

double memoryBytes = 1073741824;

後者は一見すると1024の3乗に見えないためです。

Amin Negm-Awadが述べたように、^演算子はバイナリXORです。多くの言語には、組み込みのコンパイル時べき乗演算子、つまり乗算がありません。

193
Piotr Falkowski

なぜ1000^3ではありませんか?

1000^3の結果は1003です。^はビットXOR演算子です。

Q自体を扱っていない場合でも、説明を追加します。 x^ynotを行い、質問者の例のように常にx+yに評価します。すべてのビットをxorする必要があります。例の場合:

1111101000₂ (1000₁₀)
0000000011₂ (3₁₀)
1111101011₂ (1003₁₀)

しかし

1111101001₂ (1001₁₀)
0000000011₂ (3₁₀)
1111101010₂ (1002₁₀)
72
Amin Negm-Awad

理由はいくつかありますnot1000 * 1000 * 1000を使用する。

16ビットintを使用すると、1000 * 1000がオーバーフローします。したがって、1000 * 1000 * 1000を使用すると、移植性が低下します。

32ビットintでは、以下がオーバーフローします。

long long Duration = 1000 * 1000 * 1000 * 1000;  // overflow
long long Duration = 1000000000000;  // no overflow, hard to read

リード値は、読みやすさ、移植性および正確性のために宛先のタイプと一致することを提案します。

double Duration = 1000.0 * 1000 * 1000;
long long Duration = 1000LL * 1000 * 1000 * 1000;

また、eとして正確に表現できる値にdouble表記を簡単に使用できます。もちろん、これはdoubleが整数値を正確に表すことができるかどうかを知ることにつながります-1e9より大きい値で懸念されるものです。 (DBL_EPSILONおよびDBL_Digを参照)。

long Duration = 1000000000;
// vs.
long Duration = 1e9;
64
chux

読みやすくするため。

ゼロ(1 000 000 000または1,000,000,000)の間にコンマとスペースを配置すると構文エラーが発生し、コードに1000000000があると、ゼロの正確な数を確認するのが難しくなります。

1000*1000*1000は、目がチャンクをより簡単に処理できるため、10 ^ 9であることを明らかにします。また、コンパイラが定数1000000000に置き換えるため、ランタイムコストは発生しません。

50
Tamás Zahola

読みやすくするため。比較のため、Javaは数字で_をサポートし、読みやすさを改善します(最初にStephen Colebourneが Derek FosterのPROPOSAL:Binary Literalsに返信 Project Coin/JSR 334として提案しました) )。ここに1_000_000_000と書くでしょう。

最も古いサポートから最新のサポートまで、大まかに時系列順に:

これは、言語がサポートする必要があることを認識するための比較的新しい機能です(そしてPerlがあります)。 chux @の優れた答えのように、1000*1000...は部分的な解決策ですが、最終結果が大きな型であっても、プログラマーが乗算のオーバーフローからバグを受け入れます。

25
djechlin

1,000,000,000フォームとの関連付けを簡単に読み取って取得できる場合があります。

技術的な面からは、直接数と乗算の間に違いはないと思います。コンパイラーは、とにかく一定の10億の数として生成します。

Objective-Cについて話すと、1000^3は機能しません。これは、powにはそのような構文がないためです(xorです)。代わりに、pow()関数を使用できます。しかし、その場合、最適ではなく、コンパイラーが生成した定数ではなく、ランタイム関数呼び出しになります。

6
Madars Vi

理由を説明するために、次のテストプログラムを検討してください。

$ cat comma-expr.c && gcc -o comma-expr comma-expr.c && ./comma-expr
#include <stdio.h>

#define BILLION1 (1,000,000,000)
#define BILLION2 (1000^3)

int main()
{
        printf("%d, %d\n", BILLION1, BILLION2);
}
0, 1003
$
2

Cで10進数に対して同様の効果を達成する別の方法は、リテラル浮動小数点表記を使用することです-倍精度が精度を損なうことなく必要な数値を表現できる限りです。

IEEE 754 64ビットdoubleは、2 ^ 53以下の負でない整数を問題なく表現できます。通常、long double(80または128ビット)はそれよりもさらに大きくなります。変換はコンパイル時に行われるため、実行時のオーバーヘッドはなく、予期しない精度の低下があり、適切なコンパイラーがある場合は警告が表示される可能性があります。

long lots_of_secs = 1e9;
0
jschultz410