1

对于以下代码

#include <bits/stdc++.h>
using namespace std;
int main()
{
   bitset<64>b(numeric_limits<long>::min());
   string s=b.to_string();
   char *ptr=new char [s.size()+1];
   strcpy(ptr,s.c_str());
   long l1=strtol(ptr,NULL,2);
   cout<<"l1= "<<l1<<endl;
  long l2=strtoul(ptr,NULL,2);
   cout<<"l2= "<<l2<<endl;
   cout<<strtoul(ptr,NULL,2)<<endl;
}

输出是

l1= 9223372036854775807
l2= -9223372036854775808
9223372036854775808

为什么l1不是long_min,为什么是l2?我读过该字符串可以在 ato*,strto* 函数的开头包含+/-符号。-但是二进制中的负数在计算机使用的 2 的补码中没有任何符号。我很困惑。

4

2 回答 2

1

ERANGE提供大于 along可以容纳的正值时会出现错误。要使其与您一起使用,strtol您需要添加一个-

#include <bitset>
#include <cstring>
#include <iostream>
#include <limits>
#include <string>

int main()
{
   std::bitset<64> b(std::numeric_limits<long>::min());

   std::string s = "-" + b.to_string();

   long l1=strtol(s.c_str(), NULL, 2);
   std::cout << "l1= " << l1 << '\n';
}

可能的输出:

l1= -9223372036854775808
于 2020-04-14T10:16:30.850 回答
1

unsigned long int价值_

9223372036854775808

此语句输出

cout<<strtoul(ptr,NULL,2)<<endl;

不能在类型的对象中表示signed long int

在这份声明中

long l1=strtol(ptr,NULL,2);

因为该值在signed long int函数strtol返回的类型中不可表示LONG_MAX(因为字符串中没有减号)。而这个值就是这个语句输出的

cout<<"l1= "<<l1<<endl;

来自 C 标准(7.22.1.4 strtol、strtoll、strtoul 和 strtoull 函数)

8 strtol、strtoll、strtoul 和 strtoull 函数返回转换后的值(如果有)。如果无法执行转换,则返回零。如果正确值超出可表示值的范围,则返回 LONG_MIN、LONG_MAX、LLONG_MIN、LLONG_MAX、ULONG_MAX 或 ULLONG_MAX(根据值的返回类型和符号,如果有),宏 ERANGE 的值为存储在 errno 中。

但是,该值可表示为unsigned long int. 所以这个函数的调用strtoul返回了正确的值

long l2=strtoul(ptr,NULL,2);

但是该值被分配给类型的对象signed long int。所以它的最高位被解释为符号位和下一条语句

cout<<"l2= "<<l2<<endl;

输出值LONG_MIN

于 2020-04-14T10:18:59.433 回答