user2826094
user2826094

Reputation: 133

What is the point of 'L' here?

//Using the if-else
#include <iostream>
using std::cin;
using std::cout;
using std::endl;

int main() {
  long number = 0;                  // Store input here
  cout << "Enter an integer less than 2 billion: ";
  cin >> number;
  cout << endl;

  if(number % 2L == 0)              // Test remainder after division by 2
    cout << "Your number is even."  // Here if remainder is 0
         << endl;
  else
    cout << "Your number is odd."   // Here if remainder is 1
         << endl;
  return 0;
}

Here, in the first 'if' condition, why do they have 'L' after 2? taking 'L' out seems to run the code just fine.

Upvotes: 3

Views: 397

Answers (2)

Wolph
Wolph

Reputation: 80111

In this case there is no need for it.

The L indicates a long value which means it reserves more space just your calculation will go beyond the range of a normal integer.

Upvotes: 0

Matteo Italia
Matteo Italia

Reputation: 126937

The L suffix is used to signify that a number literal is of type long int. Normally it is not necessary if you are just assigning the value to a variable, since, as for C++11 §2.14.2 ¶2 (and in particular table 6), a decimal integer literal without suffix will be of the first type that can represent it between int, long int or long long int.1

So, you don't risk to have the value itself truncated; but:

  1. you do have a certain degree of uncertainty about the type of the literal (32768 may be an int or a long, depending from the platform/compiler);
  2. you may inadvertently get a literal of the wrong type for your specific expression.

So, you need to specify L instead in contexts where you want to be sure that the type of the literal is long (or bigger); two important cases come to mind:

  • resolving overloads; if you have two overloads of a function, one for int and one for long, and you want to be sure to call the long one even if you are passing a small number, you'll have to use a long literal;

    void foo(int);
    void foo(long);
    
    foo(1);      // <-- will call the first overload
    foo(1L);     // <-- will call the second overload
    foo(32768);  // <-- may call the first or the second overload, depending
                 //     from the specific platform
    foo(32768L); // <-- will call the second overload
    
  • but most importantly: avoid surprises when doing arithmetic; if you perform e.g. a multiplication like this:

    int a;
    ...
    long v=32767*a; // don't let the "long" fool you - 32767*a is evaluated as an int!
    

    32767 is an int literal (since it's small enough to fit an int), a is an int, and the result will be an int, even if you are assigning to a long. This may be a problem if a can be big enough to overflow your calculation; by specifying a long literal, you guarantee that you'll perform a long multiplication.

    long v=32767L*a; // now we are doing all the math with longs
    

    (This problem is actually way more frequent with division and FP literals, where often you have to specify double or float literals to get the intended "real division" behavior)

    As @chris suggests, a way more frequent situation (of this same kind) arises when doing "big" bitshifts, e.g.:

    long long mask=1<<53;
    

    presents the same problem as above: 1 is an int, 53 is an int, the computation will be performed with ints, resulting in overflow (although in this particular case any decent compiler will issue a warning); here the correct form would be:

    long long mask=1LL<<53; // LL is the suffix for long long
    

Coming to your particular code: there's no risk in taking the L away; since number is already a long, 2 will be promoted to long anyway in doing the modulo (as per the "usual arithmetic conversions", §5 ¶10, and §4.5), so here L makes no difference.

Still, in many cases it's not a bad idea to keep the literal of the "intended type": it guarantees that, even if the type of the other operand is changed for some reason to a narrower type, the computation will still be done in the intended way (not that for modulo it would make any difference).


  1. The type of an integer literal is the first of the corresponding list in Table 6 in which its value can be represented. table from the C++11 standard describing the type to be used for integer literals

Upvotes: 11

Related Questions