Appleが作成したコードには、次の行があります。
CMTimeMakeWithSeconds( newDurationSeconds, 1000*1000*1000 )
1,000,000,000
を1000*1000*1000
として表現する理由はありますか?
どうして1000^3
ではないのですか?
乗法で定数を宣言する1つの理由は、実行時のパフォーマンスに影響を与えずに、読みやすさを向上させることです。また、作家が数について乗法的に考えていたことを示すため。
このことを考慮:
double memoryBytes = 1024 * 1024 * 1024;
明らかに次の点より優れています。
double memoryBytes = 1073741824;
後者は一見すると1024の3乗に見えないためです。
Amin Negm-Awadが述べたように、^
演算子はバイナリXOR
です。多くの言語には、組み込みのコンパイル時べき乗演算子、つまり乗算がありません。
なぜ
1000^3
ではありませんか?
1000^3
の結果は1003です。^
はビットXOR演算子です。
Q自体を扱っていない場合でも、説明を追加します。 x^y
はnotを行い、質問者の例のように常にx+y
に評価します。すべてのビットをxorする必要があります。例の場合:
1111101000₂ (1000₁₀)
0000000011₂ (3₁₀)
1111101011₂ (1003₁₀)
しかし
1111101001₂ (1001₁₀)
0000000011₂ (3₁₀)
1111101010₂ (1002₁₀)
理由はいくつかあります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;
読みやすくするため。
ゼロ(1 000 000 000
または1,000,000,000
)の間にコンマとスペースを配置すると構文エラーが発生し、コードに1000000000
があると、ゼロの正確な数を確認するのが難しくなります。
1000*1000*1000
は、目がチャンクをより簡単に処理できるため、10 ^ 9であることを明らかにします。また、コンパイラが定数1000000000
に置き換えるため、ランタイムコストは発生しません。
読みやすくするため。比較のため、Javaは数字で_
をサポートし、読みやすさを改善します(最初にStephen Colebourneが Derek FosterのPROPOSAL:Binary Literalsに返信 Project Coin/JSR 334として提案しました) )。ここに1_000_000_000
と書くでしょう。
最も古いサポートから最新のサポートまで、大まかに時系列順に:
"(1)1111 1111"
( 明らかに10進値ではなく、2進、4進、8進、または16進値を表すビット文字列のみ )1$000$000
1_000_000_000
1'000'000'000
これは、言語がサポートする必要があることを認識するための比較的新しい機能です(そしてPerlがあります)。 chux @の優れた答えのように、1000*1000...
は部分的な解決策ですが、最終結果が大きな型であっても、プログラマーが乗算のオーバーフローからバグを受け入れます。
1,000,000,000
フォームとの関連付けを簡単に読み取って取得できる場合があります。
技術的な面からは、直接数と乗算の間に違いはないと思います。コンパイラーは、とにかく一定の10億の数として生成します。
Objective-Cについて話すと、1000^3
は機能しません。これは、powにはそのような構文がないためです(xorです)。代わりに、pow()
関数を使用できます。しかし、その場合、最適ではなく、コンパイラーが生成した定数ではなく、ランタイム関数呼び出しになります。
理由を説明するために、次のテストプログラムを検討してください。
$ 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
$
Cで10進数に対して同様の効果を達成する別の方法は、リテラル浮動小数点表記を使用することです-倍精度が精度を損なうことなく必要な数値を表現できる限りです。
IEEE 754 64ビットdoubleは、2 ^ 53以下の負でない整数を問題なく表現できます。通常、long double(80または128ビット)はそれよりもさらに大きくなります。変換はコンパイル時に行われるため、実行時のオーバーヘッドはなく、予期しない精度の低下があり、適切なコンパイラーがある場合は警告が表示される可能性があります。
long lots_of_secs = 1e9;