表示C中无符号值范围内的有符号值范围

时间:2017-02-20 09:31:00

标签: c bit-manipulation

如何将-128中的值转换为127范围至0255范围。

我在签名变量中有一个值。我需要使用无符号变量打印转换后的值。

4 个答案:

答案 0 :(得分:1)

您的问题不够准确:将[-128..127]转换为[0..255]可以通过多种方式完成。

  • 是否要保留0..127范围内的值并将负值转换为范围128..255?这可以通过简单的方式将值(unsigned char)(uint8_t)轻松完成。

  • 是否要将-128转换为0-127转换为1 ...最多127转换为255 ?只需将128添加到签名值即可。

答案 1 :(得分:1)

OP似乎希望从signed char转换为unsigned char。 OP提供的答案支持这一点:

#include <stdio.h>

#define MAX (255)

unsigned char convert(signed char sv)
{
    unsigned char x;
    x = (unsigned char)(sv + 128);
}
int main(void) {

    signed char sv = -128;
    unsigned char uv = 0;
    uv = convert(sv);
    print("converted value = %d", uv);
}

请注意,convert()应返回unsigned char值,但不会在上面的代码中返回任何值。这明确提到在标准中导致未定义的行为:§ 6.9.1 12

回顾基本的代码问题,即convert()函数没有返回任何值以及使用print()代替printf(),可能会想知道可能存在整数溢出。

当然,上述解决方案适用于sv = -128,或更准确地说,sv = SCHAR_MINSCHAR_MAX+1代替128,但如果我们sv = SCHAR_MAX怎么办? ,甚至sv = 0?似乎SCHAR_MAX + SCHAR_MAX+1的值超出signed char的范围,0 + SCHAR_MAX+1也是如此,并且此类溢出会导致未定义的行为。

代码由整数促销保存在这里,其中包含:

  

C11 Draft Standard §6.3.1.1 2

     

无论是int还是unsigned,都可以在表达式中使用以下内容   可以使用int:

     
      
  • 具有整数类型(int或unsigned int除外)的对象或表达式,其整数转换等级小于或等于   int和unsigned int的等级。
  •   
  • _Bool,int,signed int或unsigned int类型的位字段。
  •   
     

如果int可以表示原始类型的所有值(限制为   通过宽度,对于位字段),该值被转换为int;   否则,它将转换为unsigned int。这些被称为   整数促销。

因此,sv在表达式int中被提升为sv + 128,结果值为int。除非char实际为int s,否则此处不存在整数溢出的可能性,这意味着SCHAR_MAXINT_MAX相同(此的可能性,但不太可能)。

然后将sv + 128生成的值转换为unsigned char,并且可能会返回到调用函数。但是这里不需要强制转换,因为在赋值之前结果的类型将转换为unsigned char

  

C11 Draft Standard §6.5.16.1 2

     

在简单赋值(=)中,转换右操作数的值   到赋值表达式的类型并替换存储的值   在左操作数指定的对象中。

但是这里甚至不需要赋值,因为表达式的值被unsigned char语句转换为return

  

C11 Draft Standard §6.8.6.4 3

     

如果执行带有表达式的return语句,则该值为   表达式作为函数调用的值返回给调用者   表达。如果表达式的类型与返回类型不同   它出现的函数的类型,该值被转换为   通过赋值给具有函数返回类型的对象。

因此,通过利用整数提升和返回类型转换,convert()函数可以简化为:

unsigned char convert(signed char sv)
{
    return sv + 128;
}

当然,这个功能非常小,可以重写整个程序。为了获得最大的可移植性,应使用SCHAR_MAX中的limits.h。此外,%hhu转换说明符应用于打印unsigned char的值:

#include <stdio.h>
#include <limits.h>

int main(void) {

    signed char sv = -128;
    unsigned char uv = sv + SCHAR_MAX + 1;

    printf("converted value = %hhu\n", uv);
}

请注意,您也可以简单地将sv投射到unsigned char,或者您可以依赖于分配类型转换,避免显式转换:

unsigned char uv = sv;

此方法有效,但会产生不同的结果。以下是两种方法的结果比较:

#include <stdio.h>
#include <limits.h>

int main(void)
{
    signed char sv;
    unsigned char uv;

    printf("Conversion by addition");
    sv = SCHAR_MIN;
    for (int i = 0; ; sv++, i++) {
        if (i % 6 == 0) {
            putchar('\n');
        }
        uv = sv + SCHAR_MAX + 1;
        printf("%4hhd --> %-4hhu", sv, uv);
        if (sv == SCHAR_MAX) break;
    }
    puts("\n");

    printf("Conversion by casting");
    sv = SCHAR_MIN;
    for (int i = 0; ; sv++, i++) {
        if (i % 6 == 0) {
            putchar('\n');
        }
        /* could use uv = sv instead of (unsigned char) sv */
        printf("%4hhd --> %-4hhu", sv, (unsigned char) sv);
        if (sv == SCHAR_MAX) break;
    }
    putchar('\n');

    return 0;
}

节目输出:

Conversion by addition
-128 --> 0   -127 --> 1   -126 --> 2   -125 --> 3   -124 --> 4   -123 --> 5   
-122 --> 6   -121 --> 7   -120 --> 8   -119 --> 9   -118 --> 10  -117 --> 11  
-116 --> 12  -115 --> 13  -114 --> 14  -113 --> 15  -112 --> 16  -111 --> 17  
-110 --> 18  -109 --> 19  -108 --> 20  -107 --> 21  -106 --> 22  -105 --> 23  
-104 --> 24  -103 --> 25  -102 --> 26  -101 --> 27  -100 --> 28   -99 --> 29  
 -98 --> 30   -97 --> 31   -96 --> 32   -95 --> 33   -94 --> 34   -93 --> 35  
 -92 --> 36   -91 --> 37   -90 --> 38   -89 --> 39   -88 --> 40   -87 --> 41  
 -86 --> 42   -85 --> 43   -84 --> 44   -83 --> 45   -82 --> 46   -81 --> 47  
 -80 --> 48   -79 --> 49   -78 --> 50   -77 --> 51   -76 --> 52   -75 --> 53  
 -74 --> 54   -73 --> 55   -72 --> 56   -71 --> 57   -70 --> 58   -69 --> 59  
 -68 --> 60   -67 --> 61   -66 --> 62   -65 --> 63   -64 --> 64   -63 --> 65  
 -62 --> 66   -61 --> 67   -60 --> 68   -59 --> 69   -58 --> 70   -57 --> 71  
 -56 --> 72   -55 --> 73   -54 --> 74   -53 --> 75   -52 --> 76   -51 --> 77  
 -50 --> 78   -49 --> 79   -48 --> 80   -47 --> 81   -46 --> 82   -45 --> 83  
 -44 --> 84   -43 --> 85   -42 --> 86   -41 --> 87   -40 --> 88   -39 --> 89  
 -38 --> 90   -37 --> 91   -36 --> 92   -35 --> 93   -34 --> 94   -33 --> 95  
 -32 --> 96   -31 --> 97   -30 --> 98   -29 --> 99   -28 --> 100  -27 --> 101 
 -26 --> 102  -25 --> 103  -24 --> 104  -23 --> 105  -22 --> 106  -21 --> 107 
 -20 --> 108  -19 --> 109  -18 --> 110  -17 --> 111  -16 --> 112  -15 --> 113 
 -14 --> 114  -13 --> 115  -12 --> 116  -11 --> 117  -10 --> 118   -9 --> 119 
  -8 --> 120   -7 --> 121   -6 --> 122   -5 --> 123   -4 --> 124   -3 --> 125 
  -2 --> 126   -1 --> 127    0 --> 128    1 --> 129    2 --> 130    3 --> 131 
   4 --> 132    5 --> 133    6 --> 134    7 --> 135    8 --> 136    9 --> 137 
  10 --> 138   11 --> 139   12 --> 140   13 --> 141   14 --> 142   15 --> 143 
  16 --> 144   17 --> 145   18 --> 146   19 --> 147   20 --> 148   21 --> 149 
  22 --> 150   23 --> 151   24 --> 152   25 --> 153   26 --> 154   27 --> 155 
  28 --> 156   29 --> 157   30 --> 158   31 --> 159   32 --> 160   33 --> 161 
  34 --> 162   35 --> 163   36 --> 164   37 --> 165   38 --> 166   39 --> 167 
  40 --> 168   41 --> 169   42 --> 170   43 --> 171   44 --> 172   45 --> 173 
  46 --> 174   47 --> 175   48 --> 176   49 --> 177   50 --> 178   51 --> 179 
  52 --> 180   53 --> 181   54 --> 182   55 --> 183   56 --> 184   57 --> 185 
  58 --> 186   59 --> 187   60 --> 188   61 --> 189   62 --> 190   63 --> 191 
  64 --> 192   65 --> 193   66 --> 194   67 --> 195   68 --> 196   69 --> 197 
  70 --> 198   71 --> 199   72 --> 200   73 --> 201   74 --> 202   75 --> 203 
  76 --> 204   77 --> 205   78 --> 206   79 --> 207   80 --> 208   81 --> 209 
  82 --> 210   83 --> 211   84 --> 212   85 --> 213   86 --> 214   87 --> 215 
  88 --> 216   89 --> 217   90 --> 218   91 --> 219   92 --> 220   93 --> 221 
  94 --> 222   95 --> 223   96 --> 224   97 --> 225   98 --> 226   99 --> 227 
 100 --> 228  101 --> 229  102 --> 230  103 --> 231  104 --> 232  105 --> 233 
 106 --> 234  107 --> 235  108 --> 236  109 --> 237  110 --> 238  111 --> 239 
 112 --> 240  113 --> 241  114 --> 242  115 --> 243  116 --> 244  117 --> 245 
 118 --> 246  119 --> 247  120 --> 248  121 --> 249  122 --> 250  123 --> 251 
 124 --> 252  125 --> 253  126 --> 254  127 --> 255 

Conversion by casting
-128 --> 128 -127 --> 129 -126 --> 130 -125 --> 131 -124 --> 132 -123 --> 133 
-122 --> 134 -121 --> 135 -120 --> 136 -119 --> 137 -118 --> 138 -117 --> 139 
-116 --> 140 -115 --> 141 -114 --> 142 -113 --> 143 -112 --> 144 -111 --> 145 
-110 --> 146 -109 --> 147 -108 --> 148 -107 --> 149 -106 --> 150 -105 --> 151 
-104 --> 152 -103 --> 153 -102 --> 154 -101 --> 155 -100 --> 156  -99 --> 157 
 -98 --> 158  -97 --> 159  -96 --> 160  -95 --> 161  -94 --> 162  -93 --> 163 
 -92 --> 164  -91 --> 165  -90 --> 166  -89 --> 167  -88 --> 168  -87 --> 169 
 -86 --> 170  -85 --> 171  -84 --> 172  -83 --> 173  -82 --> 174  -81 --> 175 
 -80 --> 176  -79 --> 177  -78 --> 178  -77 --> 179  -76 --> 180  -75 --> 181 
 -74 --> 182  -73 --> 183  -72 --> 184  -71 --> 185  -70 --> 186  -69 --> 187 
 -68 --> 188  -67 --> 189  -66 --> 190  -65 --> 191  -64 --> 192  -63 --> 193 
 -62 --> 194  -61 --> 195  -60 --> 196  -59 --> 197  -58 --> 198  -57 --> 199 
 -56 --> 200  -55 --> 201  -54 --> 202  -53 --> 203  -52 --> 204  -51 --> 205 
 -50 --> 206  -49 --> 207  -48 --> 208  -47 --> 209  -46 --> 210  -45 --> 211 
 -44 --> 212  -43 --> 213  -42 --> 214  -41 --> 215  -40 --> 216  -39 --> 217 
 -38 --> 218  -37 --> 219  -36 --> 220  -35 --> 221  -34 --> 222  -33 --> 223 
 -32 --> 224  -31 --> 225  -30 --> 226  -29 --> 227  -28 --> 228  -27 --> 229 
 -26 --> 230  -25 --> 231  -24 --> 232  -23 --> 233  -22 --> 234  -21 --> 235 
 -20 --> 236  -19 --> 237  -18 --> 238  -17 --> 239  -16 --> 240  -15 --> 241 
 -14 --> 242  -13 --> 243  -12 --> 244  -11 --> 245  -10 --> 246   -9 --> 247 
  -8 --> 248   -7 --> 249   -6 --> 250   -5 --> 251   -4 --> 252   -3 --> 253 
  -2 --> 254   -1 --> 255    0 --> 0      1 --> 1      2 --> 2      3 --> 3   
   4 --> 4      5 --> 5      6 --> 6      7 --> 7      8 --> 8      9 --> 9   
  10 --> 10    11 --> 11    12 --> 12    13 --> 13    14 --> 14    15 --> 15  
  16 --> 16    17 --> 17    18 --> 18    19 --> 19    20 --> 20    21 --> 21  
  22 --> 22    23 --> 23    24 --> 24    25 --> 25    26 --> 26    27 --> 27  
  28 --> 28    29 --> 29    30 --> 30    31 --> 31    32 --> 32    33 --> 33  
  34 --> 34    35 --> 35    36 --> 36    37 --> 37    38 --> 38    39 --> 39  
  40 --> 40    41 --> 41    42 --> 42    43 --> 43    44 --> 44    45 --> 45  
  46 --> 46    47 --> 47    48 --> 48    49 --> 49    50 --> 50    51 --> 51  
  52 --> 52    53 --> 53    54 --> 54    55 --> 55    56 --> 56    57 --> 57  
  58 --> 58    59 --> 59    60 --> 60    61 --> 61    62 --> 62    63 --> 63  
  64 --> 64    65 --> 65    66 --> 66    67 --> 67    68 --> 68    69 --> 69  
  70 --> 70    71 --> 71    72 --> 72    73 --> 73    74 --> 74    75 --> 75  
  76 --> 76    77 --> 77    78 --> 78    79 --> 79    80 --> 80    81 --> 81  
  82 --> 82    83 --> 83    84 --> 84    85 --> 85    86 --> 86    87 --> 87  
  88 --> 88    89 --> 89    90 --> 90    91 --> 91    92 --> 92    93 --> 93  
  94 --> 94    95 --> 95    96 --> 96    97 --> 97    98 --> 98    99 --> 99  
 100 --> 100  101 --> 101  102 --> 102  103 --> 103  104 --> 104  105 --> 105 
 106 --> 106  107 --> 107  108 --> 108  109 --> 109  110 --> 110  111 --> 111 
 112 --> 112  113 --> 113  114 --> 114  115 --> 115  116 --> 116  117 --> 117 
 118 --> 118  119 --> 119  120 --> 120  121 --> 121  122 --> 122  123 --> 123 
 124 --> 124  125 --> 125  126 --> 126  127 --> 127 

答案 2 :(得分:0)

假设您提供的信息是我们所需要的 只需将128添加到signed变量,然后将其保存为unsigned变量

例如。

s.v = -50

u.v = 128 + s.v

u.v = 78

答案 3 :(得分:0)

public boolean incrementToken() throws IOException {
        if (!this.input.incrementToken()) {
            return false;
        } else {
            String input = termAtt.toString();
            // add "_____" at the beginning and ending of the phrase for exact match searching
            input = "_____ " + input + " _____";
            char[] newBuffer = input.toLowerCase().toCharArray();
            termAtt.setEmpty();
            termAtt.copyBuffer(newBuffer, 0, newBuffer.length);
            return true;
        }
    }