• 关于float


     1 #include <iostream>
     2 using namespace std;
     3 
     4 void main()
     5 {
     6     float a = 1.0f;
     7     cout << (int)a << endl;
     8     cout << (int&)a << endl;
     9     cout << boolalpha << ((int)a == (int&)a) << endl;
    10     float b = 0.0f;
    11     cout << (int)b << endl;
    12     cout << (int&)b << endl;
    13     cout << boolalpha << ((int)b == (int&)b) << endl;
    14 }
    View Code

    这个题非常好,考查浮点数在计算机中的表示。

    现在一般的计算机浮点数都是使用IEEE754标准,可到如下网站恶补:

    https://en.wikipedia.org/wiki/IEEE_754-1985

    通过查看IEEE754标准可知,单精度浮点数的表示为:

    1位表示符号位,8位表示指数位(需加127的指数偏移),23位表示尾数位

    所以 0.1562510 = 0.00101_2 = 1.01_2 	imes 2^{-3} 在计算机中的表示为

    这样,上例中的浮点数 float a = 1.0f在计算机中的表示为

    1.0 = 1.0x20

    符号位    -> 0

    指数部分 -> 0+127 = 01111111

    尾数部分 -> 0

    即 0011 1111 1000 0000 0000 0000 0000 0000 = 0x3f800000

    所以

    cout << (int)a << endl;

    编译器的做法是取整数部分,即尾数部分1x2(127-127)=1

    cout << (int&)a << endl;

    编译器对引用的做法与强制类型转换又不一样,(int&)a相当于*(int*)&a,所以编译器并没有经过上述运算,直接将这个浮点数当作int类型来对待,故输出0x3f800000 = 1065353216。

    所以其实引用与指针很相似,只不过不分配存储空间,且一经初始化就不可以再更改而已。它在传参时同样高效。

    而float b = 0.0f是正0

    在计算机中的表示为全0

    即 0000 0000 0000 0000 0000 0000 0000 0000

    所以cout << (int)b << endl; cout << (int&)b << endl;的结果都为0

    =================================================================================================================

    在论坛还看到一个例子,也很好

    1 #include "stdio.h"
    2 int main(void)
    3 {
    4     float a;
    5     int b;
    6     a=222222222;
    7     b=(int)a;   
    8     printf("%d",b);
    9 }
    View Code

    问题为:

    输出结果为什么会是222222224而不是222222222。

    高手的解答很详细:

    这个问题需要一步一步来解释:

    我们先看看单精度浮点数的格式:
    31 30...23 22...0,bit[31]表示符号位,bit[30...23]表示指数位,bit[22...0]表示尾数位。还有一个默认的整数部分为1。

    1. float a = 222222222.
    222222222 
    => 0b 1101 0011 1110 1101 0111 1000 1110 总共28个bit需去掉4位
    => 1.101 0011 1110 1101 0111 1000 1110 提取整数部分
    => 1.101 0011 1110 1101 0111 1001 [1110]去掉多余的部分且经过了round
    开始组合
    符号位:0
    指数位:27+127(单精度偏置数)= 154= 0b 1001 1010
    尾数位:0b 101 0011 1110 1101 0111 1001
    最终结果:0b 0 1001 1010 101 0011 1110 1101 0111 1001
    上面的结果就是a这个浮点数在内存中的二进制表示。

    2. int b = (int)a.
    0b 0 1001 1010 101 0011 1110 1101 0111 1001
    => 1.101 0011 1110 1101 0111 1001 乘以 2^27
    => 0b 1101 0011 1110 1101 0111 1001 0000 正数
    => 222222224

     =================================================================================================================

    与上类似,double型的数也按上述规则转化,只不过数据长度稍有不同,如下:

    以double 3.5为例:

    3.510 = 11.12 = 1.112 x 2 1

    =>

    符号位    -> 0

    指数部分 -> 1+1023 = 100 0000 0000

    尾数部分 -> 11 -> 11 0000 ...

    组合起来即为 0100 0000 0000 1100 ... = 0x400c0000 00000000

    little endian的计算机表示为 00 00 00 00 00 00 0c 40

  • 相关阅读:
    Python round() 函数
    Python pow() 函数
    图像角点检测
    计算机视觉解析力
    空间点像素索引(三)
    空间点像素索引(二)
    空间点像素索引(一)
    相机标定实用方案
    摄像头的主要参数
    多篇开源CVPR 2020 语义分割论文
  • 原文地址:https://www.cnblogs.com/witxjp/p/4964910.html
Copyright © 2020-2023  润新知