简体   繁体   中英

stroll, strol functions not giving correct output for long_min

For the following code

#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;
}

The output is

l1= 9223372036854775807
l2= -9223372036854775808
9223372036854775808

Why is l1 not long_min and why is l2 ? I've read that the string can contain + / - sign in the beginning for ato*,strto* functions. But negative numbers in binary don't have any - sign in 2's complement that computer uses. I'm confused.

You get an ERANGE error for supplying a positive value larger than what a long can hold. To make it work with strtol you need to add a - :

#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';
}

Possible output:

l1= -9223372036854775808

The unsigned long int value

9223372036854775808

outputted by this statement

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

can not be represented in an object of the type signed long int .

In this statement

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

as the value is not representable in the type signed long int the function strtol returns LONG_MAX (because there is no minus sign in the string). And this value is outputted by this statement

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

From the C Standard (7.22.1.4 The strtol, strtoll, strtoul, and strtoull functions)

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.

However the value is representable as an unsigned long int . So this call of the function strtoul returns the correct value

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

but the value is assigned to an object of the type signed long int . So its most significant bit is interpreted as the sign bit and the next statement

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

outputs the value LONG_MIN .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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