【问题标题】:Clarification needed on (u/i)int_fastN_t(u/i)int_fastN_t 需要澄清
【发布时间】:2014-05-30 15:30:26
【问题描述】:

我阅读了很多关于最快最小宽度整数类型的解释,但我不明白何时使用这些数据类型。

我的理解: 在 32 位机器上,

uint_least16_t 可以 typedef 为一个无符号的 short。

 1. uint_least16_t small = 38;
 2. unsigned short will be of 16 bits so the value 38 will be stored using 16 bits. And this will take up 16 bits of memory.
 3. The range for this data type will be 0 to (2^N)-1 , here N=16.

uint_fast16_t 可以是无符号整数的 typedef。

 1. uint_fast16_t  fast = 38; 
 2. unsigned int will be of 32 bits so the value 38 will be stored using 32 bits. And this will take up 32 bits of memory.
 3. what will be the range for this data type ?
    uint_fast16_t => uint_fastN_t , here N = 16
    but the value can be stored in 32 bits so IS it 0 to (2^16)-1 OR 0 to (2^32)-1 ?
    how can we make sure that its not overflowing ? 
    Since its a 32 bit, Can we assign >65535 to it ?

    If it is a signed integer, how signedness is maintained.
    For example int_fast16_t = 32768;
    since the value falls within the signed int range, it'll be a positive value.

【问题讨论】:

    标签: c memory c99 unsigned signed


    【解决方案1】:

    uint_fast16_t 是最快的无符号数据类型,至少有 16 位。在某些机器上它将是 16 位,而在其他机器上可能更多。如果你使用它,你应该小心,因为给出高于 0xFFFF 的算术运算在不同的机器上可能会有不同的结果。

    在某些机器上,是的,您可以在其中存储大于 0xFFFF 的数字,但您不应该在设计中依赖这一点,因为在其他机器上这是不可能的。

    通常uint_fast16_t 类型将是uint16_tuint32_tuint64_t 的别名,您应确保代码的行为不依赖于所使用的类型。

    我想说,如果您需要编写既快速又跨平台的代码,您应该只使用uint_fast16_t。大多数人应该坚持使用uint16_tuint32_tuint64_t,以便在将代码移植到另一个平台时减少需要担心的潜在问题。

    一个例子

    以下是您可能遇到麻烦的示例:

    bool bad_foo(uint_fast16_t a, uint_fast16_t b)
    {
        uint_fast16_t sum = a + b;
        return sum > 0x8000;
    }
    

    如果您使用a 作为0x8000 和b 作为0x8000 调用上面的函数,那么在某些机器上sum 将为0,而在其他机器上它将为0x10000,因此该函数可能返回真或假。现在,如果你能证明ab 的总和永远不会大于0xFFFF,或者如果你能证明bad_foo 的结果在这些情况下被忽略,那么这段代码就可以了。

    相同代码的更安全的实现(我认为)在所有机器上的行为方式应该是相同的:

    bool good_foo(uint_fast16_t a, uint_fast16_t b)
    {
        uint_fast16_t sum = a + b;
        return (sum & 0xFFFF) > 0x8000;
    }
    

    【讨论】:

    • +1 不错的答案,但我建议return (sum > 0x8000) || (sum < a); 便携式测试sum > 0x8000(sum & 0xFFFF) > 0x8000;a=0xFFFF, b=1 失败。
    • @David 但是这个网站上有人提到固定宽度整数类型在 C 中是可选的。
    • @David 是不是因为使用机器字长类型会更有效。是不是就像在说“让表达式以更快的速度计算,我们会处理结果”?
    • @Harsha,如果您的编译器支持 C99,那么我认为您可以包含 stdint.h 并访问固定宽度类型,如 uint16_t。你为什么说它们是可选的?您对此有疑问吗?我的回答有什么不对吗?
    • @Harsa,对于您的第二条评论,我会说答案是肯定的。在 32 位处理器上,将 16 位整数存储在 32 位寄存器中并让程序员(而不是编译器)担心何时需要屏蔽高位可能会更快。这就是uint_fast16_t 允许我们做的事情。
    猜你喜欢
    • 2011-11-09
    • 2012-07-18
    • 1970-01-01
    • 2023-03-09
    • 1970-01-01
    • 2012-06-02
    • 2017-01-18
    • 2016-06-30
    • 1970-01-01
    相关资源
    最近更新 更多