32bit Integer cap on 64bit OS
I’m using Qt Creator 2.2.0 based on Qt 4.7.4 (32bit) on Windows 7 Enterprise x64. I can’t remember where to find my g++ compiler version. I’m also an engineer by training, so the obvious answer to a programmer is probably the right one.
Given the following code: Made nrows an int for clarity[/edit]
- int npts = 71338;
- int nrows = npts*(npts - 1);
I always get the result 794,071,610. The expected value is 5,089,038,906.
Now, I understand that the maximum range of a 32bit integer is 2^32 (or 4,294,967,296). When I subtract that from the expected value using my trusty TI-82, I get the observed result. This suggests to me that this is a type range issue.
But when I try other data types for nrows
- long long, qint64, quint64, int_fast64_t, int_least64_t, __int64
Anyone have an explanation or solution? Thanks!
The reason is probably that the compiler is using 32bit ints and you only assign the result to long long or whatever.
This should work
- long long npts = 71338;
- long long nrows = npts*(npts - 1);
Sometimes you have to append suffixes. I should be something like:
- long long nrows = 71338LL * 71337LL;
Of course, there are numerous other possibilities such as
- qint64 nrows = qint64 ( 71338 ) * qint64 ( 71337 )
I cannot reproduce the problem:
- int main(int argc, char *argv)
- QCoreApplication a(argc, argv);
- int v_int = 71338;
- int v_int_2 = v_int * (v_int-1);
- qDebug() << "int :" << v_int << " --> " << v_int_2;
- long v_long = 71338;
- long v_long_2 = v_long * (v_long-1);
- qDebug() << "long :" << v_long << " --> " << v_long_2;
- long long v_longlong = 71338;
- long long v_longlong_2 = v_longlong * (v_longlong-1);
- qDebug() << "long long:" << v_longlong << " --> " << v_longlong_2;
- qint64 v_qint64 = 71338;
- qint64 v_qint64_2 = v_qint64 * (v_qint64-1);
- qDebug() << "qint64 :" << v_qint64 << " --> " << v_qint64_2;
- quint64 v_quint64 = 71338;
- quint64 v_quint64_2 = v_quint64 * (v_quint64-1);
- qDebug() << "quint64 :" << v_quint64 << " --> " << v_quint64_2;
- return 0;
the output on a 32 bit system is:
- int : 71338 --> 794071610
- long : 71338 --> 794071610
- long long: 71338 --> 5089038906
- qint64 : 71338 --> 5089038906
- quint64 : 71338 --> 5089038906
The only difference on a 64bit Linux system is that the long version is correct too.
As koahnig already mentioned, make sure that all variables involved are of the bigger type, otherwise you may suffer from unwanted downcasts.
Kaohnig and Volker hit the nail on the head. Because npts was only an int, the computation was downcast regardless of the type I assigned to nrows. Since I can’t change the type of npts (it comes from other code… I showed it adjacent for clarity in my post), I had to recast it during the nrows computation:
- int npts = 71338;
- quint64 nrows = quint64(npts) * ( quint64(npts) - 1 ); //5089038906 as expected
Thanks for the help! I knew it was something obvious.