【C语言】原码、反码、补码详解 -《码上有道 ! 》

目录

  • 原码、反码、补码详解及其在C语言中的应用
    • 一、原码(Sign-Magnitude)
      • [1.1 定义与表示](#1.1 定义与表示)
      • [1.2 历史来源与作用](#1.2 历史来源与作用)
      • [1.3 示例](#1.3 示例)
      • [1.4 C语言示例](#1.4 C语言示例)
      • [1.5 代码运行结果](#1.5 代码运行结果)
    • [二、反码(One's Complement)](#二、反码(One's Complement))
      • [2.1 定义与表示](#2.1 定义与表示)
      • [2.2 历史来源与作用](#2.2 历史来源与作用)
      • [2.3 示例](#2.3 示例)
      • [2.4 C语言示例](#2.4 C语言示例)
      • [2.5 代码运行结果](#2.5 代码运行结果)
    • [三、补码(Two's Complement)](#三、补码(Two's Complement))
      • [3.1 定义与表示](#3.1 定义与表示)
      • [3.2 历史来源与作用](#3.2 历史来源与作用)
      • [3.3 示例](#3.3 示例)
      • [3.4 C语言示例](#3.4 C语言示例)
      • [3.5 代码运行结果](#3.5 代码运行结果)
    • 四、原码、反码、补码之间的关系
    • 五、总结
    • 六、参考文献
    • 七、结束语

原码、反码、补码详解及其在C语言中的应用

在计算机科学中,整数的表示方式有多种,包括原码、反码和补码。这些表示方式主要用于解决整数的二进制表示和计算问题。本文将详细介绍这三种表示方法,并通过示例来说明它们的原理和应用,特别是它们在C语言中的应用。

一、原码(Sign-Magnitude)

1.1 定义与表示

原码是一种最直接的二进制表示法,其中最高位(最左边的一位)表示符号位,其他位表示数值大小。

  • 符号位:0 表示正数,1 表示负数。
  • 数值位:直接使用二进制表示数值大小。

1.2 历史来源与作用

原码在早期计算机中被广泛使用,因为其简单直观的表示方式便于理解和实现。然而,由于在处理正负数运算时需要单独处理符号位,导致计算复杂,逐渐被反码和补码取代。

1.3 示例

十进制 原码表示
5 0000 0101
-5 1000 0101

说明

  • 0000 0101 表示正数 5。
  • 1000 0101 表示负数 -5。

1.4 C语言示例

在C语言中,没有直接操作原码的方式,但可以通过位操作实现对符号位和数值位的处理。

c 复制代码
#include <stdio.h>

void printBinary(int num) {
    for (int i = 7; i >= 0; i--) {
        printf("%d", (num >> i) & 1);
    }
    printf("\n");
}

int main() {
    int num = 5;
    int neg_num = -5;

    printf("原码表示:\n");
    printf("5 的二进制表示: ");
    printBinary(num);
    printf("-5 的二进制表示: ");
    printBinary((1 << 7) | num);  // 手动构造原码表示

    return 0;
}

1.5 代码运行结果

原码表示:
5 的二进制表示: 00000101
-5 的二进制表示: 10000101

二、反码(One's Complement)

2.1 定义与表示

反码是将原码的数值位按位取反(0 变 1,1 变 0)得到的。

  • 正数的反码:与其原码相同。
  • 负数的反码:将其原码的数值位取反,符号位不变。

2.2 历史来源与作用

反码的引入是为了解决原码在进行加减运算时的符号位问题。通过按位取反,可以简化计算机中负数的表示和运算。然而,反码存在两个零(正零 0000 0000 和负零 1111 1111),计算不便,最终被补码取代。

2.3 示例

十进制 原码表示 反码表示
5 0000 0101 0000 0101
-5 1000 0101 1111 1010

说明

  • 正数 5 的反码与其原码相同。
  • 负数 -5 的反码是 1111 1010,其中 0000 0101 的每个位取反得到 1111 1010

2.4 C语言示例

在C语言中,可以通过位操作计算反码。

c 复制代码
#include <stdio.h>

void printBinary(int num) {
    for (int i = 7; i >= 0; i--) {
        printf("%d", (num >> i) & 1);
    }
    printf("\n");
}

int main() {
    int num = 5;
    int neg_num = -5;

    printf("反码表示:\n");
    printf("5 的二进制表示: ");
    printBinary(num);
    printf("-5 的反码表示: ");
    printBinary(~num);  // 按位取反得到反码

    return 0;
}

2.5 代码运行结果

反码表示:
5 的二进制表示: 00000101
-5 的反码表示: 11111010

三、补码(Two's Complement)

3.1 定义与表示

补码是目前计算机系统中广泛使用的一种二进制表示法,解决了原码和反码的缺点。

  • 正数的补码:与其原码相同。
  • 负数的补码:在其反码的基础上加 1。

3.2 历史来源与作用

补码的引入是为了统一零的表示(只有一个零 0000 0000)并简化计算。补码使得正数和负数的加减运算可以使用同一套电路,避免了符号位单独处理的问题,极大地提高了计算效率。由于这些优点,补码成为现代计算机系统中普遍使用的整数表示方法。

3.3 示例

十进制 原码表示 反码表示 补码表示
5 0000 0101 0000 0101 0000 0101
-5 1000 0101 1111 1010 1111 1011

说明

  • 正数 5 的补码与其原码相同。
  • 负数 -5 的补码是 1111 1011,在反码 1111 1010 的基础上加 1 得到 1111 1011

3.4 C语言示例

在C语言中,负数的补码表示可以通过标准的负数表示方式得到。

c 复制代码
#include <stdio.h>

void printBinary(int num) {
    for (int i = 7; i >= 0; i--) {
        printf("%d", (num >> i) & 1);
    }
    printf("\n");
}

int main() {
    int num = 5;
    int neg_num = -5;

    printf("补码表示:\n");
    printf("5 的二进制表示: ");
    printBinary(num);
    printf("-5 的补码表示: ");
    printBinary(neg_num);

    return 0;
}

3.5 代码运行结果

补码表示:
5 的二进制表示: 00000101
-5 的补码表示: 11111011

四、原码、反码、补码之间的关系

十进制 原码 反码 补码
5 0000 0101 0000 0101 0000 0101
-5 1000 0101 1111 1010 1111 1011
  • 正数:原码、反码、补码相同。
  • 负数:反码是原码数值位取反,补码是反码加 1。

五、总结

表示法 特点 应用
原码 简单直观,计算复杂 较少应用
反码 解决符号位问题,存在两个零 较少应用
补码 统一了零的表示,简化了计算,适合二进制运算 现代计算机系统广泛使用

补码的优点使得它成为现代计算机系统中普遍使用的整数表示方法。了解原码、反码和补码之间的关系和转换方法,对于理解计算机底层运算和处理负数具有重要意义。在C语言中,理解这些表示方法有助于更好地处理整数运算和位操作。

六、参考文献

  1. Kernighan, B. W., & Ritchie, D. M. (1988). The C Programming Language (2nd ed.). Prentice Hall.
  2. Andrew S. Tanenbaum. "Structured Computer Organization." 6th Edition. Pearson, 2013.
  3. ISO/IEC. (2024). ISO/IEC DIS 9899. Programming Languages -- C.
  4. Donald E. Knuth. "The Art of Computer Programming, Volume 2: Seminumerical Algorithms." 3rd Edition. Addison-Wesley, 1997.

七、结束语

  1. 本节内容已经全部介绍完毕,希望通过这篇文章,大家对原码、反码、补码有了更深入的理解和认识。
  2. 感谢各位的阅读和支持,如果觉得这篇文章对你有帮助,请不要吝惜你的点赞和评论 ,这对我们非常重要。再次感谢大家的关注和支持
相关推荐
~yY…s<#>1 小时前
【刷题17】最小栈、栈的压入弹出、逆波兰表达式
c语言·数据结构·c++·算法·leetcode
EricWang13583 小时前
[OS] 项目三-2-proc.c: exit(int status)
服务器·c语言·前端
我是谁??3 小时前
C/C++使用AddressSanitizer检测内存错误
c语言·c++
希言JY4 小时前
C字符串 | 字符串处理函数 | 使用 | 原理 | 实现
c语言·开发语言
午言若4 小时前
C语言比较两个字符串是否相同
c语言
TeYiToKu6 小时前
笔记整理—linux驱动开发部分(9)framebuffer驱动框架
linux·c语言·arm开发·驱动开发·笔记·嵌入式硬件·arm
互联网打工人no16 小时前
每日一题——第一百二十四题
c语言
爱吃生蚝的于勒6 小时前
深入学习指针(5)!!!!!!!!!!!!!!!
c语言·开发语言·数据结构·学习·计算机网络·算法
羊小猪~~6 小时前
数据结构C语言描述2(图文结合)--有头单链表,无头单链表(两种方法),链表反转、有序链表构建、排序等操作,考研可看
c语言·数据结构·c++·考研·算法·链表·visual studio
洋2406 小时前
C语言常用标准库函数
c语言·开发语言