计算机浮点数详解

一、计算机存储浮点数的算法

在计算机中,浮点数通常采用IEEE 754标准进行存储,该标准定义了两种主要的浮点数格式:单精度浮点数(32位)和双精度浮点数(64位)。

(一)单精度浮点数

  • 占用32位存储空间。
  • 格式分为三个部分:
    • 符号位(1位):0表示正数,1表示负数。
    • 指数位(8位):用于表示浮点数的指数大小。
    • 尾数位(23位):表示浮点数的小数部分。
      其存储的值计算公式为 ( − 1 ) s i g n × 1. f r a c t i o n × 2 e x p o n e n t − b i a s (-1)^{sign}×1.fraction×2^{exponent - bias} (1)sign×1.fraction×2exponentbias(其中 s i g n sign sign是符号位, f r a c t i o n fraction fraction是尾数位表示的小数部分, e x p o n e n t exponent exponent是指数位的值,对于单精度浮点数, b i a s bias bias为127)。

(二)双精度浮点数

  • 占用64位存储空间。
  • 格式同样分为符号位(1位)、指数位(11位)和尾数位(52位)。

二、为什么浮点数不能精确存储

(一)有限的位数

无论是单精度还是双精度浮点数,位数有限。在表示一些无限小数或者非常大/非常小的数时,必然存在精度损失。例如,十进制的 0.1 0.1 0.1在二进制中是无限循环小数 0.00011001100110011 … … 0.00011001100110011…… 0.00011001100110011……,由于浮点数位数有限,无法精确表示,只能近似存储。

(二)舍入误差

在将十进制数转换为二进制浮点数存储以及进行浮点数运算时,都可能发生舍入误差。例如, 0.2 0.2 0.2 0.3 0.3 0.3相加,十进制结果为 0.5 0.5 0.5,但在计算机中,因浮点数精度限制, 0.2 0.2 0.2 0.3 0.3 0.3不能精确表示,相加结果与 0.5 0.5 0.5有微小差异。

三、如何判断两个浮点数相等

由于浮点数存在精度问题,不能直接用==判断。通常采用以下方法:

(一)设置误差范围

  1. 定义一个非常小的数作为误差范围,如 ϵ = 1 e − 6 \epsilon = 1e - 6 ϵ=1e6
  2. 判断两个浮点数之差的绝对值是否小于 ϵ \epsilon ϵ,若是,则认为两浮点数相等。例如:
#include <stdio.h>
#include <math.h>

// 设置误差范围判断两个浮点数是否相等
void compareFloatsWithEpsilon() {
    double epsilon = 1e-6;
    double a = 0.1 + 0.2;
    double b = 0.3;

    if (fabs(a - b) < epsilon) {
        printf("a 和 b 相等\n");
    } else {
        printf("a 和 b 不相等\n");
    }
}

(二)相对误差判断

  1. 计算两个浮点数的相对误差,即两数之差除以其中一个数的绝对值。
  2. 如果相对误差小于给定阈值,则认为两浮点数相等。例如:
// 通过相对误差判断两个浮点数是否相等
void compareFloatsWithRelativeError() {
    double threshold = 1e-6;
    double a = 0.1 + 0.2;
    double b = 0.3;
    double relative_error = fabs(a - b) / (fabs(a) > fabs(b)? fabs(a) : fabs(b));

    if (relative_error < threshold) {
        printf("a 和 b 相等\n");
    } else {
        printf("a 和 b 不相等\n");
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值