stroll,strol 函数没有为 long_min 提供正确的输出

stroll, strol functions not giving correct output for long_min

对于下面的代码

#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 的补码中没有任何 - 符号。我很困惑。

如果您提供的正值大于 long 所能容纳的正值,您会收到 ERANGE 错误。要使其与 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

unsigned long int

9223372036854775808

由这条语句输出

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

无法在 signed long int.

类型的对象中表示

在此声明中

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

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

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

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

8 The strtol, strtoll, strtoul, and strtoull functions return the converted value, if any. If no conversion could be performed, zero is returned. If the correct value is outside the range of representable values, LONG_MIN, LONG_MAX, LLONG_MIN, LLONG_MAX, ULONG_MAX, or ULLONG_MAX is returned (according to the return type and sign of the value, if any), and the value of the macro ERANGE is stored in errno.

但是该值可以表示为 unsigned long int。所以这个函数的调用 strtoul returns 正确值

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

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

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

输出值LONG_MIN