unsigned int类型的函数返回负数

时间:2011-10-01 04:10:17

标签: c++ c winapi unsigned-integer

哇我以为我知道我的C ++,但这很奇怪

这个函数返回一个unsigned int,所以我认为这意味着我永远不会得到一个负数返回吗?

该功能决定了你前面或后面几个小时。所以对我来说,我在澳大利亚,悉尼所以我是+10 GMT,这意味着我是UTC = LocalTime +( - 10)。因此,GetTimeZoneInformation正确地确定我是-10。

但是我的函数返回一个unsigned int所以不应该返回10而不是-10?

unsigned int getTimeZoneBias()
{
    TIME_ZONE_INFORMATION tzInfo;
    DWORD res  = GetTimeZoneInformation( &tzInfo );

    if ( res == TIME_ZONE_ID_INVALID )
    {
        return (INT_MAX/2); 
    }

    return (unsigned int(tzInfo.Bias / 60));  // convert from minutes to hours         
}

TCHAR ch[200];
_stprintf( ch, _T("A: %d\n"), getTimeZoneBias()); // this prints out A: -10
debugLog += _T("Bias: ") + tstring(ch) + _T("\r\n");

4 个答案:

答案 0 :(得分:10)

您正在尝试将unsigned int打印为signed int。将%d更改为%u

_stprintf( ch, _T("A: %u\n"), getTimeZoneBias());
                       ^

问题在于整数aren't positive or negative by themselves for most computers。这是他们被解释的方式。

因此,一个大整数可能与一个小的(绝对值)负整数无法区分。

答案 1 :(得分:4)

以下是我的想法:

tzInfo.Bias的值实际上是-10。 (0xFFFFFFF6) 在大多数系统上,将有符号整数转换为相同大小的无符号整数对表示没有任何作用。

因此该函数仍返回0xFFFFFFF6

但是当你打印出来时,你将它打印为有符号整数。所以它会打印-10。如果您将其打印为无符号整数,则可能会得到4294967286

你可能想要做的是获得时差的绝对值。所以你想把这个-10转换成10.你应该返回abs(tzInfo.Bias / 60)

答案 2 :(得分:2)

_T来电中有一个错误。它应该是:

_T("A: %u\n")

函数 返回非负整数。但是,通过使用错误的printf说明符,您将导致它作为整数从堆栈弹出。换句话说,这些位被解释为错误。我相信这也是未定义的行为。

答案 3 :(得分:1)

正如其他人所指出的,当你转换为unsigned int时,你实际上是在告诉编译器使用int中的位模式并将其用作unsigned int 。如果您的计算机与大多数人一样使用two's complement,那么您的号码将被解释为UINT_MAX-10,而不是10。当您使用%d格式说明符时,编译器将返回使用与int相同的位模式而不是unsigned int。这就是您仍然获得-10

的原因

如果你想要一个整数的绝对值,你应该尝试以数学方式得到它而不是使用强制转换。