Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

In languages that don't allow underscores in integer literals, is it a good idea to create a constant for 1 billion? e.g. in C++:

size_t ONE_BILLION = 1000000000;

Certainly, we shouldn't create constants for small numbers like 100. But with 9 zeros, it's arguably easy to leave off a zero or add an extra one in code like this:

tv_sec = timeInNanosec / 1000000000;
tv_nsec = timeInNanosec % 1000000000;
share|improve this question
24  
I hope everyone here votes for NO. That way, maybe one day my bank will transfer one billion dollars to my account because a programmer didn't use a constant and misplaced a zero! :) –  Mathew Foscarini May 24 '13 at 16:30
43  
Why not create constants for small numbers? What does 100 mean? Unless there is some context, it's a magic number. –  Allan May 24 '13 at 16:30
4  
@MathewFoscarini In general, mistakes can go either way. But when it comes to your bank, mistakes will always go against you. –  emory May 24 '13 at 18:30
22  
Consider writing 1e9, 10^9 or 1_000_000_000 if the language you are using supports it. –  hammar May 24 '13 at 18:58
4  
Long scale or short scale billion? –  rvalue May 26 '13 at 6:42

13 Answers 13

up vote 28 down vote accepted

Most languages feature some kind of exponential notation. A million is 1e6, (meaning 1 times 10 to the power of 6). This basically solves the issue even better than most propositions here.

In a lot of C-like languages, the scientific notation is however defining a floating point type, which is unfortunate if you really need an int. However, you can easily type-cast that constant to avoid implicit conversions in your formular.

n / int(1e9) would divide by a billion.

In your example, dealing with physical quantities (time in nanosecond), I would generally ask myself whether integer is the right type. In fact a floating point double might be better suited when dealing with measurable quantities (although there are of course cases where you would prefer a long long).

share|improve this answer
6  
I think the NANOSECONDS_IN_ONE_SECOND solution is much clearer and neater –  Andreas Bonini May 25 '13 at 17:40
1  
The Question was about integer liberals and I propose to use scientific notation. Whether to do this in place or by defining a constant is an issue of structuring code that was not asked for in the question. Defining a constant adds limited abstraction, I would write a conversion function/macro to achieve better abstraction –  wirrbel May 25 '13 at 18:00
1  
would casting a very large double to an int not risk the typical rounding difference problems of floating point numbers? –  Philipp May 26 '13 at 12:11
    
with normal precision integer types this shouldnot be a problem as long as you use a double precision float to convert from. you are right when using values of the long long range. –  wirrbel May 26 '13 at 12:50

Create one called NANOSECONDS_IN_ONE_SECOND instead as that what it represents.

Or a shorter, better name if you can think of one.

share|improve this answer
57  
I'd say Nanoseconds_Per_Second but this is, in my opinion, the correct answer. –  KChaloux May 24 '13 at 16:56
8  
@Mathew I don't get your point. There's nothing wrong with saying millimeters per meter. You may be implying that it is redundant, in that nanosecond MEANS one billion fractions of a second, but there's nothing wrong in stating it again. It's like saying 1 + 1 = 2. "x per y" continues to make more sense when x and y are disjoint, like "units per half dozen" or "nanoseconds per millisecond" –  Mark Canlas May 24 '13 at 17:34
7  
@MathewFoscarini Actually, no, in this context it's not. If it were, a constant named NANOSECONDS is meaningless as you can't tell what it's supposed to apply to. Likewise, NANOSECONDS_PER_MICROSECOND is a similar valid constant that makes sense. –  Izkata May 24 '13 at 17:41
5  
@MathewFoscarini, "millimeters per meter" is a way to remove the unit on the conversion to get the raw value. 1mm/1m = 1000, which is exactly the point of what's being done here. –  zzzzBov May 24 '13 at 19:48
10  
Why so much typing? NS_PER_SEC should be obvious to anyone who ought to be dealing with nanoseconds. –  Rex Kerr May 24 '13 at 21:03

Constants are meant to give numbers meaning. There is not any additional meaning in ONE_BILLION to 1000000000. Actually, it makes it more confusing, because in different natural languages, a billion means something different (either a thousand million or a million million)! If you want to write it shorter, there's a good chance your programming language allows the use scientific notation, i.e. 1e9. Otherwise, I agree with @JohnB, that this number really means the number of nanoseconds in a second, so name it that.

share|improve this answer
3  
+1 for mentioning scientific notation. –  mskfisher May 24 '13 at 19:57
9  
Good pointing that billion in different languages mean different amount of zeros. –  frozenkoi May 24 '13 at 22:46
3  
would suggest changing regular languages to natural languages. regular means something else... –  jk. May 25 '13 at 6:39
3  
You don't need different languages. You don't even need different countries. In British English, "billion" means something different before and after 1974 in official communications (mass media and government), and both usages still exist. –  Jörg W Mittag May 26 '13 at 11:26
1  
"There is not any additional meaning in ONE_BILLION to 10000000000.. I disagree. (Hint: I deliberately misquoted you and added another zero; would have have noticed if I hadn't mentioned it?) –  Keith Thompson Jun 3 '13 at 19:41

For one or two usages, I would use the convention:

tv_sec = timeInNanosec / (1000 * 1000 * 1000);
tv_nsec = timeInNanosec % (1000 * 1000 * 1000);

It's perfectly self explanatory, gets compiled to a constant and it's hard to screw up.

Also, it's very useful in cases such as:

var Time = 24 * 60 * 60;

where it's easy to see we are talking about one day in seconds.

share|improve this answer
    
This is what I usually do. It also has the advantage that I won't forget that I defined NANOSECONDS_IN_ONE_SECOND yesterday and define NANOSECONDS_PER_SECOND today. And perhaps ONE_AMERICAN_BILLION tomorrow. –  Thomas Padron-McCarthy May 25 '13 at 10:21
    
Surely 'SecondsInOneDay = 24 * 60 * 60' is easier still? –  JBRWilkinson May 26 '13 at 17:22
    
@JBRWilkinson sure, my initial snippet was using a class instance.Time = ..., but then I dumbed it down... –  Sklivvz May 26 '13 at 20:29
2  
In C or C++, (1000 * 1000 * 1000) is of type int, which is only required to be 16 bits, so it can overflow. You can write (1000L * 1000L * 1000L) to avoid that. –  Keith Thompson Jun 3 '13 at 19:36
    
I do this a lot. It works very well. –  vy32 Jun 11 '13 at 15:13

The length of the value is not what defines whether a constant is needed or not.

You use constants to avoid magic numbers, not to avoid typing.

For example these are perfectly valid constants:

public static final int CLOSE_CURSORS_AT_COMMIT = 1;
public static final int CONCUR_READ_ONLY = 2;
public static final int CONCUR_UPDATABLE = 3;
public static final int FETCH_FORWARD = 4;
public static final int FETCH_REVERSE = 5; 
public static final int FETCH_UNKNOWN = 6;
public static final int HOLD_CURSORS_OVER_COMMIT = 7;
public static final int TYPE_FORWARD_ONLY = 8;
public static final int TYPE_SCROLL_INSENSITIVE = 9;
public static final int TYPE_SCROLL_SENSITIVE = 10;

Use:

public static final int NANOSECS_PER_SECOND = 1000000000;

(code samples are in Java, translate to your favorite language )

share|improve this answer
3  
+1 Named numbers are nearly useless. The purpose of constants it to give meaning to those numbers. What do they represent? What thing are they counting or limiting or formally named coefficient? Not what is the value of the count. –  JustinC May 24 '13 at 18:52
5  
Seeing as we're talking Java, I'll make the observation that, as of Java 7, we can put underscores in numbers to help readability! –  Nick May 24 '13 at 20:54
2  
Those are terrible examples of valid constants. They should have been enums, except they were created before enums. –  Christoffer Hammarström May 26 '13 at 17:38
    
@ChristofferHammarström They were indeed created before enums, they are part of the ResultSet class, in the SQL package of the Java SDK. –  user61852 May 26 '13 at 20:39
2  
@ChristofferHammarström They're bad because now we have enums but not for being unmeaningful. Enum didn't exist when these classes were created and in order to differentiate between mutually exclusive options like FETCH_FORWARD and FETCH_REVERSE is giving them a different value. The value doesn't matter, just the fact that they are different. –  user61852 May 27 '13 at 11:40

An American or European billion?

(or in technical terms, a billion in the short scale or long scale - one is 1000 million, the other is a million million).

Given this confusion, then I'd say yes - it makes sense to define it once and keep with it, likewise applies to any constant you need to agree the definition on - define it once.

share|improve this answer
17  
"An American or European billion?" - "What? I don't know that! Ahhhhh!!!!" –  Tesserex May 25 '13 at 0:01
    
In the UK, at least, we've long since adopted the 1e9 billion. –  Jack Aidley May 25 '13 at 7:45
1  
@Tesserex - well, you have to know these things when you're a king, you know. –  gbjbaanb May 25 '13 at 12:51

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.

share|improve this answer
2  
+1 for one of the best abuses of the preprocessor I've seen. I'd still go with NSEC_PER_SEC or something in production, though. –  Victor May 25 '13 at 16:34
    
Very nearly -1 for abusing the preprocessor :) –  Michael Kjörling May 26 '13 at 14:11

Yeah, that sounds like a reasonable idea. Off-by-one DIGIT errors are even worse than the infamous off-by-one errors. Although, it may create confusion for other people (including your future self) to read the code.

A more explanatory name like NANOSEC_PER_SEC seems good, as it would add clarity where it is used for time. However, it makes no sense to use in contexts other than time, and it would be impractical to create a separate 1,000,000,000 for every situation.

What you really want to do, silly as it seems at first, is 'divide over sec'. This leaves NANO_PER, which is not only language-independent (10^9 in America and Europe) but also situation-independent (no limiting on the units), and it is easy to type and read.

share|improve this answer
    
this post is rather hard to read (wall of text). Would you mind editing it into a better shape? –  gnat May 24 '13 at 21:12
1  
Fixed :) Thanks for the tip! –  MegaWidget May 24 '13 at 22:09

In general it's a bad idea to use scalar constants for unit conversions, and if you find yourself making constants for such things you're doing conversion in way too many places.

When you have a quantity of one unit (say, 10 seconds), and want to convert to another unit (i.e. nanoseconds); this is precisely the time to use the type system of your language to ensure that the units are actually scaled as you intend.

Make your function take a Nanoseconds parameter, and provide conversion operators and/or constructors in that class for Seconds, Minutes, or what-have-you. This is where your const int or #define or 1e9 seen in other answers belongs.

This avoids having variables of ambiguous units floating around your code; and prevents entire swathes of bugs from where the wrong multiply/divide was applied, or was already applied, or the quantity was actually distance instead of time, or...

Also, in such classes it's good to make construction from plain scalarsprivate and use a static "MakeSeconds(int)" or similar to discourage sloppy use of opaque numbers.

More specifically to your example, in C++ check out Boost.Chrono.

share|improve this answer
    
+ At the very least, use a common type with a scaling or offset factor from a basis, much like the often maligned timezone. –  JustinC May 26 '13 at 8:50

I personally wouldn't consider it good practice to create a constant unless it needs to be a constant. If its going to be in multiple places and having it defined at the top of the file for modification / or testing is going to be useful then absolutely.

If its just because its awkward to type ? then no.

Personally if I got someone else's code that had a constant defined, I generally consider this to be an important aspect of the code. E.g. tcp keep alive timers, maximum number of connections allowed. If I had to debug it I would probably pay a lot of unneeded attention to it trying to figure out why / where its being used.

share|improve this answer
    
+1, I hope bank programmers read this :) –  Mathew Foscarini May 24 '13 at 16:31
    
I get the joke but if bank programers had to make a constant for every number you could transfer the software would be gigantic, unmanageable and slow. I could only imagine what that would be like, imagine being told it would take 3 working days to transfer money to .... OH MY GOD, THATS IT!!! –  Simon McLoughlin May 24 '13 at 17:08
    
My bank does take 3 days to transfer money :( –  Mathew Foscarini May 24 '13 at 17:14
1  
@MathewFoscarini bankers use Excel they do not need programmers ;) –  Mateusz May 24 '13 at 17:44
    
@Simon Depending on language and compiler, constants should be optimized into the code, incurring little overhead. I understand your point, but constants can be used wherever using a name instead of a magic number would help code readability. –  Steven May 24 '13 at 20:31

When you think about why you wrote "1 Billion" instead of "1000000000" in your question title, you'll realise why the answer is yes.

share|improve this answer

Do not create a constant for your big literals. You would need a constant for each such literal, which is (in my opinion) a complete joke. If you desperately need to make your literals clearer without the help of things like syntax highlighting, you could (though I would not) create functions or macros to make your life "easier":

#define SPLIT3(x, y, z) x##y##z

int largeNumber1 = SPLIT3(123,456,789);
int largeNumber2 = 123456789;
share|improve this answer

I would do this:

const int Million = 1000 * 1000;
const int Billion = 1000 * Million;

or

const int SciMega = 1000 * 1000; const int SciGiga = 1000 * SciMega;

Regarding number of nanoseconds per second: nano is the "inverse" of giga.

Kilo  Mega  Giga   etc.
10^3  10^6  10^9
Milli Micro Nano   etc.
10^-3 10^-6 10^-9

Note the "Sci" - for scientific, as in computers, the meanings of kilo, mega, giga etc. are different: 1024 (2^10), 1024*1024 (2^20), etc. 2 megabytes is not 2,000,000 bytes.

UPDATE Commenter pointed out that special terms exist for digital exponents of 2: http://en.wikipedia.org/wiki/Mebibyte

share|improve this answer
    
"2 megabytes is not 2,000,000 bytes." Ask any spinning-platter hard disk manufacturer you want. (Not the downvoter, btw.) –  Michael Kjörling May 26 '13 at 14:13
    
@michaelkjorling this is a programming question, not a business ethics or marketing one. I do agree about hard drives, but that's a different topic. And ouch about the down votes! –  Mr. TA May 27 '13 at 14:46
1  
Actually, 2 Megabytes is 2,000,000 bytes. 2 Mebibytes is 2,097,152 bytes. See en.wikipedia.org/wiki/Mebibyte –  vy32 Jun 11 '13 at 15:14
    
@vy32 thanks, never heard of that before. Will update my answer to reflect that. –  Mr. TA Jun 11 '13 at 17:14
    
@Mr.TA, no problem! We're working hard to bring Computer Science into compliance with SI Units! Join the club. –  vy32 Jun 11 '13 at 22:16

protected by gnat Nov 4 at 14:02

Thank you for your interest in this question. Because it has attracted low-quality answers, posting an answer now requires 10 reputation on this site.

Would you like to answer one of these unanswered questions instead?

Not the answer you're looking for? Browse other questions tagged or ask your own question.