细说浮点数

一.什么是浮点数

        浮点数能够表示带小数部分的数字,如我们小学常定义的Π值3.1415926,它们提供的值范围也更大也更为精准。当然如果数字很大,以至于无法表示为long类型,如人体的细菌数(估计超过100兆),则可以使用浮点类型来表示。

        使用浮点类型可以表示诸如2.5、3.14159和122442.32这样的数字,即带小数部分的数字。计算机将这样的值分成两部分存储。一部分表示值,另一部分用于对值进行放大或缩小。下面打个比方。对于数字34.1245和34124.5,它们除了小数点的位置不同外,其他都是相同的。可以把第一个数表示为0.341245(基准值)和100(缩放因子),而将第二个数表示为0.341245(基准值相同)和10000(缩放因子更大)。缩放因子的作用是移动小数点的位置,术语浮点因此而得名。C++内部表示浮点数的方法与此相同,只不过它基于的是二进制数,因此缩放因子是2的幂,不是10的幂。幸运的是,初学计算的程序员不必详细了解内部表示(当你学过计组之后就会有详细的认识)。重要的是,浮点数能够表示小数值、非常大和非常小的值,它们的内部表示方法与整数有天壤之别。

二.浮点数的书写

        在c++中浮点数分两种写法:

  • 标准小数点的写法(我们常见的小数写法)

    3.14
    100.45
    99.1
    1.0

  • E表示法(类似于我们常见的科学计数法)

    3.14e3//表示3.14*10^3
    3.14e+3//表示3.14*10^3
    9.11e-31//表示9.11*10^(-31)电子质量,单位千克

E表示方法
​​​

三.浮点数的分类

        和ANSI C一样,C++也有3种浮点类型:float、double和long double。这些类型是按它们可以表示的有效数位和允许的指数最小范围来描述的。有效位(significant figure)是数字中有意义的位。例如,珠穆朗玛峰的高度是8,849米,该数字使用了4个有效位,指出了最接近的高度数。然而,将珠穆朗玛峰的高度写成约8800米时,有效位数为2位,因为结果经过四舍五入精确到了百位。在这种情况下,其余的2位只不过是占位符而已。有效位数不依赖于小数点的位置。例如,可以将高度写成8.849米。这样仍有4个有效位,因为这个值精确到了第4位。

        事实上,C和C++对于有效位数的要求是,float至少32位,double至少48位,且不少于float,long double至少和double一样多。这三种类型的有效位数可以一样多。然而,通常,float为32位,double为64位,long double为80、96或128位。另外,这3种类型的指数范围至少是−37到37。可以从头文件cfloat或float.h中找到系统的限制。以下是float.h的部分代码,关键位置标有中文注释。

//
// float.h
//
//      Copyright (c) Microsoft Corporation. All rights reserved.
//
// Implementation-defined values commonly used by sophisticated numerical
// (floating point) programs.


// Define the floating point precision used.定义使用的浮点精度
/*
FLT_EVAL_METHOD 用来指明在表达式求值(尤其是数学运算)过程中是否需要提升浮点数的类型,可能的取值有:
    -1:未知的,不确定的。

    0:不提升类型,使用当前的类型。

    1:将浮点数提升到 double 类型,大于等于 double 类型的保持不变;也就是说,将 float 类型提升为 double 类型,double 和 long double 类型不变。

    2:将浮点数提升到 long double;也就是说,将 float、double 提升到 long double 类型,long double 类型保持不变。

	【注】FLT_EVAL_METHOD 对所有浮点数类型(float、double 和 long double)都有效,也就是说,所有浮点数类型都必须采用相同的类型提升。提升类型能够提高浮点数的精度,让表达式的结果更加精确。
*/

#ifdef _M_FP_FAST
    #define FLT_EVAL_METHOD -1
#else
    #ifdef _M_IX86
        #if _M_IX86_FP >= 2
            #define FLT_EVAL_METHOD 0
        #else
            #define FLT_EVAL_METHOD 2
        #endif
    #else
        #define FLT_EVAL_METHOD 0
    #endif
#endif


//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
//
// Constants 定义了各种类型的数据的精度,即小数点的位数
//
//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+



    //DBL开头的是double类型的
#define DBL_DECIMAL_DIG  17                      // # of decimal digits of rounding precision
    /*
    从 float/double/long double 转换到至少有 FLT_DECIMAL_DIG/DBL_DECIMAL_DIG/LDBL_DECIMAL_DIG 位数字的十进制,再转换回原类型为恒等转换:这是序列化/反序列化浮点值所要求
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值