【问题标题】:Unsigned long returning negative in C++无符号长在 C++ 中返回负数
【发布时间】:2013-03-11 21:33:17
【问题描述】:

当任何 numA-D 中的任何一个被多次相乘时,该数字突然变为负数。例如,当 numA 乘以 3 乘以 256 时,该数字变为负数,但如果仅乘以 256 两次则不会。本项目的目的是将一个 ip 地址改为 unsigned long,然后将 unsigned long 改为一个 ip 地址。

using namespace std;
unsigned long ip2long (string ipv4)
{

// variable to return
unsigned long rtn;
string A,B,C,D;
string delimiter = ".";
size_t position;


/* must parse string by '.' character
and then assign (A,B,C,D) to the values
and return the unsigned long last, you don't have to make
the variables unsigned longs */


int locOfA = ipv4.find('.' );
int locOfB = ipv4.find('.', locOfA + 1);
int locOfC = ipv4.find('.', locOfB + 1);
int locOfD = ipv4.find('.', locOfC + 1);


A =  ipv4.substr(0,locOfA);
B = ipv4.substr(locOfA + 1, locOfB - locOfA - 1);
C = ipv4.substr(locOfB + 1, locOfC - locOfB -1 );
D = ipv4.substr(locOfC + 1, locOfD - locOfC -1);

int numA = atoi(A.c_str());
int numB = atoi(B.c_str());
int numC = atoi(C.c_str());
int numD = atoi(D.c_str());
cout << endl;
cout << numA << endl;
cout << numB << endl;
cout << numC << endl;
cout << numD << endl;


cout << endl;
// assigning a unsigned long to the sum of the algorithm
cout << (numA * 256 * 256) +  << endl;
cout << (256 * 256 * 256 * numB) << endl;
cout << (256 * numC) << endl;
cout << (256 * numD) << endl;

rtn = numD + (256 * numC) + (256 * 256 * numB) + (256 * 256 * 256 * numA);


return rtn;
}

【问题讨论】:

  • 因此,不要将您的 numA、numB、numC 和 numD 变量声明为 signed 整数。除非您明确使用 unsigned 关键字,否则变量是有符号的。
  • 请记住signed integer overflow 是未定义的行为。

标签: c++ negative-number unsigned-long-long-int


【解决方案1】:

unsigned long 是无符号的——它不能是负数。但是你所有的数字,因此你所有的计算,都是ints,而不是unsigned longs。 ints 允许为负数。

换句话说,这条线

rtn = numD + (256 * numC) + (256 * 256 * numB) + (256 * 256 * 256 * numA);

是一样的

rtn = static_cast<unsigned long>(numD + (256 * numC) + (256 * 256 * numB) + (256 * 256 * 256 * numA));

所有变量和常量都是int,不会自动提升为unsigned long。

【讨论】:

  • 谢谢,这正是我想要的!
【解决方案2】:

int 是 32 位的。这意味着它的最大值是 2^31 = 256*256*256*128 - 1。(它的下限值是 -2^31)
如果 numA >=128,它将变为负数。
或者如果 numD + (256 * numC) + (256 * 256 * numB) + (256 * 256 * 256 * numA) > 2^31 = 2147483648
你会看到负数。

【讨论】:

  • 不,int 并不总是 32 位。也不是所有机器 2 的补码机器。
【解决方案3】:

所有整数类型都有符号

  • LONG - Whitout 无符号总是有符号的 –2,147,483,648 到 2,147,483,647
  • INT - Whitout 无符号总是有符号的 –2,147,483,648 到 2,147,483,647
  • SHORT - Whitout 无符号总是有符号的 –32,768 到 32,767
  • FLOAT - Whitout 无符号总是有符号 3.4E +/- 38(7 位)
  • DOUBLE - Whitout 无符号总是有符号 1.7E +/- 308(15 位)

无符号可存储的最大数是有符号的两倍。

示例:

long val = 2147483647; // Signed max value

unsigned long val = 4294967294;  // 2x bigger number can be stored

如果尝试将 4294967294 存储在签名中怎么办?

signed long val = 4294967294;  // result will be -2

就像我说的 usigned 中的值可以返回 2 倍更大的数字。这些错误发生在超过的情况下

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-11-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-17
    • 1970-01-01
    • 2013-09-21
    • 1970-01-01
    相关资源
    最近更新 更多