计算机进行小数运算时出错的原因

#include <stdio.h>

int main()
{
    int i;
    float sum;
    sum = 0;

    for(i=1; i<=100; i++){
        sum += 0.1;
    }

    printf("%f\n", sum);// 10.000002

    return 0;
}

用二进制表示小数

4933701-9d400ae6a6e39ac5.png
1011.0011带小数点的二进制转换成十进制

计算机运算出错的原因

有些十进制数的小数无法转换成二进制

4933701-07da4d06342720ef.png
小数点后4位能够用二进制数表示的数值,二进制数是连续的,十进制数是非连续的。

因为无法正确表示的数值,最后都变成了近似值。计算机这个功能有限的机器设备,是无法处理无限循环的小数的。因此,在遇到循环小数时,是无法处理无限循环的小数的。因此,在遇到循环小数时,计算机就会根据变量数据类型所对应的长度将数据从在中间阶段或四舍五入。

什么是浮点数

浮点数是指用符号、尾数、基数、指数这四部分来表示的小数。

4933701-defb70ae21bb333f.png
浮点数的表示形式

因为计算机内部使用的是二进制数,所以基数自然是2,因此,实际的数据中往往不考虑基数,只用符号、尾数、指数这三部分即可表示浮点数。

4933701-2c078c1c39bd7a6d.png
浮点数的内部构造
  • 符号部分是指使用一个数据位来标识数值的符号
    符号位为1时表示负,为0时则表示“正或者0”。这和用二进制数来表示整数时的符号位是同样的。数值的大小用尾数部分和指数部分来表示。
    尾数部分和指数部分并不只是单单存储着用整数表示的二进制。
  • 尾数部分用的是“将小数点前面的值固定为1的正则表达式”
  • 指数部分用的则是“EXCESS系统表现”

正则表达式和EXCESS系统

尾数部分使用正则表达式,可将表现形式多样的浮点数统一为一种表现形式。

4933701-cfd1b1a33d3a7bbb.png
浮点数可用不同形式来表示同一个数值

十进制数的浮点数规则(正则表达式):“小数点前面是0,小数点后第一位不能是0”。

二进制数中,将小数点前面的值固定为1的正则表达式。具体来讲,就是将二进制数表示的小数左移或右移(逻辑移位)数次后,整数部分的第一位变成1,第二位之后都变为0。而且,第一位的1在实际的数据中不保存。有第一位必须是1,因此省略该部分后就节省了一个数据位,从而也就可以表示更多的数据范围。

4933701-0d19752871efb272.png
单精度浮点数尾数部分的正则表达式

指数部分中使用的EXCESS系统,主要是为了表示负数时不使用符号位。EXCESS系统表现是指,通过将指数部分表示范围的中间值设置为0,使得负数不需要使用符号来标识。

4933701-61b11161f7eafe7c.png
单精度浮点数指数部分的EXCESS系统表现

用于确认单精度浮点数表示方法的C语言程序

#include <stdio.h>
#include <string.h>

int main()
{
    float data;
    unsigned long buffer;
    int i;
    char c[34];

    data = (float)0.75;//将小数以单精度浮点数形式存储到变量中
    memcpy(&buffer, &data, 4);//将数据复制到4字节长度的整数变量buffer中以逐个提取出每一位
    //逐一提取每一位
    for(i=33; i>=0; i--){
        if(i==1 || i==10){
            //加入符号以区分符号部分、指数部分、尾数部分
            c[i] = '-';
        }else{
            //为字节赋值为'0'或'1'
            if(buffer%2 == 1){
                c[i] = '1';
            }else{
                c[i] = '0';
            }
            buffer /= 2;
        }
    }
    c[34] = '\0';
    printf("%s\n", c);//0-01111110-100000000000000000000000

    return 0;
}
4933701-bc6ae1af3421fb90.png
用单精度浮点数表示的数据

如何避免计算机计算出错

  • 回避策略,即无视这些错误。
  • 把小数转换成整数来计算

将小数替换成整数来计算的C语言程序

#include <stdio.h>

int main()
{
    int i;
    int sum;

    sum = 0;
    for(i=1; i<=100; i++){
        sum += 1;
    }

    sum /= 10;
    printf("%d\n", sum);// 10

    return 0;
}

除此之外,BCD(Binary Coded Decimal)也是一种使用二进制表示十进制的方法。简单来讲,BCD就是用位来表示0~9的1位数字的处理方法。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值