在C中是否有一种无分支技术来计算两个无符号整数之间的绝对差值?例如,给定变量a和b,对于a = 3,b = 5或b = 3,a = 5的情况,我希望值为2.理想情况下,我还希望能够使用SSE寄存器对计算进行矢量化.
我转换的无符号整数使用位运算符为二进制,和目前还整数&1,以检查是否比特是1或0,并且输出,然后通过1右移由2.然而的位被以错误的顺序返回到划分(反转),所以我想在开始之前反转整数中的位顺序.
有一个简单的方法吗?
示例:如果我给了unsigned int 10 = 1010
while (x not eq 0)
if (x & 1)
output a '1'
else
output a '0'
right shift x by 1
Run Code Online (Sandbox Code Playgroud)
这会返回0101这是不正确的...所以我想在运行循环之前反转最初的位顺序,但我不确定如何做到这一点?
两个补码被设置为使计算机更容易计算两个数的减法.但计算机如何区分整数是有符号整数还是无符号整数?它的内存只有0和1.
例如, 1111 1111在计算机中,存储器可以表示数字255,但也可以表示-1.
我不小心碰到了iPad上Safari的javascript引擎中一个非常奇怪的错误.
无符号移位运算符>>>应该按位右移数字.我在脚本中遇到了一些错误,这些错误在其他平台上运行良好,将其剥离并最终得到:
<html><head><script type='text/javascript'>
var one = 1;
function Zero()
{
return one*0;
}
function Strange()
{
return one = (Zero()+1) >>> 0;
}
var s = 'A bunch of ones: '; // except on iPad :(
for (var i=0; i<200; i++)
{
s += Strange()+' ';
}
document.write(s);
</script></head><body></body></html>
Run Code Online (Sandbox Code Playgroud)
奇怪的是,它正确地生成了一堆,但在某个时刻,某些东西会中断并且从那时起它只会输出零.
显然>>> 0在这里毫无意义(零位置的移位通常什么都不做,尽管如果javascript做出这种区分,它可能会强制整数变为无符号).这只是为了证明这个问题,如果你省略了>>> 0它没有显示出来.在我的实际情况中,有不同的数字和更复杂的表达涉及,但同样的事情发生:一切都工作,直到一些迭代,然后一些'休息'和变量突然变成并保持为零,即使在后续计算真正应该做他们非零.
适用于Android和PC浏览器.奇怪吧?
有人可以向我解释以下代码输出:
void myprint(unsigned long a)
{
printf("Input is %lx\n", a);
}
int main()
{
myprint(1 << 31);
myprint(0x80000000);
}
Run Code Online (Sandbox Code Playgroud)
输出gcc main.c:
Input is ffffffff80000000
Input is 80000000
Run Code Online (Sandbox Code Playgroud)
为什么被(1 << 31)视为签名并被0x80000000视为未签名?
我自己确信,在一个项目中,我正在研究有符号整数是大多数情况下的最佳选择,即使其中包含的值永远不会是负数.(更简单的循环反转,更少的错误机会等,特别是对于只能保持0和20之间的值的整数,无论如何.)
出现问题的大多数地方是std :: vector的简单迭代,过去常常是一个数组,之后变为std :: vector.所以这些循环通常如下所示:
for (int i = 0; i < someVector.size(); ++i) { /* do stuff */ }
Run Code Online (Sandbox Code Playgroud)
由于此模式经常使用,因此编译器警告垃圾邮件的数量与签名和未签名类型之间的此比较往往隐藏更多有用的警告.请注意,我们肯定没有带有多个INT_MAX元素的向量,并注意到目前为止我们使用了两种方法来修复编译器警告:
for (unsigned i = 0; i < someVector.size(); ++i) { /*do stuff*/ }
Run Code Online (Sandbox Code Playgroud)
这通常有效但如果循环包含任何代码,如'if(i-1> = 0)......'等,可能会默默地中断.
for (int i = 0; i < static_cast<int>(someVector.size()); ++i) { /*do stuff*/ }
Run Code Online (Sandbox Code Playgroud)
这种变化没有任何副作用,但它确实使循环的可读性降低了很多.(而且它打字更多.)
所以我提出了以下想法:
template <typename T> struct vector : public std::vector<T>
{
typedef std::vector<T> base;
int size() const { return base::size(); }
int max_size() const { return base::max_size(); }
int …Run Code Online (Sandbox Code Playgroud) 在.Net中使用带符号数作为索引的理由是什么?
在Python中,您可以通过发送负数来从数组的末尾开始索引,但在.Net中不是这种情况.对.Net来说,以后添加这样的功能并不容易,因为它可能会在索引时使用特殊规则(是的,一个坏主意,但我猜它会发生)破坏其他代码.
并不是说我曾经需要索引大小超过2,147,483,647的数组,但我真的不明白为什么他们选择签名数字.
是不是因为在代码中使用带符号的数字更为正常?
编辑:我刚刚找到这些链接:
编辑2:好的,Matthew Flaschen发布的帖子还有其他几个很好的理由:
有些问题是为什么Java不支持无符号类型以及有关处理无符号类型的一些问题.我做了一些搜索,看起来Scala也不支持无符号数据类型.Java和Scala的语言设计中的限制,生成的字节码,还是JVM本身?是否有一些语言在JVM上运行,并且在其他方面与Java(或Scala)相同,但是支持无符号原始数据类型?
int plus unsigned int返回unsigned int.应该这样吗?
考虑以下代码:
#include <boost/static_assert.hpp>
#include <boost/typeof/typeof.hpp>
#include <boost/type_traits/is_same.hpp>
class test
{
static const int si = 0;
static const unsigned int ui = 0;
typedef BOOST_TYPEOF(si + ui) type;
BOOST_STATIC_ASSERT( ( boost::is_same<type, int>::value ) ); // fails
};
int main()
{
return 0;
}
Run Code Online (Sandbox Code Playgroud) 我正在阅读卡内基梅隆大学有关计算机系统的幻灯片来进行测验。在幻灯片第 49 页中:
使用无符号倒数
使用无符号作为循环索引的正确方法Run Code Online (Sandbox Code Playgroud)unsigned i; for (i = cnt-2; i < cnt; i--) a[i] += a[i+1];更好
Run Code Online (Sandbox Code Playgroud)size_t i; for (i = cnt-2; i < cnt; i--) a[i] += a[i+1];
我不明白为什么它不会是无限循环。我正在递减i并且它是无符号的,所以它应该总是小于cnt。请解释。