为什么用 C 写1000,000,000作为1000 * 1000 * 1000?

在苹果编写的代码中,有这么一行:

CMTimeMakeWithSeconds( newDurationSeconds, 1000*1000*1000 )

是否有任何理由将 1,000,000,000表示为 1000*1000*1000

为什么不是 1000^3呢?

15264 次浏览

为什么不是 1000^3

1000^3的结果是1003。 ^是位 XOR 运算符。

即使它不涉及 Q 本身,我补充一个澄清。x^y没有总是向 x+y求值,就像它在提问者的例子中所做的那样。每一个字母都要做 x。例如:

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

但是

1111101001₂ (1001₁₀)
0000000011₂ (3₁₀)
1111101010₂ (1002₁₀)

可能更容易阅读并获得与 1,000,000,000表单的一些关联。

从技术方面来说,我想直接数和乘法之间没有什么区别。无论如何,编译器将把它生成为固定的十亿数。

如果您谈到 Objective-c,那么 1000^3将不起作用,因为 pow 没有这样的语法(它是 xor)。相反,可以使用 pow()函数。但在这种情况下,它将不是最优的,它将是一个运行时函数调用而不是编译器生成的常量。

以乘法方式声明常数的一个原因是为了提高可读性,同时不影响运行时性能。 同时,表明作者正在以乘法的方式思考这个数字。

想想这个:

double memoryBytes = 1024 * 1024 * 1024;

这显然比:

double memoryBytes = 1073741824;

因为后者乍一看不像1024的第三次方。

正如 Amin Negm-Awad 所提到的,^操作符是二进制 XOR。许多语言缺少内置的编译时指数运算符,因此需要乘法。

为了便于阅读。

在零之间放置逗号和空格(1 000 000 0001,000,000,000)会产生语法错误,代码中包含 1000000000会使得很难确切地看到有多少个零。

1000*1000*1000显示它是10 ^ 9,因为我们的眼睛可以更容易地处理这些数据块。而且,没有运行时成本,因为编译器将用常量 1000000000替换它。

为了便于阅读。作为比较,Java 在数量上支持 _以提高可读性(最初由 Stephen Colebourne 提出,作为 Project Coin/JSR 334的 答复德里克 · 福斯特的提议: 二进制文学)。在这里写 1_000_000_000

按照大致的时间顺序,从最古老的支持到最新的:

对于语言来说,意识到它们应该支持的特性是一个相对较新的特性(还有 Perl)。正如 chux@的出色回答一样,1000*1000...是一个部分解决方案,但是即使最终结果是一个很大的类型,也会使程序员面临因乘法过多而导致的错误。

没有使用 1000 * 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_EPSILONDBL_DIG)。

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

为了说明原因,考虑以下测试程序:

$ 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 中对十进制数实现类似效果的另一种方法是使用文字浮点表示法——只要一个 double 可以表示您想要的数字而不会损失任何精度。

IEEE 75464位双精度数可以毫无问题地表示任意非负整数 < = 2 ^ 53。通常,long double (80或128位)甚至可以更进一步。转换将在编译时完成,因此没有运行时开销,并且如果存在意外的精度损失并且您有一个好的编译器,您可能会得到警告。

long lots_of_secs = 1e9;