相关疑难解决方法(0)

120
推荐指数
7
解决办法
22万
查看次数

是否定义了有符号整数的按位运算结果?

我知道有>>符号整数的行为可以依赖于实现(具体来说,当左操作数为负时).

怎么样的人:~,>>,&,^,|?当他们的操作数有符号内建类型(整数short,int,long,long long),都将结果保证是相同的(中位含量),好像他们的类型是无符号的?

c c++ bitwise-operators

47
推荐指数
2
解决办法
2万
查看次数

算术按位右移"a shr b",带有存储在变量中的有符号整数 - 结果错误!内部Delphi的错误?

我有一个关于Delphi中位移行为的问题(或者更可能是错误报告)(在Borland Delphi 7中测试过).

目标:使用任意数字向右执行"算术"按位移位.

这意味着必须扩展符号位 - 如果设置了一个数字的最高有效位,则将从左侧填充二进制数,而不是0.

因此,算术右移后的数字"-1"必须保持相同的数字(所有位= 1),但是"逻辑移位"(总是用零填充数字)必须给出最大正整数(最大正有符号整数) ,为了正确)

我只在32位系统上测试过它(Windows); 而且,我需要它以32位整数显式工作.

当源编号存储在变量中时,看起来Delphi中存在带有"shr"的内部错误.

我的示例代码:

program bug;

{$APPTYPE CONSOLE}

var
I:Integer;
C:Cardinal;

begin
I := -1;  // we’ll need that later
C := $FFFFFFFF;
Run Code Online (Sandbox Code Playgroud)

(这只是开始).接下来,让我们尝试一些"shr":

Writeln('0) ', -1 shr 1 );
Writeln('1) ', $FFFFFFFF shr 1 );
Run Code Online (Sandbox Code Playgroud)

"-1"是等效于"$ FFFFFFFF"的签名.似乎"shr"行为(算术或逻辑)基于源号是签名还是不签名(整数或基数)的事实.

输出是:

0) -1
1) 2147483647
Run Code Online (Sandbox Code Playgroud)

非常正确.然后我需要尝试手动将这些数字转换为整数或基数:

Writeln('2) ', Integer(-1) shr 1 );
Writeln('3) ', Integer($FFFFFFFF) shr 1 );
Writeln('4) ', Cardinal(-1) shr 1 );
Writeln('5) ', Cardinal($FFFFFFFF) shr 1 ); …
Run Code Online (Sandbox Code Playgroud)

delphi integer bit-shift delphi-7 unsigned-integer

26
推荐指数
1
解决办法
1886
查看次数

为什么(int)((unsigned int)((int)v)?

我在其中找到此代码的网站

int v, sign;
// or, to avoid branching on CPUs with flag registers (IA32):
sign = -(int)((unsigned int)((int)v) >> (sizeof(int) * CHAR_BIT - 1));  // if v < 0 then -1, else 0. 
Run Code Online (Sandbox Code Playgroud)

此语句为变量符号指定变量v的符号(-1或0).我想知道为什么(int)((unsigned int)((int)v)用而不是普通的v?

c casting bitwise-operators

26
推荐指数
3
解决办法
1884
查看次数

为什么要分两步进行位移?

Linux 内核中,我找到了以下代码:

static inline loff_t pos_from_hilo(unsigned long high, unsigned long low)
{
#define HALF_LONG_BITS (BITS_PER_LONG / 2)
    return (((loff_t)high << HALF_LONG_BITS) << HALF_LONG_BITS) | low;
}
Run Code Online (Sandbox Code Playgroud)

该代码用于将系统调用参数组合成一个更宽的变量,因此例如在 ia32 上,偏移量pwritev在两个 32 位寄存器中指定。

在 x64 上,loff_t并且unsigned long都是 64 位宽。在这种情况下,high变量将被忽略并仅low被使用。在 ia32 上,loff_t是 64 位宽和unsigned long32 位宽。在这种情况下,两个参数highlow组合在一起。

我想知道为什么代码移位两次而不是一次。在提交消息和 LWN 文章中有更多关于此代码的信息系统调用和 64 位体系结构,但没有解释双位移位。

c linux bit-manipulation unspecified-behavior

8
推荐指数
1
解决办法
122
查看次数

负整数>> 31 = -1不是1?

所以,假设我有一个有符号整数(几个例子):

-1101363339 = 10111110 01011010 10000111 01110101 in binary.
-2147463094 = 10000000 00000000 01010000 01001010 in binary.
-20552      = 11111111 11111111 10101111 10111000 in binary.
Run Code Online (Sandbox Code Playgroud)

现在:-1101363339 >> 31例如,应该等于1对吗?但在我的电脑上,我得到-1.无论我选择什么负整数,如果x =负数,x >> 31 = -1.为什么?显然是二进制的,它应该是1.

c

7
推荐指数
3
解决办法
805
查看次数

为什么同一语句中的左移和右移会产生不同的结果?

请考虑以下示例:

第一个案例:

short x=255;
x = (x<<8)>>8;
cout<<x<<endl;
Run Code Online (Sandbox Code Playgroud)

第二种情况:

short x=255;
x = x<<8;
x = x>>8;
cout<<x<<endl;
Run Code Online (Sandbox Code Playgroud)

第一种情况下的输出是255,而第二种情况下的输出是-1.-1因为输出确实有意义,因为cpp进行算术右移.以下是获取-1作为输出的x的中间值.

x: 0000 0000 1111 1111  
x<<8:1111 1111 0000 0000 
x>>8:1111 1111 1111 1111
Run Code Online (Sandbox Code Playgroud)

为什么在第一种情况下不会发生相同的机制?

c++ bit-manipulation bit-shift

7
推荐指数
1
解决办法
269
查看次数

Printf()打印字符为32位

我正在运行一个快速测试,以确保我的指针算术运算:

main.c中

#include <stdio.h>
#include <stdlib.h>

#define ADDRESS    0xC0DCA11501LL
#define LENGTH     5


void print_address( char *, char );

/* Main program */
int main( int argc, char *argv[] )
{
    char nums[ LENGTH ];

    /* LSB first */
    for( int i = 0; i < LENGTH; i++ )
    {
        nums[ i ] = ( ADDRESS >> ( 8 * i ) ) & 0xFF;
    }

    print_address( nums, LENGTH );

    system("PAUSE");

    return 0;
}

void print_address( char *data, char len ) …
Run Code Online (Sandbox Code Playgroud)

c printf

5
推荐指数
1
解决办法
216
查看次数

char类型按位操作失败到int

我尝试在C中按位操作.这是我的代码:

int main() {
    char c = 127;
    c <<= 1;
    if (c == 0xfe) {
        printf("yes");
    }
    else {
        printf("No");
    }
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

系统控制台打印否.我希望收到的是是.位移后c中的值为ffffffffe.似乎系统已经将8位改为32位.谁能帮我.

c bit-manipulation type-conversion integer-promotion type-promotion

4
推荐指数
1
解决办法
63
查看次数

如何快速设置64位整数中的全1之后的9位

我正在编写一个C ++程序,并且需要一个在所有现有的“ 1”之后将所有9位都设置为1的函数。

也就是说,我要编写一个void set10BitsFull(int64_t& n)将整数“ int64_t n = 0b...1000000000...set10BitsFull(n)转换n为“ 0b...1111111111...” 的函数。

(更新)将输入整数的位稀疏地设置为1,并且两个1之间至少有10位距离。对于样本输入0x20000200,期望的输出为0x3FF003FF。最后1个位之后将至少有9位0。最左边的10位将始终为零。

这是我对该功能的实现

/**
 * Inline function that set 10 bits to 1 after each set 1
 * i.e.,
 * ......1000000000...... -> ......1111111111.......
 *
 * @param n
 *      pointer of input number
 */
inline void set10BitFull(int_fast64_t *n) {
    // n = 1000000000
    *n |= (*n >> 1); // n = 1100000000
    *n |= (*n >> 2) | …
Run Code Online (Sandbox Code Playgroud)

c++ bit-manipulation

4
推荐指数
1
解决办法
141
查看次数

你如何平均将两个32位颜色打包成一个整数?

我试图平均两种颜色.

我原来的(可怕的)工具如下:

//color is a union
int ColorAverage(int c1, int c2) {
    color C1(c1);
    color C2(c2);
    return color(
        (unsigned char)(0.5f * C1.a + 0.5f * C2.a),
        (unsigned char)(0.5f * C1.r + 0.5f * C2.r),
        (unsigned char)(0.5f * C1.g + 0.5f * C2.g),
        (unsigned char)(0.5f * C1.b + 0.5f * C2.b)
    ).c;
}
Run Code Online (Sandbox Code Playgroud)

我目前的解决方案如下(表现更好):

int ColorAverage(int c1, int c2) {
    unsigned char* b1 = reinterpret_cast<unsigned char*>(&c1);
    unsigned char* b2 = reinterpret_cast<unsigned char*>(&c2);
    int value;
    unsigned char* bv = reinterpret_cast<unsigned char*>(&value);
    bv[0] …
Run Code Online (Sandbox Code Playgroud)

int average colors

3
推荐指数
1
解决办法
485
查看次数

当优化关闭时,任何流行的编译器都会利用未定义的行为吗?

该博客声称:

  • 未定义的行为仅在高优化级别(例如 -O2 或 -O3)下“发生”。
  • 如果我使用 -O0 之类的标志关闭优化,那么就没有 UB。

都是假的。我想知道是否有任何现实世界的展示可以证明这一点。

例如,n << 1当 时触发 UB n<0。对于以下函数:

void foo(int n) {
  int t = n<<1;
  if (n>=0)
    nuke();
}
Run Code Online (Sandbox Code Playgroud)

编译器可以谨慎地编译它:

void foo(int n) {
  int t = n>=0 ? (n*2) : error("lshift negative int");
  if (n>=0)
    nuke();
}
Run Code Online (Sandbox Code Playgroud)

或通常:

void foo(int n) {
  int t = n*2;
  if (n>=0)
    nuke();
}
Run Code Online (Sandbox Code Playgroud)

或者积极优化它:

void foo(int n) {
  // unused
  // int t = n<<1;

  // always true, otherwise …
Run Code Online (Sandbox Code Playgroud)

c undefined-behavior

0
推荐指数
1
解决办法
222
查看次数