6

我有一个声明为的函数:

void foo(unsigned int x)

如何检查 foo() 没有收到负数?我希望如果我调用 foo(-1) 会引发异常,但当然由于 x 会自动转换为无符号,我无法检查它的积极性,例如:

if not(x>=0){ do_something();};

或类似的检查。

4

5 回答 5

2

没有什么好的方法可以做到这一点,但你可以通过一些技巧来做到这一点:

1)声明一个未定义的更好匹配:

void foo(unsigned int x) {
  //do something
}

void foo(int x);

2) 使用 typeid 来确定类型。

于 2012-09-16T01:20:19.400 回答
2

您定义了该函数,因此它需要一个unsigned int参数,因此它不可能接收到负值。

如果您使用int参数调用它,该值将被隐式转换intunsigned int,并且该转换的结果是明确定义的。这是该语言的一个特性,除非您的编译器碰巧给您提供了这样做的方法,否则您无法将其关闭——而且我不知道有哪个编译器可以关闭它。

就您的功能而言,这两个调用:

foo(-1);       /* -1 is converted to unsigned int, to the value UINT_MAX */
foo(UINT_MAX);

无法区分。这不是唯一的情况。任何负值int都将转换为有效值unsigned

如果认为非常大的值对 无效foo(),那么您可以检查参数值是否在某个“合理”范围内——但定义什么是“合理”并不总是那么容易。

于 2012-09-16T01:20:50.607 回答
1

foo正如 wich 的回答所暗示的,您可以添加一个带int参数的重载版本。既然你说你想foo(-1)抛出一个异常,你可以让重载的foo()人这样做:

#include <iostream>

class Wrong_Type {
public:
    Wrong_Type(){}
};

void foo(unsigned n) {
    std::cout << "In foo, unsigned n = " << n << "\n";
}

void foo(int n) {
    std::cout << "In foo, int n = " << n << "\n";
    throw Wrong_Type();
}

int main() {
    try {
        foo(-1);
    }
    catch (Wrong_Type) {
        std::cout << "Caught Wrong_Type exception\n";
    }
}

当我运行它时,输出是:

In foo, int n = -1
Caught Wrong_Type exception

但这不是一个理想的解决方案,因为它基于参数的类型而不是它的值引发异常。1和都是-1type int,所以调用foo(1)也会抛出异常。一些其他有效的调用,例如foo(1.0),变得模棱两可。

如果您可以替换foo(1)foo(1U),其中1U是类型的常量unsigned int,那么这可以工作。

于 2012-09-16T02:36:44.267 回答
0

我不是 C++ 专家,但是...

您只有固定数量的位(通常是 32 或 64)来表示一个整数。如果你知道你永远不会有一个小于零的整数,你可以使用所有这些位并存储一个更大的数字。如果您的数字可能小于零,则编译器必须为符号保留一点。

它比这更复杂一些 - 请参阅Wikipedia 上关于 2 的补码的文章

长话短说,在 foo 内部,如果您看到 x“非常非常大”,您可能已经传递了一个负数。

检查您的编译器文档以了解 int 与 uint 的大小。

您可能希望将您的参数更改为常规整数void foo(int x),或者只是放松地知道您当前的设置 x 永远不会小于零。

于 2012-09-16T01:20:57.283 回答
0

这是一个可能的解决方案:

void foo(unsigned int x)
{
  unsigned int last_bit_one = 1 << 31; 
  if ( (x & last_bit_one) != 0)           // check if the last bit of x is 1 
    std::cout << "NEGATIVE NUMBER" << std::endl;
  else
    std::cout << "do something" << std::endl;
}

当然,我们需要假设您输入的无符号数小于 2147483648。

于 2021-02-09T18:40:19.017 回答