在c++中计算64位整数的位数时,大输入(64位)会产生意想不到的结果

Big inputs(64 bits) giving unexpected results while Counting number of bits in a 64-bit integer in c++

本文关键字:64位 输入 结果 意想不到 计算 c++ 整数      更新时间:2023-10-16

我试图计数64位整数的位数,但它显示了一些意想不到的。下面是代码。计数位不是主要部分,但一些意想不到的输出是....请看看输入和输出!!!!

#include<iostream>
#include<math.h>
#include<stdint.h>
#include<cstdio>
using namespace std;
int64_t t,n,ans;
int main(){
    cin>>t;
    while(t--){
         int64_t ans=0;
         cin>>n;
         /*
         while(n>0LL){
             n>>=1LL;
             ans++;
         }//*/
        ans=floor(log2(n));
        //ans=floor(log2l(n));
        cout<<ans<<"n";
    }
    return 0;
}

输入和输出是这个

10
18446744073709551615

63(18446744073709551615中的位数)应该只打印一次,控制台应该等待,直到我输入另一个数字并计数其他数字中的位数。但这并没有发生。输出如下所示....

63
63
63
63
63
63
63
63
63
63

除了上述解释如何正确计数位之外,这就是为什么它一直持续到t耗尽而不要求更多输入的原因:

问题在于您的值的大小:18446744073709551615

大于signed long long。因此,一旦您将它输入到cin中,流就不再是good(): failbit设置:

failbit - Logical error on i/o operation

从这里http://www.cplusplus.com/reference/istream/istream/operator%3E%3E/:

提取和解析字符…把它们理解为……正确的类型………然后(if good),……相应地调整流的内部状态标志。

那么,在你的例子中

    读取第一个值18446744073709551615, failbit设置。
  1. 您处理n中的任何内容(应该是numeric_limits::max()),忽略任何输入错误
  2. 你尝试读取下一个值
  3. 由于设置了failbit, cin>>n不做任何事情,使旧的n保持原样
  4. 此过程重复直到t耗尽

在x86-64上有POPCNT指令。https://en.wikipedia.org/wiki/SSE4 POPCNT_and_LZCNT

https://msdn.microsoft.com/en-us/library/bb385231.aspx

unsigned __int64 __popcnt64(
   unsigned __int64 value
);
GCC

__builtin_popcountll ((long long) x);