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
。
对于下面的代码
#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
。