Why write 1,000,000,000 as 1000*1000*1000 in C?

Objective CCIntegerLiterals

Objective C Problem Overview


In code created by Apple, there is this line:

CMTimeMakeWithSeconds( newDurationSeconds, 1000*1000*1000 )

Is there any reason to express 1,000,000,000 as 1000*1000*1000?

Why not 1000^3 for that matter?

Objective C Solutions


Solution 1 - Objective C

One reason to declare constants in a multiplicative way is to improve readability, while the run-time performance is not affected. Also, to indicate that the writer was thinking in a multiplicative manner about the number.

Consider this:

double memoryBytes = 1024 * 1024 * 1024;

It's clearly better than:

double memoryBytes = 1073741824;

as the latter doesn't look, at first glance, the third power of 1024.

As Amin Negm-Awad mentioned, the ^ operator is the binary XOR. Many languages lack the built-in, compile-time exponentiation operator, hence the multiplication.

Solution 2 - Objective C

>Why not 1000^3?

The result of 1000^3 is 1003. ^ is the bit-XOR operator.

Even it does not deal with the Q itself, I add a clarification. x^y does not always evaluate to x+y as it does in the questioner's example. You have to xor every bit. In the case of the example:

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

But

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

Solution 3 - Objective C

There are reasons not to use 1000 * 1000 * 1000.

With 16-bit int, 1000 * 1000 overflows. So using 1000 * 1000 * 1000 reduces portability.

With 32-bit int, the following first line of code overflows.

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

Suggest that the lead value matches the type of the destination for readability, portability and correctness.

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

Also code could simple use e notation for values that are exactly representable as a double. Of course this leads to knowing if double can exactly represent the whole number value - something of concern with values greater than 1e9. (See DBL_EPSILON and DBL_DIG).

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

Solution 4 - Objective C

For readability.

Placing commas and spaces between the zeros (1 000 000 000 or 1,000,000,000) would produce a syntax error, and having 1000000000 in the code makes it hard to see exactly how many zeros are there.

1000*1000*1000 makes it apparent that it's 10^9, because our eyes can process the chunks more easily. Also, there's no runtime cost, because the compiler will replace it with the constant 1000000000.

Solution 5 - Objective C

For readability. For comparison, Java supports _ in numbers to improve readability (first proposed by Stephen Colebourne as a reply to Derek Foster's PROPOSAL: Binary Literals for Project Coin/JSR 334) . One would write 1_000_000_000 here.

In roughly chronological order, from oldest support to newest:

It's a relatively new feature for languages to realize they ought to support (and then there's Perl). As in chux@'s excellent answer, 1000*1000... is a partial solution but opens the programmer up to bugs from overflowing the multiplication even if the final result is a large type.

Solution 6 - Objective C

Might be simpler to read and get some associations with the 1,000,000,000 form.

From technical aspect I guess there is no difference between the direct number or multiplication. The compiler will generate it as constant billion number anyway.

If you speak about objective-c, then 1000^3 won't work because there is no such syntax for pow (it is xor). Instead, pow() function can be used. But in that case, it will not be optimal, it will be a runtime function call not a compiler generated constant.

Solution 7 - Objective C

To illustrate the reasons consider the following test program:

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

Solution 8 - Objective C

Another way to achieve a similar effect in C for decimal numbers is to use literal floating point notation -- so long as a double can represent the number you want without any loss of precision.

IEEE 754 64-bit double can represent any non-negative integer <= 2^53 without problem. Typically, long double (80 or 128 bits) can go even further than that. The conversions will be done at compile time, so there is no runtime overhead and you will likely get warnings if there is an unexpected loss of precision and you have a good compiler.

long lots_of_secs = 1e9;

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionDuckView Question on Stackoverflow
Solution 1 - Objective CPiotr FalkowskiView Answer on Stackoverflow
Solution 2 - Objective CAmin Negm-AwadView Answer on Stackoverflow
Solution 3 - Objective Cchux - Reinstate MonicaView Answer on Stackoverflow
Solution 4 - Objective CTamás ZaholaView Answer on Stackoverflow
Solution 5 - Objective CdjechlinView Answer on Stackoverflow
Solution 6 - Objective CMadars ViView Answer on Stackoverflow
Solution 7 - Objective CPeter - Reinstate MonicaView Answer on Stackoverflow
Solution 8 - Objective Cjschultz410View Answer on Stackoverflow