zoukankan      html  css  js  c++  java
  • 小数常量数据的一个有意思的问题

    最近看网上帖子时,看到一位网友提到的一个有意思的问题:

    int main()
    {
    float a;
    a=1.1;
    }
    当我编译这样一段程序,VC会提示:warning C4305: '=' : truncation from 'const double ' to 'float '。
    经过百度,原来“在C语言中,如果不指定数据类型,那么小数常量会被认为是 double 类型”。
    a是float,而1.1是double。 double 不能隐式转换为 float ,所以才会产生这个warning。
    可是!!当我将1.1改为1.5,再次编译,编译器却没有提示warning!(我又再次把1.5改为10.5,编译后仍然没提示warning)
    我发现:凡是类似于X.5这种形式的常量都不会提示warning。

    首先,需要说明的是,在C/C++中,以小数形式给出的数据常量,如果不加特别说明,都认为是double型数据

    此处涉及到小数数据从十进制到2进制的一个转换。比如:

    十进制的1.5,其在2进制中表示就是1.1,这个数值大小既可以在float的精度内准确表示也可以在double的精度内准确表示,因此,在语句:

    float a = 1.5; 中,不会出现对数据的截断(truncated)。

    而对于十进制的数值1.1,1.3,其表示成二进制小数时,位数是无限循环的。例如1.1的二进制表示应该为:1.000110001100011………….

    对于语句:float a = 1.1;

    编译器在执行该语句的时候,会首先将数值1.1转换成二进制下符合double精度的表示值(此处应该也可能会存在截断问题,因为1.1二进制表示是无线循环的),且此处1.1的二进制表示值应该会填满double型数据的所有位。故而在向低精度的float型数值做转换的时候会存在截断。

    拓展:如果有如下的一条蛋疼的语句:

    double testdouble= 1.11111111111111111111111113333333333333333333333;

    cout<<testdouble<<endl;

    输出时会发现testdouble=1.11111,而且这里编译器不会有warning。这里的解释应该是常量值1.11111111111111111111111113333333333333333333333在编译器将其视作const double型数据时,就已经产生了截断,因为计算机double型没有那么高的精度来保存这么多位数,故而最终只保存了1.11111这个值,但是编译器对于这种截断不会报错或者警告。

  • 相关阅读:
    Generator函数介绍
    C语言基础三
    C语言基础二
    C语言基础一
    node——路由控制
    Node.js_HTTP模块
    node_Express安装及检验
    conda Pyhon版本切换
    JAVA泛型里面各值代表的意义
    jq实现表格多行列复制
  • 原文地址:https://www.cnblogs.com/jiayouwyhit/p/3248504.html
Copyright © 2011-2022 走看看