float a=1.0f在内存中的表示是3f800000,这个3f800000是怎么得出的(转)

3f800000H=0 01111111 00000000000000000000000B

符点型数据在X86机上占四个字节,其存储按IEEE754标准实现,即:
1位的符号位s         0(代表正数,1代表负数)
8位的指数位e(移码表示)01111111是0的移码  //这个对吗???(对的,须减去127才是真正的指数)
参考链接:http://blog.chinaunix.net/uid-20937170-id-3396073.html
	http://www.cnblogs.com/jillzhang/archive/2007/06/24/793901.html
23位的小数位f  0000000000000000000000 表示小数部分为0
计算机在表示符点数时,要将10进制数转成二进制的规范数形式进行存储的。即:1.f*2^e在存储时,小数前面的1是隐式存储的,不体现在数据中。
现在翻译一下:
1.f*2^e 指的是二进制。
3f800000H=1.0*2^0=1.0
给你一个比较标准的答复: 浮点数转化为整数时,是取整,而化为整数引用时 (int&)a 相当于 *(int*)&a。 所以 float a=1.0f; (int)a 和 (int&)a 是不同的,1.0f在内存中是 3F800000,作为int看待的话是1065353216,所以(int)a等于1,(int&)a等于1065353216。 而之所以当b=0.0f时,(int)b 和 (int&)b 相等,是因为0.0f和0的内存布局正好一致,都是 00000000。
 
 
 
 
移码 :普及一下
计算机中的移码
用补码表示阶码的时候,当阶码无限小,产生了下溢的时候,阶码变成了0,那么这个浮点数的值变为了1。
而实际上这个数是无限接近于零的。那么我们就需要取出其中的 "-0“ 值作为机器零,于是移码产生了。
移码(又叫增码)是符号位取反的补码,一般用做浮点数的阶码,引入的目的是为了保证浮点数的机器零为全0。
①移码的定义:设由1位符号位和n位数值位组成的阶码,则 [X]移=2En + X -2n≤X ≤ 2n
例如: X=+1011 [X]移=11011
X=-1011 [X]移=00101
②移码与补码的关系: [X]移与[X]补的关系是符号位互为相反数(仅符号位不同),
例如: X=+1011 [X]补=01011 [X]移=11011
X=-1011 [X]补=10101 [X]移=00101
③移码运算应注意的问题:
◎对移码运算的结果需要加以修正,修正量为2En ,即对结果的符号位取反后才是移码形式的正确结果。
◎移码表示中,0有唯一的编码——1000…00,当出现000…00时(表示-2En),属于浮点数下溢。
//。上面的这种理解好像不太正确
看下文

单精度浮点数: 1位符号位   8位阶码位   23位尾数

双精度浮点数: 1位符号位   8位阶码位   52位尾数

 

实数在内存中以规范化的浮点数存放,包括数符、阶码、尾数。数的精度取决于尾数的位数。比如32位机上float型为23位       double型为52位。

单精度float型存储在内存中的大小为4个字节,即32位。

浮点表示的一般形式为:R=M*2^e (R:Real       M:Mantissa尾数     e:exponent阶码)

把上面float的二进制可分成三部分:

   x                   xxxxxxxx             xxxxxxxxxxxxxxxxxxxxxxx

数符(1b)         阶码(8b)         尾数(23b)

double型的浮点数分别是:数符(1b)、阶码(8b)、尾数(52b)

数符sign:real的正负号     "+":0        "-":1

阶码e:e=E-127(double型中e=E-1023) e为正值说明这个浮点数向左移动了e位, e为负值说明这个浮点数向右移动了e位。127=2^7-1 1023=2^10-1

尾数M:有效数字位,这里是有效数字位的部分二进制码

例1:float型浮点数125.5转化成32位二进制浮点数

125.5的二进制码为1111101.1,写成二进制的科学计数为:1.111101*2^6(因为科学计数法“整数”部分大于1,在二进制中,“整数”部分只能恒为1)即向左移6位,则e=6,则E=e+127=133,而E的二进制码为10000101,而1.111101把“整数”部分去除1之后为111101,之后补0,共23b,形成了阶码。

所以125.5的32位二进制浮点数为

0 10000101 11110100000000000000000

例2:float型浮点数0.5转化成32位二进制浮点数

0.5的二进制码为0.1,写成二进制的科学计数为:1.0*2^(-1)即向右移1位,则e=-1,则E=e+127=126,而E的二进制码为01111110,而1.0把“整数”部分去除1之后为0,之后补0,形成了阶码。

 

所以0.5的32位二进制浮点数为

0 01111110 00000000000000000000000

double型浮点数类似。

例3:32位二进制浮点数为0 10000010 00010000000000000000000转化成十进制数浮点数

题中已给我们分了三部分,数符部分、阶码部分、尾数部分。

数符部分为0,则代表此数为正数;阶码部分为10000010,则E=130,则e=E-127=3,则说明其向左移了3位,0001加上“整数”部分的1之后,为1.0001。则原二进制数为1000.1=十进制8.5,或R=1.0001*2^3=8.5

其中很多计算类似。可举一反三!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
由于缺乏具体的需求和语言限制,本文将提供一个基于C++和CSGL库的简单的3D地形绘制示例程序。该程序将读取一个高程数据的DEM文件,并将其换为一个网格模型,然后使用CSGL库来显示该模型。 首先,需要下载和安装CSGL库。在编写程序前,请确保已经熟悉了C++编程语言和OpenGL的基础知识。 以下是一个简单的程序示例: ```cpp #include <iostream> #include <fstream> #include <cstring> #include <cstdlib> #include <csgl/csgl.h> using namespace std; const int MAX_VERTEX = 1000000; // 顶点数上限 const int MAX_FACE = 1000000; // 面数上限 struct Point { float x, y, z; }; struct Face { int a, b, c; }; int main(int argc, char **argv) { if (argc != 2) { cout << "Usage: " << argv[0] << " <dem_file>" << endl; return 1; } // 读取DEM文件 ifstream fin(argv[1]); if (!fin.good()) { cout << "Failed to read file: " << argv[1] << endl; return 1; } // 获取DEM尺寸 int width, height; fin >> width >> height; // 读取DEM数据 float *data = new float[width * height]; for (int i = 0; i < width * height; i++) { fin >> data[i]; } // 生成顶点和面 Point *vertices = new Point[width * height]; Face *faces = new Face[(width - 1) * (height - 1) * 2]; int vertexCount = 0; int faceCount = 0; for (int j = 0; j < height; j++) { for (int i = 0; i < width; i++) { vertices[vertexCount].x = i; vertices[vertexCount].y = j; vertices[vertexCount].z = data[j * width + i]; vertexCount++; if (i < width - 1 && j < height - 1) { faces[faceCount].a = j * width + i; faces[faceCount].b = j * width + i + 1; faces[faceCount].c = (j + 1) * width + i + 1; faceCount++; faces[faceCount].a = j * width + i; faces[faceCount].b = (j + 1) * width + i + 1; faces[faceCount].c = (j + 1) * width + i; faceCount++; } } } // 释放DEM数据内存 delete[] data; // 创建模型 CSGLModel *model = csglModelCreate(); model->numVertices = vertexCount; model->vertices = new float[vertexCount * 3]; memcpy(model->vertices, vertices, vertexCount * sizeof(Point)); model->numFaces = faceCount; model->faces = new int[faceCount * 3]; for (int i = 0; i < faceCount; i++) { model->faces[i * 3] = faces[i].a; model->faces[i * 3 + 1] = faces[i].b; model->faces[i * 3 + 2] = faces[i].c; } // 释放顶点和面内存 delete[] vertices; delete[] faces; // 初始化CSGL库 csglInit(argc, argv); // 创建窗口 csglCreateWindow("3D Terrain", 800, 600); // 设置投影矩阵 glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(75.0, 800.0 / 600.0, 0.1, 1000.0); // 设置模型视图矩阵 glMatrixMode(GL_MODELVIEW); glLoadIdentity(); gluLookAt(0.0, 0.0, 10.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0); // 设置光照 glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); GLfloat lightPos[] = {0.0, 0.0, 1.0, 0.0}; glLightfv(GL_LIGHT0, GL_POSITION, lightPos); // 设置材质 GLfloat matAmbient[] = {0.5, 0.5, 0.5, 1.0}; GLfloat matDiffuse[] = {0.8, 0.8, 0.8, 1.0}; GLfloat matSpecular[] = {1.0, 1.0, 1.0, 1.0}; GLfloat matShininess[] = {100.0}; glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, matAmbient); glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, matDiffuse); glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, matSpecular); glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, matShininess); // 显示模型 csglDisplayModel(model); // 进入消息循环 csglMainLoop(); // 释放模型内存 csglModelDestroy(model); return 0; } ``` 该程序将使用命令行参数来指定输入的DEM文件。程序将读取DEM数据并换为一个网格模型,然后使用CSGL库来显示该模型。 在主函数,程序首先检查命令行参数的数量。如果参数数量不正确,则打印用法信息并返回错误代码。然后,程序打开指定的DEM文件并读取其尺寸和数据。接下来,程序将生成顶点和面,并使用CSGL库来创建一个模型对象。 在初始化CSGL库后,程序将创建一个窗口并设置投影矩阵和模型视图矩阵。程序还将启用光照和设置材质。最后,程序将显示模型并进入消息循环,直到用户关闭窗口。在退出循环后,程序将释放模型内存并返回0。 该程序仅仅是一个简单的示例,可以根据具体需求进行修改和扩展。例如,可以添加用户交互功能,使用户能够旋和缩放模型。可以使用更复杂的材质和光照设置来增强模型的真实感。可以使用其他库来读取DEM数据,例如GDAL或OpenCV。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值