当前课程知识点:C语言程序设计(上) > 数据计算实现与顺序结构程序设计(一) > 2.1 算术运算的C程序实现 > 2.1.4 整数相除
我们下边再做一点讨论
如果说
也就说我们把程序里面的float
这一块给它注释掉
大家看我把这一句话注释掉了
我把程序改成了
这边的预定
全预定的是int型的
因为我们刚才看见了三组数据
里边有两组数据
都给的是整型数
实际上给的是整型数
那我们把第二组输入去掉的话
可不可以说
把我们这里边涉及到的参数abc
以及
你的d q x1 2都定义成整型
那应该说是没有问题的
好了我们暂且这样做一下
读进来abc
计算没有做任何变化
大家看这里边红框框起来的部分
自始至终没有做任何变化
我们只是说
把定义的变量做了变化
把输出这一块也没有变化
还是把d输出
我们看结果是什么样子
我们拿了最后一组数据来做测试
输入的是 2
就a是2 b是2
c是负3
我们得到了的这个结果
d没有问题 还是28
可是我们得到的x1x2有问题
我们刚才的x1x2
不是这样的一个结果
可见这个结果现在是有问题的
是错了
为什么会错呢
大家看 这块我们的输入是整型
我们给的x1x2也是整型
这都没有问题 d也没有问题
为什么会出错呢
我们再来看一组数据
换一组输入
这一组输入的是1 2 -2
我们看
得到的数据跟刚才我们输入的第一组数据
得到的一样的结果
也就说 这一组数据是正确的
大家想想 同一个程序
根本就没有变 我们仅仅是
提供了不同的输入
得到的结果 会不同
这个不同是因为什么造成的呢
是我们改了什么
只改了说数据是整型 还是实型
可见 这块我们想说什么
整数相除的时候
它会出现什么问题
比如说我们拿这样一个数去相除
我们看到这个结果是
对不同的 两组输入
程序是一样的
得到的结果一个是错的一个是对的
这是为什么
相除 整数相除 带来的问题
那整数相除有什么问题
简单说 比如说我们这样
你拿 1除以3
大家想想 1除以3
1是整型没有错
3是整型没有错
但是得到的结果应该是0.3333
可是 两个整数相除在程序里边
尤其是在c里边
它得到的 只取整数
它不会取0.3333
这样的话 它取的是什么呢 0
把那点333就扔掉了
这就是 我们这的问题
就说 两个整数相除的时候
结果 只取整数部分
小数部分就丢掉了
这样的话就会给后续的运算
带来错误 这种错误
编译器会给了我们一个误导
使编译的时候并查不出来这种错误
因为编译的时候我们还没有运算结果
编译器不会 检测出来这种错误
所以 这种错误比较隐式的
在里边 如果你不小心的话
这里边的 这个结果
你会认为 它是正确的
实际上 这个结果是错误的
所以 我们说
整数相除的时候要慎用
怎么叫慎用呢
比如说 把这件事这样做它就可以了
把1除以3 可以写成1.0除以3
1.0除以3
下面我可以不改成3.0
这时候 c做这件事情的时候
一个实型数和一个整型数运算的时候
它先会把整型数
换成 实型数
就两个实型数运算
结果是实型数
这就没有问题了
所以 整型数运算的时候
尤其是做 整型数相除的时候
会有问题 这个大家一定要注意
接下来我们再讨论一个问题
讨论我们第三个问题
大家一定会说 刚才这样做了
这个两个整数相除有这么大的问题
那咱 能不能这样
我把x1x2 定义成实型的
也就说 我把我的容器
定义成实型的
你会不会算出来的结果
就会自然变成实型的呢
大家看一下
相当于我们在这
定义了 float x1 x2
其他的还是整型的
这个计算 同样没有做任何变化
我们来输出
输出的时候
我们是 d是按整型的
x1x2 按实型的输出这三个数
大家看到的结果 是这样子
就我们给的输入还是2 2 负3
就是刚才 出错的这一组数据
就是 针对这一组输入
它的输出 如果是整型的话会输错
那我们在这看见
仍然 是错的
就是 它的x1不是0
是0.00
是什么意思
就说 你的两个整型数
在做相除的时候
你其实已经 舍掉了它的小数
小数部分 只保留了整数部分
你把这个整数 再送到一个
实型数的 容器里的时候
实际上拿到的只有你整数的部分
只不过它用了 4个字节来放你的
这个整型数
而并不取决于x2和x1
它的变量 是什么样子的
那我们刚才讨论了这个问题
实际上这块
我们用这么长的时候讨论
整数相除的问题
这是大家通常在程序设计里边
做计算的时候
往往会 出现问题却查不出来
你的错误原因的一个
非常重要的一个问题
就说编译 过程是非常流畅的
运行的过程 也是非常流畅的
但是就是结果不对
那大家 这种错误会比较隐式的
显现出来
大家不容易查到
也就是说我这个数实际上是
0.00123456
是这么一个数
这样一个数在计算机里怎么表示
它其实是这样的
如果我们用单精度的实型数表达的话
那就是4个字节
通常它是用3个字节来表达
这个小数的部分
而用 1个字节来表达指数的部分
它表达小数的 这个部分
用1位 做符号位
这是一个正的数
那 再用23位
来做它的小数的部分的 数据的部分
然后指数的部分也有一位是做符号位
而 其他的部分
7位呢 是来做什么呢
做它的 指数的这个部分
就是2 它的绝对值
那1位是占了它的符号位
对一个实型数 它是这样存放的
如果 这是我们现在说
这种存放方式
通常在 程序设计里边
把它叫做 规格化的数
什么叫规格化的数
大家刚才知道
这个数实际上你可以没有指数的部分
就是0.00123456
这不就完了吗 你为什么要整一个
乘以10的负2次方呢
是说 在程序里边
统一把数 做成这种规格化的数
也就说 小数点放在
第一个 有效数字的前边
而实际上这个数的大小
是靠 指数的部分去调节的
这是在程序里边 都是这样表达
一个数据的
那如果说你是
长双精度的16个字节
你用多少位来表达你的尾数
多少位表达指数
语言系统
是会对你有一个裁定
这是不用我们 使用的人去分的
是语言处理系统自动把它分好了
对这样的一个实型数和
整型数相比的话 我们看
差别是非常大的
对一个整型数
是用两个字节
有的系统是用4个字节
不管是两个字节还是4个字节
符号占一位 剩下的就是整数部分
它这块根本就没有指数部分的这一说
所以我们把一个整型的数据
去做运算
然后又要把它放到一个大的容器里边
那它就是把你的整数部分放到
它这块的尾数部分
就是它的小数部分
而它的指数部分实际上是没有的
所以 整型的数据和实型的数据
在你 做计算的时候
是要非常讲究使用的
就是我们刚才讲的
一个 带小数的数
也就说浮点的数 和整型的数
它的存储原理 是不一样的
另外
比如说我们对单精度的实数
你在输出的时候
一般来说我们总看见小数点
后面有6位数
有的系统是7位数
这个不要紧的
是6位还是7位都可以
总而言之 是说
你运算的过程
可能不是按照单精度的数去运算的
实际上运算器里边
永远都是用 双精度的数
也就说
用8个字节 去给你做这个运算的
它的精度是比较高的
但是当你输出的时候
它是会按 单精度的实型数去输出
就是6位或者7位的 有效位
所以我们说
只有整型数 它的运算是精确的
而实型数 运算是不精确的
所以 我们大家刚才再说到这个
数的有效位 以及数的精度的时候
大家一看
这个 实型数有非常大的优势的
是因为它表达的数据的范围比较大
而整型数就比起它来逊色了很多
但是 对数的精确性来说
是整型数 永远是精确的
所以 能用整数的时候
自然 不要用实数
但是 必须用实数的时候
不能跟 整型数混着用
我们刚才说数据会超出它的表达范围
是这样 如果比最小的数还小
或者比最大的数还大
分别称为下溢和上溢
下溢计算机会自动把它处理成0
而上溢 是不允许的
比如说上溢
你产生这种上溢是一个银行问题
那你丢掉的 是一个大的钱数
这是不允许的 所以会报错
好了 关于这个实型数
是有这么几点 还要提醒大家注意
也就说 有它的尾数的部分
有指数的部分
你定义的是双精度
就是8个字节
你定义的单精度就是4个字节
而数据的有效位
我们看到的它输出的
后边带几位小数
两个因素来确定
一个因素是
你指定的输出格式
你要看见几位
另外一个是
你实际上在内存里
存储的是什么样子
这两个因素决定了
看到的东西 是什么样的情况
-1.1 计算机的问题求解方法
--讨论题:数学模型
-1.1 计算机的问题求解方法--作业
-1.2 C语言与C程序
--讨论题:运算符
-1.3 C语言处理系统与程序调试运行
--例程
-1.4 程序中的人机交互
--例程
--作业讨论区
-2.1 算术运算的C程序实现
--算术混合运算.c
-2.1 算术运算的C程序实现--作业
-2.2 关系运算的C程序实现
--bukao.c
--字符比较.c
--讨论题:比较大小
-2.2 关系运算的C程序实现--作业
-第二周作业--作业
-2.3 逻辑运算的C程序实现
--计算结合性
--闰年.c
--自动购票问题.c
-2.3 逻辑运算的C程序实现--作业
-2.4 位运算的C程序实现
--讨论题:位运算
-2.5 几种很个别的运算
--讨论题
--讨论题
-2.5 几种很个别的运算--作业
-2.6 混合运算及数据类型转换
--讨论题:数据类型
-2.7 顺序结构程序实例
--Video
--三角形面积.c
--讨论题:工业产值
-2.7 顺序结构程序实例--作业
-3.1 程序中的路径选择实现
--打印学生成绩.c
--一元二次方程.c
-3.1 程序中的路径选择实现--作业
-3.2 路径中的再选择——嵌套判断
--例程
--讨论题:程序改错
-3.2 路径中的再选择——嵌套判断--作业
-3.3 复杂判断问题的C程序设计
--3.3 多级选择
--银行存款.c
--讨论题:多级选择
-3.4 多分支问题的C程序设计
--加减乘除运算.c
-3.4 多分支问题的C程序设计--作业
-3.5 GOTO的适当使用
-3.6 选择结构的程序实例
--3.6 程序展示
--计算第几天.c
--讨论题:输出奇数
--讨论题:计算税金
-3.6 选择结构的程序实例--作业
-第四周作业--作业
-4.1 需要重复执行的程序
--求和.c
--打印学生成绩.c
--统计录入速度.c
--求平均数.c
-4.1 需要重复执行的程序--作业
-4.2 至少要执行一次的循环
--n的阶乘.c
--字符分类统计.c
-4.2 至少要执行一次的循环--作业
-4.3 已知循环次数用for语句
--求和问题.c
--数列求和.c
--讨论题:循环语句
-4.3 已知循环次数用for语句--作业
-4.4 循环控制——简单循环应用
--水仙花数.c
--讨论题:死循环
--讨论题:猜数字
-循环结构的程序设计(一)--4.4 循环控制——简单循环应用
-4.5 循环的嵌套
--讨论题:程序运行
-4.5 循环的嵌套--作业
-4.6 break与continue
--最大素数.c
-4.6 break与continue--作业
-4.7 循环的综合应用
--数的排列组合.c
--鸡兔同笼.c
--打印空心字符.c
--讨论题:打印图形
--讨论题:计算闰年
-第六周作业
-第六周作业--作业
-5.1 同类有序数据处理问题
-5.2 一维数组的定义和引用
--数组定义.c
--数组初始化.c
--反向输出.c
--讨论题:对称数
-5.2 一维数组的定义和引用--作业
-5.3 一维字符串数组
--讨论题:编程
-5.4 字符串处理函数
--字符串反向.c
--字符串函数
-5.5 二维数组的定义与使用
-5.6 二维数组的输入输出
-5.6 二维数组的输入输出--作业
-5.7 二维数组的应用
--转置矩阵.c
--讨论题:修改程序
-5.8 二维字符数组
--5.8 单词排序
--单词排序.c
-5.8 二维字符数组--作业
-5.9 数组综合应用
--统计成绩.c
--统计字符次数.c
--讨论题:洗牌
-本期课程结束语
--end
-第八周编程作业
-《C语言程序设计(上)》期末复习参考
--html
-《C语言程序设计(上)》期末复习参考答案
--html