C ++: large integers

I am writing lexer as part of a compiler project, and I need to determine if the integer will be larger than what can fit in an int so that I can print the error. Is there a standard C ++ library for large integers that can fit this purpose?

+4
source share
9 answers

Standard C library functions for converting numeric strings to integers must detect numbers that are out of range and set errno to ERANGE to indicate a problem. See here

+10
source

Perhaps you can use libgmp. However, I think this is simply not necessary for your purpose.

If you, for example, parse your numbers to a 32-bit unsigned int, you

  • analyze the first no more than 9 decimal numbers (this gender (32 * log (2) / log (10)). If you have more of them, the number is fine.
  • take the next digit. If the number you received / 10 does not match the number of the previous step, the number is bad.
  • if you have more digits (for example, more than 9 + 1), the number is bad.
  • else the number is good.

Be sure to skip any leading zeros, etc.

+5
source

libgmp is a generic solution, although it may be a bit heavyweight.

For a lighter lexical analyzer, you can think of it as a string; trim leading zeros, then if it is longer than 10 digits, it is too long; if it’s shorter, then this is normal, if exactly 10 digits, the string is compared with the maximum values ​​2 ^ 31 = 2147483648 or 2 ^ 32 = 4294967296. Keep in mind that -2 ^ 31 is a legal value, but 2 ^ 31 is not. Also keep in mind the syntax for octal and hexadecimal constants.

+3
source

How about this one. Use atol and check for overflow and overflow.

#include <iostream> #include <string> using namespace std; main() { string str; cin >> str; int i = atol(str.c_str()); if (i == INT_MIN && str != "-2147483648") { cout << "Underflow" << endl; } else if (i == INT_MAX && str != "2147483647") { cout << "Overflow" << endl; } else { cout << "In range" << endl; } } 
+1
source

To anyone offering atoi:

  • My atoi () does not install errno.
  • The implementation of my atoi () does not return INT_MIN or INT_MAX on overflow.
  • We cannot rely on a sign reversal. Consider 0x4000 ... 0.
    • * 2 and the negative bit is set.
    • * 4, and the value is zero.
    • With base-10 numbers, our next digit will multiply this by 10.

These are all nuts. If your lexer does not read the numeric data, stop the premature optimization . It only leads to grief.

This approach may not be effective, but it is suitable for your needs:

 const char * p = "1234567890123"; int i = atoi( p ); ostringstream o; o << i; return o.str() == p; 

Or using the stack:

 const char * p = "1234567890123"; int i = atoi( p ); char buffer [ 12 ]; snprintf( buffer, 12, "%d", i ); return strcmp(buffer,p) == 0; 
+1
source

You might want to check out GMP if you want to deal with such numbers.

0
source

In your lexer, when you parse an entire string, you must multiply by 10 before adding each new digit (assuming you parse from left to right). If this total result suddenly becomes negative, you have exceeded the precision of the integer.

0
source

If your language (like C) supports evaluating expressions at compile time, you might also need to think about this.

Things like this:

 #define N 2147483643 // This is 2^31-5, ie close to the limit. int toobig = N + N; 

GCC will catch this by saying "warning: integer overflow in expression", but, of course, not a single literal overflow. It may be more than you need, I just thought that I would point it out as the real compilers in this section.

0
source

You can check if the number is higher or lower than INT_MAX or INT_MIN. You need #include <limits.h>

-1
source

All Articles