简体   繁体   English

与 uint64_t 斗争

[英]Struggling with uint64_t

I want to set individual bits in a 64 bit number and figured that the uint64_t is ideal for the job.我想在 64 位数字中设置各个位,并认为uint64_t是这项工作的理想选择。 I ran into some strange problems, so I did some experiments:我遇到了一些奇怪的问题,所以我做了一些实验:

I wrote the following test program:我写了下面的测试程序:

#include <iostream>
#include <cstdint>
#include <iomanip>

int main()
{

    uint64_t test_value = 0;

    for( int i=0; i<63; ++i ) {
        test_value = (1 << i);
        std::cout << hex << test_value << "\n";
    }

    return 0;
}

The output surprised me:输出让我感到惊讶:

1
2
4
8
10
... (irrelevant output elided)
10000000
20000000
40000000
ffffffff80000000
1
2
4
8
10
...
10000000
20000000
40000000

I tested the max value ( std::cout << hex << std::numeric_limits<uint64_t>::max() << std::endl ) resulting in ffffffffffffffff as expected.我测试了最大值( std::cout << hex << std::numeric_limits<uint64_t>::max() << std::endl ),结果如预期的那样ffffffffffffffff

I am running gcc 12.2.1 on Fedora 37.我在 Fedora 37 上运行 gcc 12.2.1。

It looks like my unsigned int changed to signed on bit 31 and rolled over on bit 32. Am I missing a compiler setting?看起来我的 unsigned int 更改为在第 31 位上签名并在第 32 位上滚动。我是否缺少编译器设置? Any help is greatly appreciated.任何帮助是极大的赞赏。

Your compiler should have warned you.你的编译器应该警告过你。
In this line:在这一行中:

test_value = (1 << i);

1 is an int literal (and int is usully 32 bit). 1是一个int文字( int通常是 32 位)。

Eg in MSVC I get:例如在 MSVC 中我得到:

warning C4334: '<<': result of 32-bit shift implicitly converted to 64 bits (was 64-bit shift intended?)警告 C4334:“<<”:32 位移位的结果隐式转换为 64 位(是否打算进行 64 位移位?)

You should change it to:您应该将其更改为:

//-------------vvv-------
test_value = (1ull << i);    // You can also use: (uint64_t)1 instead of 1ull

And now you'll get the output you expect.现在您将获得预期的输出。

Am I missing a compiler setting?我是否缺少编译器设置?

I think what you are missing is that 1 is an int , and sizeof(int) can be less than sizeof(uint64_t) .我认为您缺少的是1是一个int ,并且sizeof(int)可以小于sizeof(uint64_t) Shifting a 32-bit value left by more than 31 bits yields results that aren't particularly useful.将 32 位值左移超过 31 位会产生不是特别有用的结果。

If you replace 1 with 1ULL , or alternatively with ((uint64_t)1) , you will get behavior that is more in line with your expectations.如果将1替换为1ULL或替换为((uint64_t)1) ,您将获得更符合您期望的行为。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM