August 17, 2011

phlucious phlucious
Lab Rat
22 posts

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: [edit]Made nrows an int for clarity[/edit]

  1. int npts = 71338;
  2. 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

  1. long long, qint64, quint64, int_fast64_t, int_least64_t, __int64
I get the same result! The only data type I’ve seen work thus far is a double, but since nrows is a counter I’d prefer to keep it as an integer if possible.

Anyone have an explanation or solution? Thanks!

4 replies

August 17, 2011

koahnig koahnig
Area 51 Engineer
2873 posts

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

  1. long long npts = 71338;
  2. long long nrows = npts*(npts - 1);

Sometimes you have to append suffixes. I should be something like:

  1. long long nrows = 71338LL * 71337LL;

for example.
Of course, there are numerous other possibilities such as
  1. qint64 nrows = qint64 ( 71338 ) * qint64 ( 71337 )

August 17, 2011

mlong mlong
Robot Herder
1551 posts

This works for me:

  1. #include <QtCore/QCoreApplication>
  2. #include <QDebug>
  3.  
  4. int main(int argc, char *argv[])
  5. {
  6.     quint64 val = 71338;
  7.     quint64 result = val * (val - 1);
  8.  
  9.     qDebug() << result;
  10.  
  11.     return 0;
  12. }

 Signature 

Senior Software Engineer
AccuWeather Enterprise Solutions
/* My views and opinions do not necessarily reflect those of my employer.  Void where prohibited. */

August 17, 2011

Volker Volker
Ant Farmer
5428 posts

I cannot reproduce the problem:

  1. int main(int argc, char *argv[])
  2. {
  3.     QCoreApplication a(argc, argv);
  4.  
  5.     int v_int = 71338;
  6.     int v_int_2 = v_int * (v_int-1);
  7.     qDebug() << "int      :" << v_int << " --> " << v_int_2;
  8.  
  9.     long v_long = 71338;
  10.     long v_long_2 = v_long * (v_long-1);
  11.     qDebug() << "long     :" << v_long << " --> " << v_long_2;
  12.  
  13.     long long v_longlong = 71338;
  14.     long long v_longlong_2 = v_longlong * (v_longlong-1);
  15.     qDebug() << "long long:" << v_longlong << " --> " << v_longlong_2;
  16.  
  17.     qint64 v_qint64 = 71338;
  18.     qint64 v_qint64_2 = v_qint64 * (v_qint64-1);
  19.     qDebug() << "qint64   :" << v_qint64 << " --> " << v_qint64_2;
  20.  
  21.     quint64 v_quint64 = 71338;
  22.     quint64 v_quint64_2 = v_quint64 * (v_quint64-1);
  23.     qDebug() << "quint64  :" << v_quint64 << " --> " << v_quint64_2;
  24.  
  25.     return 0;
  26. }

the output on a 32 bit system is:

  1. int      : 71338  -->  794071610
  2. long     : 71338  -->  794071610
  3. long long: 71338  -->  5089038906
  4. qint64   : 71338  -->  5089038906
  5. 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.

August 18, 2011

phlucious phlucious
Lab Rat
22 posts

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:

  1. int npts = 71338;
  2. quint64 nrows = quint64(npts) * ( quint64(npts) - 1 ); //5089038906 as expected

Thanks for the help! I knew it was something obvious.

 
  ‹‹ [Solved]Implementing a cancel button      Qt on windows: Avoid the Taskbar Icon ››

You must log in to post a reply. Not a member yet? Register here!