Hello,

Firstly I better warn you I'm quite new to C++ and to Linux so I'm sorry if my terminology/general understanding of how things work is a bit confused.

I've downloaded a code which is in C which is helpful for a course I'm doing on stellar structure, but I'd like to use it with C++. Everything translates just fine apart from the the definition of the maximum of a number as a "long long int". Apparently C++ doesn't support this form.

I use Linux (32 bit) and I'd like to be able to use that integer in my programme. Is there a library or particular compiler I can use so that I can have numbers like that in the programme, or is there a solution I can find without downloading anything? I currently use g++. My first thought was to turn the number into a double, as that stopped the errors appearing, but after a conversation with a more computer-literate friend, I've realised how ineffective that was (just to give you an idea of my level of understanding of these things).

If there's something I need to download, please could you send me a link, and ideally give me a bit of instruction as to exactly what I need to do with it once I've downloaded it, and what I'd need to include in the programme to use it (as I said, I'm very inexperienced with both the operating system and the programming language!)

Thanks!

I thought most modern c and c++ compilers supported some form of 64-bit integers. Try just "long long" instead of "long long int".

Thanks for the reply. I've tried that, and it doesn't seem to help. I just get the error "integer constant is too large for "long" type.

Please post your program -- maybe there is something else wrong with it. I don't have a *nix os so I can't really help you much.

//The smallest non-zero number and the number of significant figures

    const float         tiny_sp     = 3.4e-38F;

    const double        tiny_dp     = 1.7e-308;

    const long double   tiny_qp     = tiny_dp;

    const short int     sig_fig_sp  = 7;

    const short int     sig_fig_dp  = 15;

    const short int     sig_fig_qp  = sig_fig_dp;

    const float         eps_sp      = 1E-6;

    const double        eps_dp      = 1E-15;

    const long double   eps_qp      = eps_dp;



//The largest number for given precision

    const float         biggest_sp  = 3.4e38F;

    const double        biggest_dp  = 1.7e308;

    const long double   biggest_qp  = biggest_dp;

    const short int     biggest_i2  = 32767;

    const long int      biggest_i4  = 2147483647;

    const long long int	biggest_i8  = 9223372036854775807;

That's the top part of the code I'm using for defining. I link several other C++ codes together to form the overall programme, but when I try to do that the errors which come up are all related to the constant defined in the bottom line of this.

That value is correct as maximum for signed long long.

What specific compiler are you using?

Look at the include file <limits.h> to see what types and their ranges are available in that compiler.

Try putting "LL" after the literal value, as in:
const long long int biggest_i8 = 9223372036854775807LL;

Alas, long long int is not a standard type in C++ at the moment. Moreover, the C++ (and C) standard garantees that long number type is not less that ordinar type - that's all (for example, sizeof(long long int) >= sizeof(long int) , but not sizeof(long long) > sizeof(long) ).

Therefore it was a very careless project decision to rely upon non-standard long long int POD type with huge values range.

There are arbitrary precision integer arithmetics libraries for C++ and C but it seems you need too serious code refactoring to use those libraries (it's easier to move to double type).

If it's a very long (long long;) ) code use Windows+VC++ compiler with 64-bit long long type extension. Regrettably I don't know proper linux compilers with 64-bit long long (ask linux guru)...

Thanks for the information.

Could anyone suggest a Linux compiler with a 64-bit long long type extension? I've been having a look and can't seem to find anything. If anyone has any further ideas for how to fix this please let me know.

Thanks

Doesn't the latest version of g++ support it? Maybe you just need to download the lastest version. GNU is usually pretty good at keeping those compilers up-to-date.

The problem here is that g++ knows that only 64 bit can effectively be handled at the processor level. So the authors/steering committee have decided that if long int (which is 8 bytes long) is insufficient then you should be using the gmp (gnu multiple precision library).

Since this is a prerequisite to compile gcc/g++ (well, you can avoid it but it is more work than downloading and compiling gmp). You are likely to have it. If not then http://gmplib.org/ (this site also has the manuals).

It is very easy to use:

#include <iostream>
#include <gmpxx.h>

int main()
{
  mpz_class a,b,c;
  a="4567890237498712303247829734";
  b="4356789023749871231827348234";
  c=567423;
  std::cout<<"A = "<<a*b*c<<std::endl;
}

Then use g++ testProg.cpp -lgmpxx -lgmp to test it

Note that you use a string to initialize if you initialization is very very big.

You can compare / use it in conjunction with int etc. Note that you need to use a suitable get_xx function to convert back to int. You can check the number is suitable for the conversion as well.

Anyway if you get stuck post a bit of code and I hope we can help. If it is open source (and much of the astronomy code is -- then just the link will do)

Comments
Useful pointer :-)

So the authors/steering committee have decided that if long int (which is 8 bytes long)

Where do you get an 8 byte long int? It's 4 bytes everywhere I've seen.

Where do you get an 8 byte long int? It's 4 bytes everywhere I've seen.

A long long int (signed/unsigned) is 8 bytes. cout<<sizeof(long long)

A long long int (signed/unsigned) is 8 bytes. cout<<sizeof(long long)

Sorry I think I have made a mistake. I only have 64 machines so I get 8 byte. (by default). It you want 8 byte on a 32 bit x86 machine you will need the correct option on your configure line when you build gcc.

The quick way then is to use the gmp.

A long long int (signed/unsigned) is 8 bytes. cout<<sizeof(long long)

vmanes was correct -- you said a "long int", not long long.

>>I only have 64 machines so I get 8 byte. (by default).
I'm running 64-bit Vista using VC++ 2008 Express and sizeof(long) is 4 bytes. It probably depends also on the compiler.

I realize that TR1 is not a standard yet, but if you don't want to use GMP and you don't want to use g++'s 'long long', perhaps this will do:

#include <iostream>
#include <tr1/cstdint>

int main() {
    std::tr1::int64_t foo = 99999999999999999LL;
    long long int bar = 99999999999999999LL;
    std::cout << foo << "\n" << bar << std::endl;
    std::cout << foo + bar << std::endl;
    return 0;
}

tr1::int64_t seems to work fine using g++. I'm sure if you were using VC++, you could point it to the TR1 headers as well.

I'm sure if you were using VC++, you could point it to the TR1 headers as well.

Now VC++ 2008 supports 64-bit long long w/o TR1 headers (no such headers in VC++).

VC++ 2005 also supports long long int with no special/additional headers.

OP is working in Linux, where current version of gcc also supports long long int. At least as far back as ver 4.1.3.

http://blogs.msdn.com/vcblog/archive/2008/01/08/q-a-on-our-tr1-implementation.aspx

Just a suggestion. That pack has been available since January 2008. *shrug*

I would assume it is better to use part of TR1 where available as opposed to g++/VC++ extensions, even if they appear to provide the same thing.

Of course, if this is for a personal project, I'm sure it doesn't matter anyways. :)


EDIT: I realize that link is old and that it say that TR1 implementations aren't available for VC++ Express - that is not the case anymore. VC++ SP1 and VC10 both have these headers now.

This article has been dead for over six months. Start a new discussion instead.