您的位置:首页 > 其它

如何判断一个数为无符号数还是有符号数

2014-08-12 21:50 274 查看
转自:http://blog.csdn.net/eric491179912/article/details/6249946

网上搜到的去年sybase在上海交大的一道笔试题,猛一下还真想不出来怎么整,总是以为正数的时候无法判断,后经实验室一牛师弟点拨,方才编出以下代码,主要利用了无符号数和有符号数相减结果为无符号数的性质。

#include<stdio.h>

int main()

{

//unsigned int a = 100; //待判断数

int a = 100;

int b = -1; //参照数

if(a<0)

{

printf("有符号数");

}

else

{

if(b-a>0)//若 a 为无符号数,则 b - a 时,b 会“升级”为无符号数,-1 变成无符号数就是 0xFFFFFFFF,是最大值,因此 b - a 将为非负数

printf("无符号数");

else

printf("有符号数");

}

return 0;

}

其他网友解答:

1. 利用函数重载

发信人: Enderson (小强), 信区: C_Cpp

标 题: Re: 如何判断一个变量是有符号还是无符号的?

发信站: 兵马俑BBS (Wed Nov 7 21:25:45 2007), 本站(bbs.xjtu.edu.cn)

void f(int val)

{

std::cout << "singned" << std::endl;

}

void f(unsigned int val)

{

std::cout << "unsigned" << std::endl;

}

在判断a是否有符号整数的地方调用函数f(a)就可以了吧

2. 通过改变符号位判断

发信人: phylips (星星||决定了,为老婆孩子奋斗), 信区: C_Cpp

标 题: Re: 如何判断一个变量是有符号还是无符号的?

发信站: 兵马俑BBS (Wed Nov 7 17:16:02 2007), 本站(bbs.xjtu.edu.cn)

那这样可以不

把A进行一个位运算,将最高位置1,判断是否大于0

A = A|(1 << 31);

if(A > 0)

printf("unsigned");

else

printf("signed");

3. 利用去反等判断

发信人: xiaopei (很累), 信区: C_Cpp

标 题: Re: 如何判断一个变量是有符号还是无符号的?

发信站: 兵马俑BBS (Thu Nov 8 10:32:08 2007), 本站(bbs.xjtu.edu.cn)

看到过这样的方法:

n为非负数

n>=0 && -n>=0 && n-1>=0

为真则为无符号,否则有符号



---------------



读《C专家编程》,其中一段讲面试,说是微软曾经有一道面试题:

写一段代码,确定一个变量是有符号数还是无符号数?

书上给出了两个宏:

#define ISUNSIGNED(a) (a>=0 && ~a>=0)

#define ISUNSIGNED(type) ((type)0-1 > 0)

第二个从类型来判断,没有问题。

而第一个只能用在K&R C里,在ANSI C里就不行了。

当这个宏被用在int/unsigned int时,没有任何问题。

但是当使用在char和short上就会出错。

ANSI C中的整型升级:

char,short int或者int型位段(bit-field),包括它们的有符号或无符号变型,

以及枚举类型,可以使用在需要int或unsigned int的表达式中,

如果int可以完整地表示源类型的所有值,那么该类型的值就转换为int,否则转换为unsigned int。

ANSI C中的寻常算术转换:

当执行算术运算时,操作数的类型如果不同,就会发生转换。

数据类型一般朝着浮点精度更高、长度更长的方向转换,

整型数如果转换为signed不会丢失信息,就转换为signed,否则就转换为unsigned。

这个称为值保留(value preserving)原则。

所以,无论原先是否有符号,char和short都被转换成了signed int(整型升级)。

原先unsigned的东西变成了signed,然后再进行取反。

同时,常数0被认为是signed int类型,所以一律被判为有符号数了。

问题是一旦char或者short参与了运算,它们将被首先转换成int,

在这以后,任何操作都变成徒劳的了,int永远都是signed。

那么能否在整型升级之前让signed char/short变成负数呢?至少我现在还没想到办法。

偶使用了赖皮方法,无耻地定义了全局变量,还用了变态的逗号表达式……

于是第一个宏就变成下面这个样子了:

int r, t;

#define ISUNSIGNED(a) (t = a, r = (a>=0 && (a=~a)>=0), a = t, r)

再一想,既然用了全局变量保存a的值,还讨论干啥?于是……

int r, t;

#define ISUNSIGNED(a) (t = a, r = ((a=-1) >= 0), a = t, r)

而且这样做的前提是,假设int是最长的整型类型,并且是有符号的。

Peter Van Der Linden看到,保证要吐死了,5555~~~~~









先看ANSI C手册中的关于寻常算术转换的规定。

首先,如果一个操作书的类型是long double,那么另一个操作数也被转化为long double。其次,如果一个操作数的类型是double,那么另一个操作数也被转换为double。再次,如果其中一个操作数的类型是float,那么另一个操作数也被转换为float。否则,两个操作数进行整型提升,执行下面的规则:

如果其中一个操作数是unsigned long int,那么另一个操作数也被转换为unsigned long int。其次,如果其中一个操作数是long int, 而另一个操作数的类型是unsigned int ,如果long int 能够完整表示unsigned int 的所有值,那么unsigned int类型操作数被转换为long int,如果long int类型不能完整的表示unsigned int 的所有值,那么两个操作数都被转换为unsigned long int。再次,如果其中一个操作数的类型是long
int,那么另一个操作数转换为long int。再再次,如果其中一个操作数的类型是unsigned int ,那么另一个操作数被转换为unsigned int。如果所有以上的情况都不属于,那么两个操作数都为int。

简言之,当进行算术运算时,操作数的类型如果不同,就会发生转换。数据类型一般朝着浮点精度更高,长度更长的防线转换,整型数如果转换为signed 不会丢失信息,就转换为signed,否则转换为unsigned。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: