笔者也是一名菜鸟,所以有些东西可能不正确,而且这个简书排版也不怎么会,有问题各位大佬可以直接指出,不用留情面。
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进制
-
这里是将16进制的数,每一位拆分转换成10进制,然后再转换成2进制。
image.png
-
10进制转2进制方法图
image.png
重要:余数从下往上依次获取就是我们的二进制字符串
- (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]];
}
-
补码:反码+1注意进位
//补码
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语言的几个知识点,肯定有更简单的方法,但是笔者这几年所干的高强度重复工作,导致自己所有的东西都忘的一干二净,现在从头学起。
网友评论