unsigned int类型的函数返回负数

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

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

该函数确定您前面或后面的UTC小时数。 所以对我来说,我在澳大利亚,悉尼所以我是+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"); 

这就是我认为正在发生的事情:

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

所以函数仍然返回0xFFFFFFF6

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

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

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

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

问题是对于大多数计算机来说,整数本身并不是正面的或负面的 。 这是他们被解释的方式。

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

您的_T通话中有一个错误。 它应该是:

 _T("A: %u\n") 

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

正如其他人所指出的,当你转换为unsigned int ,实际上是在告诉编译器使用int的位模式并将其用作unsigned int 。 如果您的计算机使用二进制补码 ,那么您的数字将被解释为UINT_MAX-10而不是您预期的10 。 当您使用%d格式说明符时,编译器将返回使用与int相同的位模式而不是unsigned int 。 这就是为什么你仍然得到-10

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