【问题标题】:How to extract four unsigned short ints from one long long int?如何从一个 long long int 中提取四个 unsigned short int?
【发布时间】:2010-09-13 23:25:55
【问题描述】:

假设我有一个 long long int 并且想要取出它的位并从中构造四个 unsigned short int。

在这里,特定的顺序并不重要。

我通常知道我需要移位并截断到 unsigned short int 的大小。但我想我可能会在某个地方犯一些奇怪的错误,所以我问。

【问题讨论】:

    标签: c++ c 64-bit bit-manipulation


    【解决方案1】:
    #include <stdint.h>
    #include <stdio.h>
    
    union ui64 {
        uint64_t one;
        uint16_t four[4];
    };
    
    int
    main()
    {
        union ui64 number = {0x123456789abcdef0};
        printf("%x %x %x %x\n", number.four[0], number.four[1],
                                number.four[2], number.four[3]);
        return 0;
    }
    

    【讨论】:

    • 这会受到little/big-endian的影响吗?
    • 是的,大端系统与小端系统的结果不同。
    • 这绝对是一个快速而简单的解决方案,与以下顺序相同:“@numbers = unpack 'S4', pack 'Q', $number;”在 Perl 中
    • 会严重失败,例如一个 Cray 和一个 TI DSP,仅举几例 CPU,其中 short 是/可以是 32 位。
    • 我 100% 同意这个解决方案根本不便携。也许我应该修改答案以使用 inttypes.h。 :-)
    【解决方案2】:
    union LongLongIntToThreeUnsignedShorts {
       long long int long_long_int;
       unsigned short int short_ints[sizeof(long long int) / sizeof(short int)];
    };
    

    这应该可以满足您的想法,而不必乱动位移。

    【讨论】:

    • 你能保证结构在短整数之间没有填充吗?
    • 糟糕——我最初写了三个无符号整数。这可能会误导你。对此感到抱歉。无论如何,您的回答很有帮助。
    • 它最初是 unsigned short int (可能每个 2 个字节 - 没关系)。我的观点是,除非您确定填充/对齐规则,否则该结构很危险。
    【解决方案3】:
    (unsigned short)((((unsigned long long int)value)>>(x))&(0xFFFF))
    

    其中value 是您的long long intx 是四条短裤的 0、16、32 或 48。

    【讨论】:

    • 位移位的问题在于,在 C/C++ 中,负数的行为是未定义的。
    • 对于负“值”,它不是未定义的,而是实现定义的。对于负数“x”,它是未定义的,但在这里永远不会发生。并且负整数的存储格式也是由实现定义的(在某些可能性内),所以在这个分数上这并不比使用联合差。
    • 我不在乎移位符号是否扩展了值,我将屏蔽除底部 16 位之外的所有位。这些是明确定义的。
    • 我认为 Alexander 指出负符号数量右移的结果不必是 0 填充或符号填充。它可以是任何东西,只要编译器文件是什么。至少在 C++ 中。我也没有检查过C标准。不过,在“几乎所有”编译器上你是对的。
    • 你明白了:标准中的正确措辞是“实现定义的”。我认为此答案中解决方案的最简单解决方法是首先将值转换为无符号类型。然后该解决方案优于结构,因为它在大端和小端架构上产生相同的结果。
    猜你喜欢
    • 2016-07-29
    • 1970-01-01
    • 1970-01-01
    • 2012-01-27
    • 2016-12-20
    • 1970-01-01
    • 1970-01-01
    • 2019-12-12
    • 1970-01-01
    相关资源
    最近更新 更多