【问题标题】:How to Determine if an Int is 16 Bits如何确定 Int 是否为 16 位
【发布时间】:2019-06-24 07:48:18
【问题描述】:

我正在使用 C 语言中的按位和逻辑运算符。我熟悉这些运算符的概念和用途,但遇到了一些问题。

我需要确定一个整数x 是否适合短。我仅限于使用运算符! ~ & ^ | + << >>。此外,我最多只能使用这些运算符中的 8 个。

我从其他几篇文章(比如这篇文章:How to tell if a 32 bit int can fit in a 16 bit short)中知道,像这样的解决方案

!(((((x) & 0xffff8000) >> 15) + 1) & 0x1fffe)

会很好用(感谢 Emil Romanus)。但是,我也被禁止使用不是0x00xff 的任何常量。

我对这里的逻辑很困惑。有什么想法吗?

编辑:我忘了提条件语句也是被禁止的。所以没有 ifs、elses、循环等。

【问题讨论】:

  • !0x0 == 1 ... !0x0 + !0x0 == 2 ... 只是说:)
  • @pmg ahhhh 我赶上你的漂移
  • 首先,您知道您的架构/编译器的intshort 的大小吗?假设sizeof(int) == sizeof(int32_t)sizeof(short) == sizeof(int16_t) 是一个很大的假设。

标签: c architecture binary bit-manipulation


【解决方案1】:

这是你的解决方案

 (unsigned)~0 == 0xffff

或者没有==

 !((unsigned)~0 - 0xffff)

 !((unsigned)~0 ^ 0xffff)

或者如果只允许 0xff

!((unsigned)~0 ^ (((0xff << (!!0xff << !!0xff << !!0xff << !!0xff))) | 0xff)))

【讨论】:

  • 我有点明白你在做什么,但为什么要在每个 0xff 旁边添加两个 ! 运算符?那不就是否定否定吗?另外,我应该最多只使用 8 个运算符。
  • 我需要号码1!! 将任何非零转换为 1
  • 然后是第三个解决方案。没有别的办法
  • @P__J__ 拿着我的啤酒 ;-)
【解决方案2】:

对于可读性设置invuint = ~0uinvushort = ~((short)0u),我们可以做到invuint - invushort 要么是0,要么不是。标准 C 中的 0 等于 false,因此您可以使用简单的 !(invuint - invushort) 查看 unsigned int 是否适合 unsigned short

但这很可能不是你被要求做的,这有点太容易了。如果您需要知道unsigned int 的内容是否适合unsigned short,那就有点复杂了。

我们可以在这里重用incushort = ~((short)0u) 作为掩码。

对于an_uint = 0; an_uint = incushort,我们将an_uint 的最低位设置为1,因此我们有0x0000ffff。用~an_uint 反转它会得到0xXXXX0000,其中X 代表未知数量的。所以如果sizeof(unsigned int) == sizeof(unsigned short) 我们得到0 但我们可以变得更简单,见上文。

如果我们使用mask = 0xXXXX0000 作为掩码来获取所有大于unsigned shortuint_with_unknown_content &amp; mask 的位,如果uint_with_unknown_content 适合unsigned short,我们将得到0

【讨论】:

    【解决方案3】:

    解决方案基于这样一个事实:如果x 的 17 个 MSB 都相等且 x 可以在 16 位上编码,x^(x&lt;&lt;1) 的 16 个 MSB 将为零。

    因此

    return (x^(x<<1))&(0xffff0000)==0;
    

    解决问题。

    为了可读性,操作被分成几条指令和 为了减少使用的运算符的数量,最终的测试被反转了(似乎没有被禁止)。

    int canNOTbemappedto16bits(int x) {
       int one = !0x0;  // 1 op
       int ffff = (unsigned short) ~0x0;//1 op
       int ffff0000 = (unsigned int) ~0x0 ^ ffff; // 2ops
       return   (x^(x<<one))&ffff0000 ; // 3ops
    }
    

    7 个操作!

    【讨论】:

    • 我喜欢你的逻辑,而且你的回答非常简洁明了,但是如果不使用 - 运算符,我该怎么做呢?另外,我只能使用 8 个运算符。
    • 我错过了“-”被禁止的事实。但唯一需要的操作是“-1”,可以用+(~0)代替。关于操作员的数量,它适合,但不适用于 oneliner。我更新了答案。
    • @vastImmortalSuns 以前的答案有一个错误,但我找到了一种更简单的方法,可以完全遵守约束。
    • 啊,我明白了!感谢您澄清这一点,我没有意识到您甚至可以否定 0,但现在这完全有道理:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-08-14
    • 2017-09-14
    • 1970-01-01
    • 2015-03-29
    • 1970-01-01
    • 1970-01-01
    • 2013-06-25
    相关资源
    最近更新 更多