从可变位宽扩展符号

Posted

技术标签:

【中文标题】从可变位宽扩展符号【英文标题】:Sign extending from a variable bit width 【发布时间】:2016-08-06 10:35:53 【问题描述】:

这是一段 C++ 代码:

#include <iostream>
#include<limits.h>
using namespace std;

void sign_extending(int x,unsigned b)

  int r;      // resulting sign-extended number
  int const m = CHAR_BIT * sizeof(x) - b;
  r = (x << m) >> m;
  cout << r;


void Run()

  unsigned b = 5; // number of bits representing the number in x
  int x = 29;      // sign extend this b-bit number to r
 sign_extending(x,b);

结果:-3

结果数将是一个有符号数,其位数存储在 b 中。我正在尝试在 python 中复制此代码:

from ctypes import *
import os

def sign_extending(x, b):
  m = c_int(os.sysconf('SC_CHAR_BIT') * sizeof(c_int(x)) - b)    
  r = c_int((x << m.value) >> m.value)        # Resulting sign-extended number
  return r.value

b = c_int(5)       # number of bits representing the number in x
x = c_int(29)      # sign extend this b-bit number to r
r = sign_extending(x.value, b.value)
print r

结果:29

我无法像从 c++ 中的输出那样获得符号扩展数。我想知道我当前代码(python)中的错误或问题,以及使用这种技术的可能解决方案。

【问题讨论】:

您所做的不是符号扩展。在 C++ 中,当您使用有符号整数时,已经为您进行了符号扩展。 这个问题与你昨天问的问题非常相似:***.com/questions/38794715/… 另外,在 C 和 C++ 中,将负数右移是 not guaranteed to replicate the sign bit。 @PM2Ring 它是相似的,但是我正在尝试使用不同的技术做同样的事情。昨天我询问了使用位域,现在我遇到了这种方法的问题。 【参考方案1】:

你可以使用

def sign_extending(x, b):
    if x&(1<<(b-1)): # is the highest bit (sign) set? (x>>(b-1)) would be faster
        return x-(1<<b) # 2s complement
    return x

【讨论】:

我可以使用它,但我想要一个解决方案,它是对我当前代码的改进,而不是完全改变它 对我来说这看起来像是一个改进,因为它具有更好的可读性;)我实际上无法改进您的代码,抱歉。 为什么要移植坏代码?人们告诉你 &gt;&gt; 不能保证做符号扩展。您应该将此代码移植回 C++。

以上是关于从可变位宽扩展符号的主要内容,如果未能解决你的问题,请参考以下文章

有符号与无符号数之间赋值的截断和扩展

我们可以在 c++20 协程中使用 alloca() 或可变长度数组扩展吗?

可变参数模板在目标文件中有重复的符号?

打字稿可变泛型类,接受扩展公共基础的可变数量的类对象?

可变参数模板包扩展

Swift 2在协议扩展中使用变异函数时出错“无法在不可变值上使用变异成员:'self'是不可变的