定点数和浮点数的细节讲解

一、了解定点数和浮点数

计算机中的实数处理一般有两种方法:定点数和浮点数。定点数指的是小数点位置固定的数值,典型的例子是货币的计算,小数点后两位即为分。

浮点数指的是小数点位置可以向左或向右浮动的数值,这里的“浮动”指的是小数点对数值精度的影响。

比如,$1.23 \times 10^4$和$12.3 \times 10^3$都可以用科学计数法表示为1.23e+04,但是前者的小数点的位置在大数的后面,而后者小数点的位置在大数的前面。所以,浮点数的表示范围相对较大,但是精度相对较低。

二、定点数的详解

在计算中,我们通常需要进行浮点数(实数)和定点数(整数)之间的转换。有时候,我们需要把实数乘以一个精度因子,再将其转换成整数,这就是定点数的表示方法。

#include <stdio.h>

#define Q        8        // 小数部分的位数
#define QQ        (1<<Q)    // 2^Q
#define QQ2       (1< %d\n", a, a_fix);
    printf("b: %.2lf -> %d\n", b, b_fix);
    printf("a+b: %.4lf\n", fix(a_fix + b_fix));
    return 0;
}

上述代码实现了将小数部分为8位的实数转化为整数操作,例如将2.25转换为$2.25 \times 2^8=576$。

三、浮点数的详解

在计算机内部,单精度浮点数32位,双精度浮点数64位。由于存储空间的限制,无法完全精确地表示实数。所以,计算机内部的浮点数通常采用科学计数法表示,在IEEE754标准中,单精度浮点数最高位表示符号,接着是指数部分,然后是尾数部分。

#include <stdio.h>

int main()
{
    float a = 1.2345;
    double b = 12.345;
    printf("a: %.10f\n", a);
    printf("b: %.15lf\n", b);
    return 0;
}

输出结果为:

a: 1.2344999313
b: 12.345000000000000

从输出结果可以看出,浮点数的精度不如定点数高。

四、小数点的移位问题

在浮点数的运算中,容易出现小数点的移位问题。比如,我们需要将一个浮点数加上一个整数,但是因为小数点位置的不同,可能会出现问题。

#include <stdio.h>

int main()
{
    double a = 1.0, b = 100000000000.0;
    int c = 1;
    printf("a+b: %.1lf\n", a+b);          // 输出:100000000001.0
    printf("(a+c)+b: %.1lf\n", (a+c)+b);    // 输出:100000000002.0
    printf("a+(c+b): %.1lf\n", a+(c+b));    // 输出:100000000001.0
    return 0;
}

从输出结果可以看出,在浮点数的运算中,加法并不满足结合律。

五、避免浮点数误差

为了避免浮点数运算中出现误差,我们可以采用避免小数点移位的方法,即将小数转换为整数进行运算。

#include <stdio.h>

int main()
{
    double a = 1.0, b = 100000000000.0;
    int a_fix = a * 1000;
    int b_fix = b;
    printf("a_fix+b_fix: %.1lf\n", (double)(a_fix+b_fix)/1000);    // 输出:100000000001.0
    return 0;
}

上述代码中,我们将浮点数乘以一个精度因子1000,再将其转换为整数进行计算。最后再将计算结果转换为浮点数。

六、整数溢出问题

在使用定点数时,有可能会出现整数溢出的问题。当定点数的位数不够用时,需要向左移动小数点,此时整数位数就会增加,如果整数位数过大,就会超出计算机所能表示的范围。

#include <stdio.h>

#define Q        3        // 小数部分的位数
#define QQ        (1<<Q)    // 2^Q
#define fract(x)  ((int)((x)*QQ+0.5))
#define fix(x)    ((double)(x)/QQ)

int main()
{
    double a = 128.0;
    int a_fix = fract(a);
    printf("a_fix: %d\n", a_fix);
    printf("2*a_fix: %d\n", 2*a_fix);  // 输出:512,已经溢出
    return 0;
}

因此,在使用定点数时,要注意定点数的整数和小数部分的位数,以免溢出。

原创文章,作者:小蓝,如若转载,请注明出处:https://www.506064.com/n/249627.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
小蓝的头像小蓝
上一篇 2024-12-12 17:11
下一篇 2024-12-12 17:11

相关推荐

  • int类型变量的细节与注意事项

    本文将从 int 类型变量的定义、声明、初始化、范围、运算和类型转换等方面,对 int 类型变量进行详细阐述和讲解,帮助读者更好地掌握和应用 int 变量。 一、定义与声明 int…

    编程 2025-04-29
  • Python中将字符串转化为浮点数

    本文将介绍在Python中将字符串转化为浮点数的常用方法。在介绍方法之前,我们先来思考一下这个问题应该如何解决。 一、eval函数 在Python中,最简单、最常用的将字符串转化为…

    编程 2025-04-29
  • 浮点数:float小数点后几位C

    在编程中,浮点数是一种常见的数据类型之一,而float小数点后几位C则是指浮点数在计算机中存储的精度问题。在编写程序的时候,我们需要考虑浮点数的精度问题,以避免算法出错或结果不准确…

    编程 2025-04-28
  • Python入门:输入三个浮点数并进行计算

    本文将介绍如何使用Python输入三个浮点数,并且进行计算,最后输出结果。 一、输入三个浮点数 在Python中,我们可以使用input()函数来获取用户的输入。为了输入三个浮点数…

    编程 2025-04-28
  • 浮点型数据的细节揭秘

    一、基本概念 浮点型数据是指可以表示实数的一种数据类型。在C语言中,浮点型数据有两种类型:float(单精度浮点数)和double(双精度浮点数)。其中,float数据类型占用4个…

    编程 2025-04-25
  • Latex加粗的使用细节

    一、Latex加粗的基本使用方法 在Latex中,加粗的基本语法是使用 \textbf{要加粗的文字} 。比如下面这个例子: The \textbf{quick} brown \t…

    编程 2025-04-25
  • :Darkgray的细节探索

    一、颜色值解析 对于前端开发来说,颜色选择是一项非常常见的任务。要实现一个​​优雅的前端设计,我们需要学会如何选择恰当的颜色。在这里,我将介绍darkgray,这是一种常用的颜色,…

    编程 2025-04-24
  • biba模型的细节探究

    一、无 biba模型是一种多级安全模型,它强调了完整性比机密性更为重要。在biba模型中,所有对象和主体都被赋予一个完整性级别,而更高完整性级别的主体只能读取更低完整性级别的对象。…

    编程 2025-04-22
  • QString contains:细节决定成败

    一、基本概念 QString是Qt中最为常用的字符串类,其中很重要的一个函数是contains。contains函数的作用是用于判断字符串是否包含指定的字符串,例如: QStrin…

    编程 2025-04-20
  • 切面表达式:细节决定成败

    一、切面表达式注解 注解是Java中非常重要的一种语法标记,Spring AOP中也通过注解的方式来定义切面。在定义切面时,可以使用@Aspect注解表示一个切面类,也可以使用@B…

    编程 2025-04-13

发表回复

登录后才能评论