Reasons Not To
Firstly, here is a reason not write any underscores or use any trick to simulate it: it makes the constants harder to find in the code. Suppose that some program exhibits, somewhere in its operation, hard-coded value 1500000 for some parameter. I want to know where in the source code of the program this actually occurs, so I grep the code for 1500000
, and find nothing. Why? Might it be in hexadecimal (but why for such a round decimal number). Unbeknownst to me, the constant is actually written as 1_500_000
. I needed the regex 1_?500_?000
.
Guiding Characters in Comment
Just because one kind of visual aid is not available, or we don't wish to use it for the above reason, doesn't mean that we cannot take advantage of the two dimensions of the text file to create an alternative visual aid:
foo = bar / 1000000000;
// --^--^--^
With this we can easily convince ourselves that there are three groups of three zeros. Yet, we can still grep the source code for 1000000000
and find it.
Syntax Coloring
A text editor with programmable syntax coloring can be made to color groups digits in numeric constants with alternating colors for better readability. We don't have to do anything in the code.
Preprocessing: C, C++, Objective C
Now, if we really want some commas between digits, in C and C++ we can use some preprocessing:
/* Four digit base TH-ousand constant macro */
/* Condensed using Horner's rule */
#define TH(A,B,C,D) ((((((A) * 1000) + (B)) * 1000) + (C)) * 1000 + D)
tv_sec = nanoseconds / TH(1,000,000,000)
Works for numbers like TH(1,234,567,890)
.
A macro similar to TH can also work with token pasting rather than arithmetic. In the C preprocessor, the binary ##
operator ("token paste") can be used in a macro body in order to paste together two operands into a single token. One or both of the operands can be macro arguments. The downside here (creating a risk for us) is that if the resulting catenation isn't a valid token, the behavior is undefined.
#define TOK4(A, B, C, D) A ## B ## C ## D
Now
TOK4(1,000,000,000) /* produces the single token 1000000000 */
TOK4(1,123,000,000.0E+2) /* produces the single token 1123000000.0E+2 */
TOK4(pr,in,t,f) /* produces the token printf */
TOK4(#,*,a,b) /* undefined behavior, #*ab is not valid token syntax */
C programs that paste together identifiers and use the results to name global variables and functions exist and are awful to work with because they are impervious to tools like GNU id-utils and ctags.
1e9
,10^9
or1_000_000_000
if the language you are using supports it.