Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/126.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 使用位运算检测负整数_C++_C_Binary - Fatal编程技术网

C++ 使用位运算检测负整数

C++ 使用位运算检测负整数,c++,c,binary,C++,C,Binary,检查给定整数是否为负的一种方法是:(使用位运算) 现在似乎很好。但真的是这样吗?这符合标准吗?如果负整数不表示为2的补码怎么办?如果在二进制计算系统中,不要求只有负整数的最高有效位才有1,那该怎么办 我们可以编写这样的代码,既可移植又符合标准吗 相关主题: 将整数强制转换为相应的无符号类型,这样就不必担心使用的是什么有符号表示。唯一剩下的问题是可能存在填充位。这是一种无位移位的解决方案,因此不依赖于与位大小匹配的位宽度: 使用类似于使用循环移位的位换行的方法,这样您可以在位字符串的开头获得拇

检查给定整数是否为负的一种方法是:(使用位运算)

现在似乎很好。但真的是这样吗?这符合标准吗?如果负整数不表示为2的补码怎么办?如果在二进制计算系统中,不要求只有负整数的最高有效位才有1,那该怎么办

我们可以编写这样的代码,既可移植又符合标准吗


相关主题:


将整数强制转换为相应的无符号类型,这样就不必担心使用的是什么有符号表示。唯一剩下的问题是可能存在填充位。这是一种无位移位的解决方案,因此不依赖于与位大小匹配的位宽度:


使用类似于使用循环移位的位换行的方法,这样您可以在位字符串的开头获得拇指下的最后一位,然后
bool neg=n&1它还是什么。下面是一些位包装代码:

template <typename T>
inline T rotate_left(T val, unsigned char shift=1)
{
    static const bits = sizeof(T) * CHAR_BIT;
    return (val >> (bits-shift)) | (val << shift);
}

template <typename T>
inline T rotate_right(T val, unsigned char shift=1)
{
    static const bits = sizeof(T) * CHAR_BIT;
    return (val << (bits-shift)) | (val >> shift);
}

// And now for some platform-dependant specializations...

#include <intrin.h>

template<>
inline unsigned char rotate_left(unsigned char val, unsigned char shift=1)
{
    return _rotl8(val, shift);
}

template<>
inline unsigned char rotate_right(unsigned char val, unsigned char shift=1)
{
    return _rotr8(val, shift);
}

template<>
inline unsigned int rotate_left(unsigned int val, unsigned char shift=1)
{
    return _rotl(val, shift);
}

template<>
inline unsigned int rotate_right(unsigned int val, unsigned char shift=1)
{
    return _rotr(val, shift);
}

template<>
inline unsigned long long rotate_left(unsigned long long val, unsigned char shift=1)
{
    return _rotl64(val, shift);
}

template<>
inline unsigned long long rotate_right(unsigned long long val, unsigned char shift=1)
{
    return _rotr64(val, shift);
}
模板
内联T向左旋转(T val,无符号字符移位=1)
{
静态常量位=sizeof(T)*字符位;
返回(val>>(位移位))|(val移位);
}
//现在,对于一些依赖于平台的专业化。。。
#包括
模板
内联无符号字符向左旋转(无符号字符val,无符号字符移位=1)
{
返回旋转8(val、shift);
}
模板
内联无符号字符向右旋转(无符号字符val,无符号字符移位=1)
{
返回旋转8(val、shift);
}
模板
内联无符号整数向左旋转(无符号整数val,无符号字符移位=1)
{
返回旋转(val、shift);
}
模板
内联无符号整数向右旋转(无符号整数val,无符号字符移位=1)
{
返回旋转器(val、shift);
}
模板
内联无符号长循环左循环(无符号长循环val,无符号字符移位=1)
{
返回旋转64(val、shift);
}
模板
内联无符号long long rotate_right(无符号long long val,无符号char shift=1)
{
返回旋转64(val、shift);
}
注释:C和C++是不同的语言。它们各自的标准在某种程度上是独立发展的,它们对数字表示有不同的形式限制


我们可以编写这样的代码,既可移植又符合标准吗

假设您需要一种识别和解释符号位的通用方法,我认为您的问题的答案是否定的

关于C++:我不认为该标准对符号位的存在有明确的要求。即使每个实现都使用符号位,也不能保证它是代码假定的第一个(高阶)位。此外,该位的解释可能与您假设的相反(符号位的“1”值可能表示该数字为正)

关于C99:该语言确实需要符号位,并且要求符号=1表示负数(尽管它可能是“负零”)。然而,语言标准并没有给出确定符号位位置的一般方法

下面的代码试图以通用的方式创建“SypMaskMask'”,但它不能绝对保证在C99或C++中工作。失败的原因包括上面提到的那些,但最有趣的是,它可能调用“陷阱表示”(例如奇偶校验位错误)

\ifdef\uuucplusplus
#定义INT_MAX std::numeric_limits::MAX()
#定义UINT_MAX std::numeric_limits::MAX()
#恩迪夫
//假设符号位变为无符号的高阶位
整数符号掩码=整数最大值^UINT最大值;
//无符号类型未利用符号位时的回退
//这可能会在某些平台上调用“陷阱表示”
如果(sign\u mask==0)sign\u mask=~INT\u MAX;
这篇维基百科文章讨论了用二进制表示有符号数字的几种不同方式:


.

扩展R.s方法:

template <typename T> is_negative(T v) {
    boost::make_unsigned<T>::type u(v);
    return (u & (1 << std::numeric_limits<T>::digits - 1));
}
模板为负(tV){
boost::make_unsigned::type u(v);

return(u&(1)
给定的int<0
有什么问题?@Chris:没什么问题。只是我想“用位运算”来做@Nawaz-如果你发现比
更快的东西,我会很感兴趣。这是错误的。标准没有指定整数表示。所以你假设顶部的位有助于识别负数。PS。很高兴你找到了字符位。@Chris:我不是说更快。我只是想“使用位运算”来完成它只是出于好奇。——纳瓦兹10小时前,如果你在演员阵容中使用
uintmax\t
,你就不必担心
x
的原始类型了@Chris:完全正确。希望优化器不会实际扩展到更多的位,但我不确定……到无符号类型的转换定义为约化模1加上m目标类型的最大值,也就是转换为两个补码。这同样适用于常量
-1
,给出的结果在减法后只设置了最高位。@R..-我以前不知道,但我查过了,标准上说转换为无符号类型最终转换为两个补码ent表示法。这是否意味着我们可以做
const int x=-1;如果((无符号)x=*(无符号*)&x){/*two的补码*/}或者{/*other表示*/}
(忽略
*(无符号*)&x是未定义行为的明显部分)?无符号整数的范围可能与有符号整数的范围相同,在这种情况下,宏将为-1和INT_MAX给出相同的结果。我在您的答复中没有看到任何讨论。它是否符合标准且可移植?似乎是。我看不到与此相关的任何问题。如何检测负整数?如上所述:向左旋转(n) 然后是布尔值x=n&1。如果n==1,则为负。模板根据给定值推断类型,默认移位为1。它适用于f
#define IS_NEG(x) ((unsigned_type)x & (unsigned_type)-1-(unsigned_type)-1/2)
template <typename T>
inline T rotate_left(T val, unsigned char shift=1)
{
    static const bits = sizeof(T) * CHAR_BIT;
    return (val >> (bits-shift)) | (val << shift);
}

template <typename T>
inline T rotate_right(T val, unsigned char shift=1)
{
    static const bits = sizeof(T) * CHAR_BIT;
    return (val << (bits-shift)) | (val >> shift);
}

// And now for some platform-dependant specializations...

#include <intrin.h>

template<>
inline unsigned char rotate_left(unsigned char val, unsigned char shift=1)
{
    return _rotl8(val, shift);
}

template<>
inline unsigned char rotate_right(unsigned char val, unsigned char shift=1)
{
    return _rotr8(val, shift);
}

template<>
inline unsigned int rotate_left(unsigned int val, unsigned char shift=1)
{
    return _rotl(val, shift);
}

template<>
inline unsigned int rotate_right(unsigned int val, unsigned char shift=1)
{
    return _rotr(val, shift);
}

template<>
inline unsigned long long rotate_left(unsigned long long val, unsigned char shift=1)
{
    return _rotl64(val, shift);
}

template<>
inline unsigned long long rotate_right(unsigned long long val, unsigned char shift=1)
{
    return _rotr64(val, shift);
}
#ifdef __cplusplus
   #define INT_MAX std::numeric_limits<int>::max()
   #define UINT_MAX std::numeric_limits<unsigned int>::max() 
#endif

// assumes sign bit becomes high-order bit of unsigned
   int sign_mask = INT_MAX ^ UINT_MAX; 

// fallback in case unsigned type doesn't take advantage of the sign-bit
// This might invoke a "trap representation" on some platforms
   if (sign_mask==0) sign_mask = ~INT_MAX;
template <typename T> is_negative(T v) {
    boost::make_unsigned<T>::type u(v);
    return (u & (1 << std::numeric_limits<T>::digits - 1));
}