iOS高级文章

iOS 有符号16进制转10进制

2019-07-30  本文已影响0人  有梦想的程序员

笔者也是一名菜鸟,所以有些东西可能不正确,而且这个简书排版也不怎么会,有问题各位大佬可以直接指出,不用留情面。

1、16进制怎么转10进制的C方法

C语言中提供了16进制转10进制的方法:

long     strtol(const char *__str, char **__endptr, int __base);
unsigned long strtoul(const char *__str, char **__endptr, int __base);

但是当我们调用上述方法strtol(@"F7".UTF8String, 0, 16) 发现, 'F7'得到的却不是我们想要的结果 -9,而是247,但是这是为什么呢?

我们看看 F7的二进制码 1111 0111 ,如果最高位不是符号位结果可不就是247吗?所以系统没有把最高位当做符号位,明白了原因我们开始着手自己实现。

2、步骤拆解

  • 16进制转2进制
  • 2进制求原码(正数的原码、反码、补码相同,负数的原码:补码每位取反+1)
  • 2进制转10进制

(1)16进制转2进制

重要:余数从下往上依次获取就是我们的二进制字符串

- (NSString *)binaryWithHexadecimal:(NSString *)string{
    // 现将16进制转换车无符号的10进制
    long a = strtoul(string.UTF8String, NULL, 16);
    NSMutableString *binary = [[NSMutableString alloc] init];
    while (a/2 !=0) {
        [binary insertString:[NSString stringWithFormat:@"%ld",a%2] atIndex:0];
        a = a/2;
    }
    
    [binary insertString:[NSString stringWithFormat:@"%ld",a%2] atIndex:0];
    
    //不够4位的高位补0
    while (binary.length%4 !=0) {
        [binary insertString:@"0" atIndex:0];
    }
    return binary;
}

将16进制每一位的二进制字符串拼接起来就是整个16进制数的二进制补码。

(2) 2进制求原码

正数的原码、反码、补码相同
负数的原码:补码按位取反+1

   if ([binaryString characterAtIndex:0] == '1') {
    //正数最高位0 ,负数最高位1
   }
//反码
   for (int i = (int)binaryString.length - 1; i > 0; i--) {
        char c = [binaryString characterAtIndex:i];
        c = c^0x1;
         [binaryString replaceCharactersInRange:NSMakeRange(i, 1) withString:[NSString stringWithFormat:@"%c",c]];
    }
  //补码
  BOOL flag = NO; //进位
  NSInteger lastIndex = binaryString.length - 1;
  char lastChar = [binaryString characterAtIndex:lastIndex];
  if (lastChar == '0') {
      lastChar = '1';
  } else {
      lastChar = '0';
      flag = YES;
  }
        
  [binaryString replaceCharactersInRange:NSMakeRange(lastIndex, 1) withString:[NSString stringWithFormat:@"%c",lastChar]];
        
  if (flag) {
      for (int i = (int)binaryString.length - 2; i > 0; i--) {
          char c = [binaryString characterAtIndex:i];
          if (flag) {//进位
              if (c == '0') {
                  c = '1';
                  flag = NO;
                  [binaryString replaceCharactersInRange:NSMakeRange(i, 1) withString:[NSString stringWithFormat:@"%c",c]];
                  break;
              } else if (c == '1'){
                  c = '0';
                  flag = YES;
                  [binaryString replaceCharactersInRange:NSMakeRange(i, 1) withString:[NSString stringWithFormat:@"%c",c]];
              }
          }
      }
  }
    //计算
    for (int i = (int)binaryString.length - 1; i > 0; i--) {
        char c = [binaryString characterAtIndex:i];
        if (c == '1') {
            result += pow(2, bit);
        }
        ++bit;
    }
    //最高位符号为如果是负数需要乘以-1,之前的计算没有算最高位的
    if ([binaryString characterAtIndex:0] == '1') {
        result = result *-1;
    }

3、整体实现

- (int)input0x16String:(NSString *)string{
    char *_0x16String = (char *)string.UTF8String;
    NSMutableString *binaryString = [[NSMutableString alloc] init];
    for (int i = 0; i < string.length; i++) {
        char c = _0x16String[i];
        NSString *binary = [self binaryWithHexadecimal:[NSString stringWithFormat:@"%c",c]];
        [binaryString appendString:binary];
    }
    
    if ([binaryString characterAtIndex:0] == '1') {
        //反码
        for (int i = (int)binaryString.length - 1; i > 0; i--) {
            char c = [binaryString characterAtIndex:i];
            c = c^0x1;
            [binaryString replaceCharactersInRange:NSMakeRange(i, 1) withString:[NSString stringWithFormat:@"%c",c]];
        }
        
        //补码
        BOOL flag = NO; //进位
        NSInteger lastIndex = binaryString.length - 1;
        char lastChar = [binaryString characterAtIndex:lastIndex];
        if (lastChar == '0') {
            lastChar = '1';
        } else {
            lastChar = '0';
            flag = YES;
        }
        
        [binaryString replaceCharactersInRange:NSMakeRange(lastIndex, 1) withString:[NSString stringWithFormat:@"%c",lastChar]];
        
        if (flag) {
            for (int i = (int)binaryString.length - 2; i > 0; i--) {
                char c = [binaryString characterAtIndex:i];
                if (flag) {//进位
                    if (c == '0') {
                        c = '1';
                        flag = NO;
                        [binaryString replaceCharactersInRange:NSMakeRange(i, 1) withString:[NSString stringWithFormat:@"%c",c]];
                        break;
                    } else if (c == '1'){
                        c = '0';
                        flag = YES;
                        [binaryString replaceCharactersInRange:NSMakeRange(i, 1) withString:[NSString stringWithFormat:@"%c",c]];
                    }
                }
            }
        }
    }
    
    int result = 0;
    int bit = 0;
    //计算
    for (int i = (int)binaryString.length - 1; i > 0; i--) {
        char c = [binaryString characterAtIndex:i];
        if (c == '1') {
            result += pow(2, bit);
        }
        ++bit;
    }
    if ([binaryString characterAtIndex:0] == '1') {
        result = result *-1;
    }
    return result;
}

- (NSString *)binaryWithHexadecimal:(NSString *)string{
    // 现将16进制转换车无符号的10进制
    long a = strtoul(string.UTF8String, NULL, 16);
    NSMutableString *binary = [[NSMutableString alloc] init];
    while (a/2 !=0) {
        [binary insertString:[NSString stringWithFormat:@"%ld",a%2] atIndex:0];
        a = a/2;
    }
    
    [binary insertString:[NSString stringWithFormat:@"%ld",a%2] atIndex:0];
    
    //不够4位的高位补0
    while (binary.length%4 !=0) {
        [binary insertString:@"0" atIndex:0];
    }
    return binary;
}

结束语:虽然很简单的功能让我实现的很复杂,但是我也至少复习了C语言的几个知识点,肯定有更简单的方法,但是笔者这几年所干的高强度重复工作,导致自己所有的东西都忘的一干二净,现在从头学起。
上一篇下一篇

猜你喜欢

热点阅读