如何检测统一在不同的编码(1的补,补,符号大小)的整数的符号位? [英] How to uniformly detect an integer’s sign bit across various encodings (1's complement, 2's complement, sign magnitude)?

查看:221
本文介绍了如何检测统一在不同的编码(1的补,补,符号大小)的整数的符号位?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何检测 INT 签署岬用C?

这问题大多是历史的机器。我所问如何,如果一个整数为0或-0区别。在1的补数和符号/幅度INT编码,既是一个0(或+0)和-0是可能的。


简单的符号位的测试是比较反对 0

  INT X;
的printf(符号位为%s \\ n,(X℃下)设置:未设置);

但是,这无法在1的补,并签署幅度时 X -0


1号候选方法:模板测试结果
由于C定义,一个 INT 必须有一个符号位,无论整数编码,下面应该工作。

  INT X;
INT SignBitMask =待定;
的printf(符号位为%s \\ n,(X安培; SignBitMask)设置:未设置);

问题就变成如何确定 SignBitMask 的C中的价值?结果
SignBitMask = INT_MAX + 1 似乎是一个起点。


第二候选方法:创建功能和校验位模式:

  INT IsSignBitSet(INT X){
  如果(X 0)返回0;
  如果(X℃,)返回1;
  INT ZP = 0;
  如果(memcmp(安培; X,&安培; ZP,sizeof的X)== 0)返回0;
  INT锌= -0; //这甚至形成-0的方式吗?
  如果(memcmp(安培; X,&安培;锌,sizeof的X)== 0)返回1;
  //如果我们来到这里,现在该怎么办?
  返回?;
}


我想没有便携统一的解决办法 - 也许因为需要不再存在

为什么:我想知道如何把不同进行检测,并签署了印制零

请注意:我特意在这里避免了C标记,并想我第一次尝试就在历史记录标签


组合的3答案和C11dr 6.2.6.2整型(信息为 INT ,一个符号位的必须的存在,积极的符号位为0时,负符号位为1),溶液(出现独立1的补,2的补码和符号/幅值整数编码)是

  INT IsSignBitSet_Best(INT X){
  //返回1,如果x小于0 _or_ x是算术0与一些位集。
  返回(X小于0)|| ((X == 0)及及(*((unsigned int类型*)及X)));
}

直接面具的方法是最简单的,但还没有拿出一个高度便携面具定义

  INT IsSignBitSet_Simple(INT X){
  静态无符号SignBitMask = 0x80的; //或者其他一些平台依赖面膜
  返回((符号)x&安培; SignBitMask)!= 0;
}


解决方案

要寻找负0对零只是检查与所有设置任何位。

  INT testForNegative0(INT X){
   则返回(x == 0安培;&放大器; *((unsigned int类型*)及X));
}

或回答标题中的问题:

  INT hasSignBitSet(INT X){
   返回(X小于0)|| testForNegative0(X);
}

这适用于你提到的3编码,它可能不适合更深奥的那些工作。

How to detect an int sign-ness in C?

This question is mostly of historical machines. What I am asking how to distinguish if an integer is 0 or -0. In 1's complement and sign/magnitude int encoding, both a 0 (or +0) and -0 are possible.


The simple sign bit test is to compare against 0.

int x;
printf("sign bit is %s\n", (x < 0) ? "set" : "not set");

But this fails in 1's complement and sign magnitude when x is -0.


1st Candidate approach: Mask test.
As C defines that an int must have a sign bit regardless of integer encoding, the following should work.

int x;
int SignBitMask = tbd;
printf("sign bit is %s\n", (x & SignBitMask) ? "set" : "not set");

The question becomes how to determine the value of SignBitMask in C?
SignBitMask = INT_MAX + 1 seems like a starting point.


2nd Candidate approach: create function and check bit patterns:

int IsSignBitSet(int x) {
  if (x > 0) return 0;
  if (x < 0) return 1;
  int zp = 0;
  if (memcmp(&x, &zp, sizeof x) == 0) return 0;
  int zn = -0;  // Is this even the way to form a -0?
  if (memcmp(&x, &zn, sizeof x) == 0) return 1;
  // If we get here, now what?
  return ?;
}


I'm thinking there is no portable uniform solution - maybe because the need no longer exists.

Why: I have wondered how various signed zeros were detected and printed.

Note: I have purposely avoided the "C" tag here and thought I'd try just the "History" tag first.


[Edit] Answer

Combining info of 3 answers and C11dr 6.2.6.2 "Integer types" (for int, a single sign bit must exist, the positive sign bit is 0, the negative sign bit is 1), a solution (that appears independent of 1's complement, 2's complement and sign/magnitude integer encoding) is

int IsSignBitSet_Best(int x) {
  // return 1 if x is less than 0 _or_ x is arithmetically 0 with some bit set.
  return (x < 0) || ((x == 0) && (* ((unsigned int*) &x) ));
}

The direct mask approach is simplest, but have not come up with a highly portable mask definition

int IsSignBitSet_Simple(int x) {
  static unsigned SignBitMask = 0x80;  // Or some other platform dependent mask
  return ((unsigned)x & SignBitMask) != 0;
}

解决方案

To find negative 0's just check for a zero with any bit at all set.

int testForNegative0(int x) { 
   return (x==0 && *((unsigned int*)&x)); 
}

Or to answer the question in the title:

int hasSignBitSet(int x) { 
   return (x<0) || testForNegative0(x);
}

This works for the 3 encodings you mention, it may not work for even more esoteric ones.

这篇关于如何检测统一在不同的编码(1的补,补,符号大小)的整数的符号位?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆