在Apple创建的代码中,有这样一行:
CMTimeMakeWithSeconds( newDurationSeconds, 1000*1000*1000 )
有什么理由把1,000,000,000表示为1000*1000*1000吗?为什么1000^3不是这样呢?
1,000,000,000
1000*1000*1000
1000^3
u0njafvf1#
以乘法方式声明常量的一个原因是为了提高可读性,同时不影响运行时性能。另外,这也表明作者是以乘法方式考虑数字的。想想这个:
double memoryBytes = 1024 * 1024 * 1024;
它明显优于:
double memoryBytes = 1073741824;
因为后者乍看上去并不是1024的三次方。正如Amin Negm-Awad提到的,^运算符是二进制XOR,许多语言缺少内置的编译时求幂运算符,因此有了乘法。
^
XOR
xghobddn2#
1000 * 1000 * 1000
使用16位int时,1000 * 1000会溢出,因此使用1000 * 1000 * 1000会降低可移植性。对于32位int,以下第一行代码溢出。
int
1000 * 1000
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_EPSILON和DBL_DIG)。
e
double
DBL_EPSILON
DBL_DIG
long Duration = 1000000000; // vs. long Duration = 1e9;
swvgeqrz3#
为什么不是1000^3?1000^3的结果是1003。^是位XOR运算符。即使它不处理Q本身,我也要做一个澄清。x^y并不总是像在提问者的例子中那样计算为x+y。你必须对每一位进行异或。在这个例子中:
x^y
x+y
1111101000₂ (1000₁₀) 0000000011₂ (3₁₀) 1111101011₂ (1003₁₀)
但是
1111101001₂ (1001₁₀) 0000000011₂ (3₁₀) 1111101010₂ (1002₁₀)
jk9hmnmh4#
为了可读性。在零之间放置逗号和空格(1 000 000 000或1,000,000,000)会产生语法错误,并且代码中包含1000000000会使人很难准确地看到有多少个零。1000*1000*1000使它看起来是10^9,因为我们的眼睛可以更容易地处理这些块,而且没有运行时开销,因为编译器会用常量1000000000替换它。
1 000 000 000
1000000000
wpx232ag5#
为了提高可读性。作为比较,Java支持数字形式的_以提高可读性(最早由Stephen Colebourne提出,作为Project Coin/JSR 334的reply to Derek Foster's PROPOSAL: Binary Literals)。这里可以写成1_000_000_000。大致按时间顺序,从最早到最新:
_
1_000_000_000
"(1)1111 1111"
1$000$000
1'000'000'000
对于语言来说,这是一个相对较新的特性,意识到它们应该支持(然后是Perl)。正如chux@的精彩回答一样,1000*1000...是一个部分解决方案,但会给程序员带来乘法溢出的bug,即使最终结果是一个大类型。
1000*1000...
dw1jzc5e6#
可能更容易阅读并获得与1,000,000,000表单的一些关联。从技术上看,我想直接数和乘法没有什么区别,编译器会把它生成为常数十亿。如果你说的是objective-c,那么1000^3就不起作用了,因为pow没有这样的语法(它是xor)。相反,可以使用pow()函数。但是在那种情况下,它不是最优的,它将是一个运行时函数调用,而不是编译器生成的常量。
pow()
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 $
ltqd579y8#
在C语言中为十进制数实现类似效果的另一种方法是使用文字浮点表示法a-只要double可以表示所需的数字而不损失任何精度。IEEE 754 64位双精度型可以表示任何〈= 2^53的非负整数。通常,长双精度型(80或128位)甚至可以更进一步。转换将在编译时完成,因此没有运行时开销。如果出现意外的精度损失,并且您有一个良好的编译器,则可能会收到警告。
long lots_of_secs = 1e9;
8条答案
按热度按时间u0njafvf1#
以乘法方式声明常量的一个原因是为了提高可读性,同时不影响运行时性能。另外,这也表明作者是以乘法方式考虑数字的。
想想这个:
它明显优于:
因为后者乍看上去并不是1024的三次方。
正如Amin Negm-Awad提到的,
^
运算符是二进制XOR
,许多语言缺少内置的编译时求幂运算符,因此有了乘法。xghobddn2#
1000 * 1000 * 1000
是有原因的。使用16位
int
时,1000 * 1000
会溢出,因此使用1000 * 1000 * 1000
会降低可移植性。对于32位
int
,以下第一行代码溢出。建议前导值与目标类型匹配,以确保可读性、可移植性 * 和 * 正确性。
代码也可以简单地使用
e
表示法来表示可精确表示为double
的值。当然,这会导致知道double
是否可以精确表示整数值--这是大于1 e9的值所关心的问题。(参见DBL_EPSILON
和DBL_DIG
)。swvgeqrz3#
为什么不是
1000^3
?1000^3
的结果是1003。^
是位XOR运算符。即使它不处理Q本身,我也要做一个澄清。
x^y
并不总是像在提问者的例子中那样计算为x+y
。你必须对每一位进行异或。在这个例子中:但是
jk9hmnmh4#
为了可读性。
在零之间放置逗号和空格(
1 000 000 000
或1,000,000,000
)会产生语法错误,并且代码中包含1000000000
会使人很难准确地看到有多少个零。1000*1000*1000
使它看起来是10^9,因为我们的眼睛可以更容易地处理这些块,而且没有运行时开销,因为编译器会用常量1000000000
替换它。wpx232ag5#
为了提高可读性。作为比较,Java支持数字形式的
_
以提高可读性(最早由Stephen Colebourne提出,作为Project Coin/JSR 334的reply to Derek Foster's PROPOSAL: Binary Literals)。这里可以写成1_000_000_000
。大致按时间顺序,从最早到最新:
"(1)1111 1111"
(apparently not for decimal values, only for bitstrings representing binary, quartal, octal or hexadecimal values)1$000$000
1_000_000_000
1'000'000'000
对于语言来说,这是一个相对较新的特性,意识到它们应该支持(然后是Perl)。正如chux@的精彩回答一样,
1000*1000...
是一个部分解决方案,但会给程序员带来乘法溢出的bug,即使最终结果是一个大类型。dw1jzc5e6#
可能更容易阅读并获得与
1,000,000,000
表单的一些关联。从技术上看,我想直接数和乘法没有什么区别,编译器会把它生成为常数十亿。
如果你说的是objective-c,那么
1000^3
就不起作用了,因为pow没有这样的语法(它是xor)。相反,可以使用pow()
函数。但是在那种情况下,它不是最优的,它将是一个运行时函数调用,而不是编译器生成的常量。yhived7q7#
为了说明原因,考虑以下测试程序:
ltqd579y8#
在C语言中为十进制数实现类似效果的另一种方法是使用文字浮点表示法a-只要double可以表示所需的数字而不损失任何精度。
IEEE 754 64位双精度型可以表示任何〈= 2^53的非负整数。通常,长双精度型(80或128位)甚至可以更进一步。转换将在编译时完成,因此没有运行时开销。如果出现意外的精度损失,并且您有一个良好的编译器,则可能会收到警告。