53

Imagine I have the code:

vector<int> temp = vector<int>(1 000 000 000);

The above will not compile as the compiler will complain about the spaces. Is it possible to indicate to C++ to ommit those spaces when compiling, or otherwise make the number easier to read?

Makogan
  • 8,208
  • 7
  • 44
  • 112

6 Answers6

123

Try digit separator:

int i = 1'000'000'000;

This feature is introduced since C++14. It uses single quote (') as digit separator.


Also see:

33

When I've done similar things on platforms without C++14 (generally for microprocessors), I've represented large numbers by splitting it up with multiplication:

int i = (1000 * 1000 * 1000);

Add UL or L postfixes to taste

The advantage here is that it's compliant to basically any platform that supports C89 (and probably earlier).

Generally, it's probably safe to assume the multiplication operators will fall out at compile time, but if you're using constants like this in a loop, it might be worth double-checking.

Fake Name
  • 5,556
  • 5
  • 44
  • 66
  • 10
    This won't work as is on systems with 16-bit int. Similarly, while `1000'000'000'000` (or without the `'`s) will give you a `long long` on a 32-bit-`int` system, your approach of `1000*1000*1000*1000` will have UB due to overflow. You'll need to use a `long long` literal like e.g. `1000LL*1000*1000*1000`. – Ruslan May 28 '18 at 19:48
  • This seems like a dubious technique. Isn't multiplication a "slow" operator, with a high latency and a low throughput? – Galaxy May 29 '18 at 03:00
  • 1
    @Galaxy - See note about the multiplication falling out at compile time. – Fake Name May 29 '18 at 04:13
12

I usually #define constants for this purpose, as it saves counting zeroes and makes it very clear what you mean to anyone viewing the code. For example

#define THOUSAND 1000
#define MILLION 1000000

vector<int> temp = vector<int>(THOUSAND * MILLION);

This makes it clear I really do mean a thousand million and did not miscount the zeros

Obviously you can use enums if you prefer.

pico-help
  • 161
  • 3
  • 12
    For anyone curious about the choice of "thousand million" over "billion" -- ["billion" doesn't always mean 1e9](https://en.wikipedia.org/wiki/Billion). It's generally better to go with the unambiguous, if slightly thinkier, term, since that'll keep people from wondering why their values are a few orders of magnitude off, or possibly even "random" because they're wrapping. – Nic May 28 '18 at 10:08
  • 15
    Replace by `#define MILLION 100000` if your colleagues ever leaves an open session. :) – Eric Duminil May 28 '18 at 11:34
  • https://www.youtube.com/watch?v=l4bmZ1gRqCc – ctrl-alt-delor May 28 '18 at 11:44
  • 1
    @ctrl-alt-delor This is better: https://www.youtube.com/watch?v=C-52AI_ojyQ –  May 28 '18 at 12:51
1

Another idea could be:

#define _000 *1000

int k = 1 _000 _000;
Raul J
  • 43
  • 2
1

If you don't use C++14, another option would be using some kind of string-inherited class with an implicit int-cast and maybe a regex-check in the constructor to restrict the numbers. I use CString for an easy example.

class NumString : public CString
{
public:
    NumString(CString number) : num(number) { } //maybe insert some regex-check here
    operator long() const
    {
        CString tmp = num;
        tmp.Remove(' ');        
        return atol(tmp);
    }
private:
    CString num;
};


NumString a = "1 000 000 000";
int b = a;
bool test = b == 1000000000;
//test will be true
Otto V.
  • 169
  • 4
  • 11
0

As this reminds me of digit grouping my first clumsy approach without C++14
would be

#define INTGROUPED1(a)     (a%1000)
#define INTGROUPED2(a,b)   (a%1000*1000 + b%1000)
#define INTGROUPED3(a,b,c) (a%1000*1000000 + b%1000*1000 + c%1000)
int v1 = INTGROUPED1(        123);
int v2 = INTGROUPED2(    123,123);
int v3 = INTGROUPED3( 23,123,123);

but I would use such tricks rather in a private context.

Just consider someone writing

INTGROUPED3(1234,1234,1234); //This would be (234,234,234) without a compiler complaining

EDIT1:

Maybe a better aproach would be using the ## preprocessor operator

#define NUM_GROUPED_4ARGS(a,b,c,d) (##a##b##c##d)
int num = NUM_GROUPED_4ARGS(-2,123,456,789); //int num = (-2123456789);

This is more like WYSIWYG but not immune against misuse. E. g. you might want the compiler to complain about

int num = NUM_GROUPED_4ARGS(-2,/123,456,789);  //int num = (-2/123456789); 

but it will not.

grenix
  • 623
  • 7
  • 15
  • I can somehow understand the downvoting for my first approach (I indicated it myself as brainstorm by calling it clumsy) but at least it was the first non C++14 approach without having to #define macros for every number – grenix May 29 '18 at 08:18
  • This is an interesting out of the box solution. I like that you're actually able to use commas as the separator. With preprocessor metaprogramming, you could make a variadic macro like NUM_GROUP(123,456,789) that works for any number of groups. Anyway I wouldn't actually use the technique in real code but it's a nice experiment. – Jordan Melo May 31 '18 at 19:33