Long type 64bit linux

a 夏天 提交于 2019-12-10 14:47:56

问题


Very simple questions guys, but maybe I'm just forgetting something. In 64bit linux, a long is 8bytes correct? If that's the case, and I want to set the 64th bit, I can do the following:

unsigned long num = 1<<63;

Whenever I compile this, however, it gives me an error saying that I'm left shifting by more than the width. Also, if I wanted to take the first 32bits of a long type (without sign extension), can I do:

num = num&0xFFFFFFFF;

or what about:

num = (int)(num);

Thank you.


回答1:


In 64bit linux, a long is 8bytes correct?

Need not be. Depends on the compiler than on the underlying OS. Check this for a nice discussion. What decides the sizeof an integer?

Whenever I compile this, however, it gives me an error saying that I'm left shifting by more than the width

Everyone have already answered this. Use 1UL

Also, if I wanted to take the first 32bits of a long type (without sign extension), can I do:

num = num&0xFFFFFFFF;
or what about:

num = (int)(num);

num = num&0xFFFFFFFF. This will give you the lower 32-bits. But note that if long is just 4 bytes on your system then you are getting the entire number. Coming to the sign extension part, if you've used a long and not unsigned long then you cannot do away with the sign extended bits. For example, -1 is represented as all ones, right from the 0th bit. How will you avoid these ones by masking?

num = (int)(num) will give you the lower 32-bits but compiler might through a Overflow Exception warning if num does not fit into an int




回答2:


Actually, if you want some precise length (in bits) for your integers, assuming a C99 conforming compiler, #include <stdint.h> and use types like int64_t, int32_t etc. A handy type is intptr_t, an integer type with the same number of bits as void* pointer (so you can call it a machine "word")




回答3:


For portability you could use:

limits.h

#define LNG_BIT   (sizeof(long) * CHAR_BIT)

unsigned long num = 1UL << (LNG_BIT - 1);

To get "low int", something like?:

#define INT_BIT   (sizeof(int) * CHAR_BIT)

if (LNG_BIT > INT_BIT)
    return num & (~0UL >> INT_BIT);
else
    return num;

or

    num &= ~(~0U << INT_BIT);

Or, use mask, etc. Depends in large on why, for what, etc. you want the int bits.

Also notice the options given by compilers; I.e. if you are using gcc:

  • i386 and x86-64 Options
  • Submodel-Options

-m32
-m64
-mx32
        Generate code for a 32-bit or 64-bit environment.
        * The -m32 option sets int, long, and pointer types to 32 bits, and generates code that runs on any i386 system.
        * The -m64 option sets int to 32 bits and long and pointer types to 64 bits, and generates code for the x86-64 architecture. For Darwin only the -m64 option also turns off the -fno-pic and -mdynamic-no-pic options.
        * The -mx32 option sets int, long, and pointer types to 32 bits, and generates code for the x86-64 architecture.

There is also -maddress-mode=long etc.

-maddress-mode=long
        Generate code for long address mode. This is only supported for 64-bit and x32 environments. It is the default address mode for 64-bit environments.




回答4:


I believe the problem with the first question is that the compiler is treating '1' as an integer, not as a long integer. It doesn't figure it out until after the assignment.

You can fix it by doing:

unsigned long num = (unsigned long)1<<63;



回答5:


AFAIR code like this was the source of a major bug in reiserfs a few years ago:

unsigned long num = 1<<63;

If you speak of x86_64, yes, a long is 64 bit and on most other 64 bit linux plytforms too. The problem is that both the 1 and the 63 in your code are simple int, and so the result is undefined. Better use

 unsigned long num = 1UL<<63;

or

 unsigned long num = (unsigned long)1<<63;


来源:https://stackoverflow.com/questions/10040123/long-type-64bit-linux

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!