1

I'm using double long in my 64 bit computer and sizeof(double long) is 16 bytes. So I do the following assignment:

  long double f = 0xA0000000000000000000000000000000; // 32 characters in hex

and I get this warning: warning: integer constant is too large for its type. That warning doesn't seem correct, my constant can be easily saved in a 128bit value. So, why do I get the warning?

I also have this code:

  long double tmp = 0x90000000CCCCCCCC0000000000000000;
  long double res = (f & tmp);  // where f is the previously defined variable

and I get the following error error: invalid operands to binary &. Why ?

Fooko R.
  • 129
  • 1
  • 10

3 Answers3

2
error: invalid operands to binary &

because f and tmp are floating point numbers, not integers, they cannot serve as argument to binary &.

long double f = 0xA0000000000000000000000000000000

You are initializing a floating-point variable with an integer constant. That is OK per se, but the integer constant has its own type, which can only be as large as the largest integer type you have (the compiler chooses the type that fits). If the largest integer type on your compiler has less than 128 bits, this won't work.

BTW that sizeof(double long) == 16 doesn't mean that long double has 128 bit representation.

jpalecek
  • 47,058
  • 7
  • 102
  • 144
  • Hm... yes I missed that. Do you perhaps know any other type that has 128bit values other that I Can use it with binary operators? (My `long long` is 64 bits) – Fooko R. Feb 13 '12 at 11:39
1

Expanding my comment:

long double is a floating-point type. That's why you can't do bit-wise operators on them.

Unfortunately, the standard doesn't guarantee a 128-bit integer type. The only compiler I know of that actually supports it as an extension is GCC via __int128. (EDIT: It doesn't look it always supports it.)

MSVC also has the __int128 type, but it remains only reserved and unimplemented.

If you're only doing bit-wise operations, you can use a struct with two 64-bit integers. Or if you're on x86, you can use the 128-bit SSE datatypes.

Mysticial
  • 464,885
  • 45
  • 335
  • 332
  • About `__int128` it writes: `here is no support in GCC to express an integer constant of type __int128 for targets having long long integer with less then 128 bit width.` . My `long long` is 64 bytes, so it's not supported! – Fooko R. Feb 13 '12 at 11:48
  • Yeah, I noticed that. If you want more than bit-wise operators, then you're out of luck unless you find/write a light-weight 128-bit integer library. – Mysticial Feb 13 '12 at 11:49
1

0xA0000000000000000000000000000000 is an integer constant and depending on your system it can be not supported. The larger type for integer constant is unsigned long long and if the width of unsigned long long is 64-bit in your system, this constant will not fit.

What you can do is to use an hexadecimal floating constant instead of an hexadecimal integer constant.

long double f = 0xA0000000000000000000000000000000p0L;
                                                  ^^ the exponent is 0

is OK.

The p introduces the exponent (required) and the L indicates it is a long double literal (default is double).

Hexadecimal floating constant is a C99 addition and note that in hexadecimal floating constants the exponent part is required.

Regarding bitwise operators (the second part of your question), the operands of bitwise operators must be of integer types so you cannot perform bitwise operations on floating-point values.

ouah
  • 142,963
  • 15
  • 272
  • 331