为什么在C语言中把1,000,000,000写成1000* 1000*1000?

3zwjbxry  于 2023-02-07  发布在  其他
关注(0)|答案(8)|浏览(263)

在Apple创建的代码中,有这样一行:

CMTimeMakeWithSeconds( newDurationSeconds, 1000*1000*1000 )

有什么理由把1,000,000,000表示为1000*1000*1000吗?
为什么1000^3不是这样呢?

u0njafvf

u0njafvf1#

以乘法方式声明常量的一个原因是为了提高可读性,同时不影响运行时性能。另外,这也表明作者是以乘法方式考虑数字的。
想想这个:

double memoryBytes = 1024 * 1024 * 1024;

它明显优于:

double memoryBytes = 1073741824;

因为后者乍看上去并不是1024的三次方。
正如Amin Negm-Awad提到的,^运算符是二进制XOR,许多语言缺少内置的编译时求幂运算符,因此有了乘法。

xghobddn

xghobddn2#

  • 不 * 使用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是否可以精确表示整数值--这是大于1 e9的值所关心的问题。(参见DBL_EPSILONDBL_DIG)。

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

swvgeqrz3#

为什么不是1000^3
1000^3的结果是1003。^是位XOR运算符。
即使它不处理Q本身,我也要做一个澄清。x^y并不总是像在提问者的例子中那样计算为x+y。你必须对每一位进行异或。在这个例子中:

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

但是

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

jk9hmnmh4#

为了可读性。
在零之间放置逗号和空格(1 000 000 0001,000,000,000)会产生语法错误,并且代码中包含1000000000会使人很难准确地看到有多少个零。
1000*1000*1000使它看起来是10^9,因为我们的眼睛可以更容易地处理这些块,而且没有运行时开销,因为编译器会用常量1000000000替换它。

wpx232ag

wpx232ag5#

为了提高可读性。作为比较,Java支持数字形式的_以提高可读性(最早由Stephen Colebourne提出,作为Project Coin/JSR 334的reply to Derek Foster's PROPOSAL: Binary Literals)。这里可以写成1_000_000_000
大致按时间顺序,从最早到最新:

对于语言来说,这是一个相对较新的特性,意识到它们应该支持(然后是Perl)。正如chux@的精彩回答一样,1000*1000...是一个部分解决方案,但会给程序员带来乘法溢出的bug,即使最终结果是一个大类型。

dw1jzc5e

dw1jzc5e6#

可能更容易阅读并获得与1,000,000,000表单的一些关联。
从技术上看,我想直接数和乘法没有什么区别,编译器会把它生成为常数十亿。
如果你说的是objective-c,那么1000^3就不起作用了,因为pow没有这样的语法(它是xor)。相反,可以使用pow()函数。但是在那种情况下,它不是最优的,它将是一个运行时函数调用,而不是编译器生成的常量。

yhived7q

yhived7q7#

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

$ 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
$
ltqd579y

ltqd579y8#

在C语言中为十进制数实现类似效果的另一种方法是使用文字浮点表示法a-只要double可以表示所需的数字而不损失任何精度。
IEEE 754 64位双精度型可以表示任何〈= 2^53的非负整数。通常,长双精度型(80或128位)甚至可以更进一步。转换将在编译时完成,因此没有运行时开销。如果出现意外的精度损失,并且您有一个良好的编译器,则可能会收到警告。

long lots_of_secs = 1e9;

相关问题