类型为unsigned int的函数返回负数 哇,我以为我知道我的C++,但这是奇怪的< /P>
这个函数返回一个无符号整数,所以我想这意味着我永远不会得到一个负数,对吗 该函数确定您在UTC之前或之后的小时数。对我来说,我在澳大利亚悉尼,所以我是+10GMT,这意味着我是UTC=LocalTime+(-10)。因此GetTimeZoneInformation正确地确定了我是-10 但是我的函数返回一个无符号int,所以它不应该返回10而不是-10吗?类型为unsigned int的函数返回负数 哇,我以为我知道我的C++,但这是奇怪的< /P>,c++,c,winapi,unsigned-integer,C++,C,Winapi,Unsigned Integer,这个函数返回一个无符号整数,所以我想这意味着我永远不会得到一个负数,对吗 该函数确定您在UTC之前或之后的小时数。对我来说,我在澳大利亚悉尼,所以我是+10GMT,这意味着我是UTC=LocalTime+(-10)。因此GetTimeZoneInformation正确地确定了我是-10 但是我的函数返回一个无符号int,所以它不应该返回10而不是-10吗? unsigned int getTimeZoneBias() { TIME_ZONE_INFORMATION tzInfo;
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");
您正试图将
无符号整数
打印为有符号整数
。将%d
更改为%u
_stprintf( ch, _T("A: %u\n"), getTimeZoneBias());
^
问题是整数。这是他们被解读的方式
因此,大整数可能无法与小(绝对值)负整数区分。一个错误出现在您的
\u T
调用中。应该是:
_T("A: %u\n")
该函数返回一个非负整数。但是,通过使用错误的printf说明符,会导致它作为整数从堆栈中弹出。换句话说,位被解释为错误的。我相信这也是未定义的行为。以下是我认为正在发生的事情:
tzInfo.Bias
的值实际上是-10。(0xFFFFF6
)
在大多数系统上,将有符号整数强制转换为相同大小的无符号整数对表示没有任何影响
因此该函数仍然返回0xFFFFFFF6
但是当你把它打印出来的时候,你把它作为一个带符号的整数打印回来。所以它会打印-10
。如果将其打印为无符号整数,可能会得到4294967286
你可能想做的是得到时间差的绝对值。所以你想把这个-10转换成10。在其中,您应该返回abs(tzInfo.Bias/60)正如其他人所指出的,当您对
无符号int
进行强制转换时,实际上是在告诉编译器使用int
中的位模式,并将其用作无符号int
。如果您的计算机像大多数人一样使用,那么您的号码将被解释为UINT\u MAX-10
,而不是您预期的10
。使用%d
格式说明符时,编译器会返回使用与int
相同的位模式,而不是无符号int
。这就是为什么您仍然得到-10
如果你想要一个整数的绝对值,你应该试着用数学方法来获得它,而不是使用强制转换。是的,但是函数getTimeZoneBias()不会总是返回一个正数,所以我不必担心格式问题,因为它总是一个正数???@Matthew Flaschen这不是未定义的行为,它是实现定义的。它是一个正数,你只是把它误解为一个负数。您正在命令编译器错误地解释它,告诉它,当它是一个无符号数时,它是一个有符号数。@user593747:否。
%u
格式需要一个类型为无符号int
的参数<代码>%d“需要类型为int
的参数。一个无符号int
对象总是非负的(不一定是正的;它可以是0),但是如果你假装它是一个int
,它很容易看起来是负的。例如,如果int
是32位,那么无符号int
值4294967295
与int
值-1
@cnicutar具有相同的表示形式:您的断言有参考文献吗?谢谢,我得到了令我困惑的4294967286。当我编写简单函数时,我真的需要重新思考!在编写代码时做出这些假设(依赖计算机作为2的补充)是否不安全?我不知道你的意思。大多数常用的语言使用2的补码,但在编写代码时,它几乎不重要。它主要确定边缘情况以及位操作如何影响数字。如果你不确定并且你需要知道,你应该经常检查。类似于“你的C代码应该永远是硬件不可知的”。或者这句格言是“编译器不可知论”。我将在编译器中重温2的补码替代方案和分支。谢谢部分问题是,打印无符号需要%u
,在这种情况下,它是的副本,但在来回转换int&unsigned时还有很多问题。例如nxxx,其中x是位0或1,n是-或+。如果表示有符号与无符号的数字,则可以用10000表示负零,00000表示正零和10000!=0进行加法时,01111+00001=10000。你会感到奇怪。一个人的赞美是这样的,但数字是相反的。5是0101,负5是1010。你仍然会遇到奇怪的0对0的问题,在某些情况下,它充当了一个反义器或-1或+1。两个人的赞美就是一个人的赞美,但是+1。所以5是0101,负5是1010+1=1011。这就神奇地解决了奇怪的0和-0问题如果你想从我的其他评论中了解更多,请参阅youtube上的二进制:加减(为什么我们使用两个的补码)-ComputerPhille by ComputerPhille。