当前位置: 首页 > news >正文

计算机中加减乘除的实现

在计算机中各种运算都是CPU来完成的,而CPU在算术运算上只能做加法和移位和取反运算,在逻辑上只有与、或、非、异或。那么计算机中的减法、乘法、除法又是如何运算的?

1.加法

数据在内存中以二进制补码的形式存储,CPU在进行加法运算时直接将两个操作数的二进制补码相加,在转换成原码即可。

2.减法

CPU做减法时,将减数取反,在与被减数相加得到结果。

示例1:15-8 = 7

15-8 = 15 + (-8),也就是取减数的相反数进行相加。15的二进制补码:0000 0000 0000 0000 0000 0000 0000 1111,-8的二进制补码:1111 1111 1111 1111 1111 1111 1111 1000

0000 0000 0000 0000 0000 0000 0000 1111 +  1111 1111 1111 1111 1111 1111 1111 1000 = 0000 0000 0000 0000 0000 0000 0000 0111 = 7D

示例2:6 - 8 = -2

6 - 8 = 6 + (-8) ,6的二进制补码:0000 0000 0000 0000 0000 0000 0000 0110,-8的二进制补码:1111 1111 1111 1111 1111 1111 1111 0111

0000 0000 0000 0000 0000 0000 0000 0110 +  1111 1111 1111 1111 1111 1111 1111 0111 = 1111 1111 1111 1111 1111 1111 1111 1101(补码)= 1000 0000 0000 0000 0000 0000 0000 0010 = -2

这里需要注意的是,计算完后直接得到的是补码,要将补码再转换成原码才是最终的结果。整数之所以不需要转换是因为整数的原码、反码、补码均相同。

3.除法

计算机在进行除法运算时,和人计算除法的原理很相似,也是商x余y的形式,只是计算机处理的是二进制数。

示例:15/7 = 2....1

15的二进制表示为:0000 0000 0000 0000 0000 0000 0000 1111,7的二进制表示为:0000 0000 0000 0000 0000 0000 0000 0111

1.二进制15的最左边的第一位1右移3位(二进制8中有三个1),的结果为0001 < 0111所以,商0余1.

2.上一步中的余数*2 + 下一位 = 11右移2位的结果为0011 < 0111,商00余11

3.上一步中的余数*2 + 下一位 = 111右移1位的结果为0111 = 0111,商001余0

4.上一步中的余数*2 + 下一位 = 1右移3位的结果为0001 < 0111,商0010余1

所以最终结果就为0010余1,即7....1

二进制的除法,商只有0和1两种结果,所以只要比较被除数小于等于除数直接商1,余被除数-除数,以此类推。

4.乘法

计算机中,一个数左移一位代表乘以2,右移一位代表除以2。例如:2->0010->左移一位:0100->4.所以,在计算机中对于a*x的运算实际是将a左移x为1的位的所有结果累加。

示例1: 3*6 = 18

这里的a = 3 = 0011,x = 6 = 0110.

1.x的第0位为0,a不用移动。

2.x的第1位为1,所以a左移1位 -> 0110

3.x的第2位为1,所以a左移2位->1100

4.x的第3位为0,a不用移动,

所以,最终结果就是:0110 + 1100 = 10010 = 18

 

相关文章:

  • Linux基本指令+使用举例、权限的认识和相关指令、Linux添加删除用户、shell的理解(超详细)
  • Linux连接网络、修改账户密码
  • LeetCode---删除排序数组中的重复项(C语言)
  • LeetCode---合并两个有序数组
  • leetcode---返回链表的中间节点
  • 学生成绩管理系统---数据结构、C语言课程设计
  • 数据结构课程设计---学生成绩管理系统
  • leetcode---环形链表(快慢指针证明)
  • leetcode---环形链表II
  • 剑指offer---复制带随机值的链表
  • Linux---进程概念
  • 数据结构---顺序表和链表
  • C语言课程设计---诗歌管理系统
  • 数据结构---栈和队列(栈、队列、循环队列)
  • leetcode---用两个栈实现队列
  • 【React系列】如何构建React应用程序
  • 【每日笔记】【Go学习笔记】2019-01-10 codis proxy处理流程
  • Effective Java 笔记(一)
  • Gradle 5.0 正式版发布
  • gulp 教程
  • javascript 总结(常用工具类的封装)
  • MySQL Access denied for user 'root'@'localhost' 解决方法
  • Objective-C 中关联引用的概念
  • Python实现BT种子转化为磁力链接【实战】
  • SpriteKit 技巧之添加背景图片
  • weex踩坑之旅第一弹 ~ 搭建具有入口文件的weex脚手架
  • 代理模式
  • 关于extract.autodesk.io的一些说明
  • 基于OpenResty的Lua Web框架lor0.0.2预览版发布
  • MyCAT水平分库
  • # Swust 12th acm 邀请赛# [ E ] 01 String [题解]
  • #stm32整理(一)flash读写
  • #大学#套接字
  • (1)安装hadoop之虚拟机准备(配置IP与主机名)
  • (33)STM32——485实验笔记
  • (c语言)strcpy函数用法
  • (JS基础)String 类型
  • (Redis使用系列) Springboot 实现Redis 同数据源动态切换db 八
  • (八十八)VFL语言初步 - 实现布局
  • (补)B+树一些思想
  • (附源码)springboot“微印象”在线打印预约系统 毕业设计 061642
  • (附源码)计算机毕业设计大学生兼职系统
  • (含react-draggable库以及相关BUG如何解决)固定在左上方某盒子内(如按钮)添加可拖动功能,使用react hook语法实现
  • (六)c52学习之旅-独立按键
  • (五)IO流之ByteArrayInput/OutputStream
  • (转)Android学习笔记 --- android任务栈和启动模式
  • (转)Mysql的优化设置
  • (转)创业家杂志:UCWEB天使第一步
  • (转)重识new
  • (转载)hibernate缓存
  • ..回顾17,展望18
  • .Net Attribute详解(上)-Attribute本质以及一个简单示例
  • .net CHARTING图表控件下载地址
  • .net refrector
  • .NET中的Event与Delegates,从Publisher到Subscriber的衔接!