zoukankan      html  css  js  c++  java
  • 判断一个数是由符号数还是无符号数

    这是在《C专家编程》一书上提到的一个问题。我在网上搜索了一下,找到了一些解法,总结如下。

    首先是《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上就会出错。

    分析: 此宏在int/unsigned int好使的原因是宏中的a的精度始终不会发生变化,而当a是char和short时,表达式~a>=0会先将a变为int然后再取反(因为常量0的类型为int),而int当然是有符号的,对它取反就有可能小于0。

    要修正这个错误其实很简单,那就是要保证先进行取反操作再做精度提升,我们可以采用对a取反a=~a(这样就不会有类型提升),判断结束后再取一次反,恢复a的值。

    这样得到新的代码:

    #define ISUNSIGNED(a) (a >=0 && (a=~a,a >=0 ? (a=~a,1):(a=~a,0)))

     

    另一种方法是:把变量的最高位置1,然后判断变量是否大于0。如果大于0,就是无符号数;否则就是有符号数。

    #defined ISUNSIGNED(a) (a|=(0x1<<(sizeof(a)*8-1))>0?1:0)

     

    还有人给出的方法是使用函数重载的方法:

    void f(int val)

    {

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

    }

    void f(unsigned int val)

    {

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

    }

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

     

    下面是对上面测试程序:

    #include <iostream>

    #define ISUNSIGNED(A) ((A|=(1<<(sizeof(A)*8-1)))>0?1:0)

    #define ISUNSIGNED2(N) (N>=0&&~N>=0)

    #define ISUNSIGNED3(N) (N>=0&&-N>=0&&N-1>=0)

    #define ISUNSIGNED4(N) (N>=0&&(N=~N,N>=0?(N=~N,1):(N=~N,0)))

    #define TEST(n) if(ISUNSIGNED4(n))\

    cout<<#n" is unsigned"<<endl;\

    else \

    cout<<#n" is signed"<<endl;

     

    using std::cout;

    using std::endl;

     

    void isUnsigned(){

    cout<<"*********** test int ************"<<endl;

    int i = 5;

    unsigned int ui = 5;

    TEST(i)

    TEST(ui)

    cout<<"*********** test long int ************"<<endl;

    long li = 55;

    unsigned long uli = 55;

    TEST(li)

    TEST(uli)

     

    cout<<"*********** test short ************"<<endl;

    short s = 3;

    unsigned short us = 3;

    TEST(s)

    TEST(us)

     

    cout<<"*********** test char ************"<<endl;

    signed char c = 18;

    unsigned char uc = 18;

    TEST(c)

    TEST(uc)

    }

     

    void f(int val){

    cout<<"signed"<<endl;

    }

    void f(unsigned int val){

    cout<<"unsigned"<<endl;

    }

     

    int main(){

    isUnsigned();

    return 0;

    }

     

  • 相关阅读:
    codechef Dynamic GCD [树链剖分 gcd]
    bzoj 4546: codechef XRQRS [可持久化Trie]
    bzoj 4835: 遗忘之树 [树形DP]
    bzoj 4033: [HAOI2015]树上染色 [树形DP]
    bzoj 4591: [Shoi2015]超能粒子炮·改 [lucas定理]
    3167: [Heoi2013]Sao [树形DP]
    bzoj 3812: 主旋律 [容斥原理 状压DP]
    有标号的二分图计数 [生成函数 多项式]
    有标号DAG计数 [容斥原理 子集反演 组合数学 fft]
    BZOJ 3028: 食物 [生成函数 隔板法 | 广义二项式定理]
  • 原文地址:https://www.cnblogs.com/xkfz007/p/2420172.html
Copyright © 2011-2022 走看看