double a=1.0f;
cout<<(int&)a<<endl;
输出为0
在Turbo c 3.0中的结果都为0;在VC 6.0中为1065353216和0 (int)a是把float型强类型化为int类型,所以为0; (int&)a是把a地址的前两字节当成一个int类型数据输出;至于为什么Turbo c 3.0中的结果为0,可能是因为编译器的差异问题。其实(int&)a就是将a转换为int型的引用。如果 int&b=(int&)a; 这样定义的话就好理解了,其实与指针类型转换是一样的。如果a是float型的话输出就不是0了,它将float型的二进制码直接解释为int了。
根据IEEE754的浮点数存储格式: 1.0f 在内存中的存储为 0 011 1111 1 000 0000 0000 0000 0000 0000 亦即 0x3F800000 = (1065353216)10 在TC3.0下的结果是0的原因是: TC30下的int型是2个字节的, 所以读的是float类型的低两个字节内容为0. 在TC3.0下用(long &)将还是此结果。对于double也是一样的道理,和存储有关系,double是64位的,把它转换为实际的存储方式是: 0 011 1111 1111 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 ,这就解释为什么都是0了,vc 6.0下就是低4个字节,为0,同理TC 3.0为低2个字节也为0。
float a = 1.0f;
cout < < (int)a < < endl;
cout < < (int&)a < < endl;
cout < < boolalpha < < ( (int)a == (int&)a ) < < endl; // 输出什么?
float b = 0.0f;
cout < < (int)b < < endl;
cout < < (int&)b < < endl;
cout < < boolalpha < < ( (int)b == (int&)b ) < < endl; // 输出什么?
输出啥?
不明白 (int &)a是啥意识?为啥两个比较的出结果不同。
—————————————————-
cout < < boolalpha < < ( (int)a == (int&)a ) < < endl;
// 输出 false, 因为 float 的 1 和 int 的 1 在内存里的表示不一样。
…
cout < < boolalpha < < ( (int)b == (int&)b ) < < endl; // 输出 true
// 输出 true, 因为 float 的 0 和 int 的 0 在内存里的表示是一样的。
(int &)a 就表示
不管 a 是什么,我都当他是一个int变量。
从机器码的角度来说,变量a会被翻译成一个内存地址,(int &)a 就是说,这个内存地址里的内容它是一个整数。
(int)a 呢不同:如果 a 不是整数,就会按规则转换成整数,存入另一个地址(或临时变量)中去。
浮点数的 1.0f 在内存里是这样表示的:
0011 1111 1000 0000 00000000 00000000
这个32位二进制数被当作整数输出就是:
1065353216
而整数的 1 在内存里是这样表示的:
0000 0000 0000 0000 00000000 00000001
所以 (int)a != (int&)a
浮点的0和整数的0 在内存里都是:
0000 0000 0000 0000 00000000 00000000
所以 (int)b == (int&)b
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <conio.h>
using namespace std;
int main()
{
float a = 1.0f;
cout << sizeof(int) <<endl;//4
cout << sizeof(float) <<endl;//4
cout << (int)a << endl;//1
cout << &a << endl; /* 取a的地址十六进制0012FF7C*/
cout << (int)&a << endl; /*(int)&a:把a的地址强制转换成十进制的整型1245052*/
cout << (int&)a << endl;
/*(int&)a:将a的引用强制转换为整型,意思是a所在的内存,本来定义的时候为float类型,并初始为1.0f,
但现在我要按int类型解释这段内存(也就是说a所在的内存地址中的数据本来是按float型存储表示的,你非要按int型来解释不可)。
1.0f 在内存中的存储为 0011 1111 1000 0000 0000 0000 0000 0000. 把他按整型数解释为2^29+2^28+2^27+2^26+2^25+2^24+2^23=1065353216
(int&)a 相当于*(int*)&a ; *(int*)(&a) ; *((int*)&a)
*/
cout << boolalpha << ((int)a == (int&)a ) << endl;// 输出false.因为1!=1065353216.
float b = 0.0f;
cout << (int)b << endl;//0
cout << &b << endl;/*取b的地址十六进制0012FF78*/
cout << (int&)b << endl;//0
cout << boolalpha << ((int)b == (int&)b ) << endl;// 输出true,因为0==0;
/*
(int&)a 不经过转换, 直接得到a在内存单元(就是地址)的值
(int)a a在内存中的值转换成int类型
float类型在内存中存储的形式是 ,符号位 指数 尾数
由754标准:阶码采用增码(该数补码的反符号),尾数采用原码
所以1.0f 在内存中的形式为
0011 1111 1000 0000 0000 0000 0000 0000
所以输出的是 0x3f800000
0 在内存中的的存储形式
0000 0000 0000 0000 0000 0000 0000 0000
*/
return 0;
}
【参考资料】
========================c语言中FLOAT 是如何表示的===========================
c语言中FLOAT 是如何表示的?尾数,阶码是如何在32位上安排的,即哪几位是尾数,哪几位是阶码,那一位是符号位。听说与CPU有关,是真的吗?
在C++里,实数(float)是用四个字节即三十二位二进制位来存储的。其中有1位符号位,8位指数位和23位有效数字位。实际上有效数字位是24位,因为第
一位有效数字总是"1",不必存储. 有效数字位是一个二进制纯小数。
8位指数位中第一位是符号位,这符号位和一般的符号位不同,它用"1"代表正,用"0"代表负。整个实数的符号位用"1"代表负,"0"代表正。
在这存储实数的四个字节中,将最高地址字节的最高位编号为31,最低地址字节的最低位编号为0,则实数各个部分在这32个二进制位中的分布是这样的:
注意第一位有效数字是不出现在内存中的,它总是"1"。
将一个实数转化为C++实数存储格式的步骤为:
(1)先将这个实数的绝对值化为二进制格式,注意实数的整数部分和小数部分化为二进制的方法是不同的。
(2)将这个二进制格式实数的小数点左移或右移n位,直到小数点移动到第一个有效数字的右边。
(3)从小数点右边第一位开始数出二十三位数字放入第22到第0位。
(4)如果实数是正的,则在第31位放入"0",否则放入"1"。
(5)如果n 是左移得到的,说明指数是正的,第30位放入"1"。如果n是右移得到的或n=0,则第30位放入"0"。
(6)如果n是左移得到的,则将n减去1然后化为二进制,并在左边加"0"补足七位,放入第29到第23位。
如果n是右移得到的或n=0,则将n(不减1)化为二进制后在左边加"0"补足七位,再各位(指这七位)求反,再放入第29到第23位。
或者这么转换:
(1)先将这个实数的绝对值化为二进制格式,注意实数的整数部分和小数部分化为二进制的方法是不同的。
(2)将这个二进制格式实数的小数点左移或右移n位,直到小数点移动到第一个有效数字的右边。
(3)从小数点右边第一位开始数出二十三位数字放入第22到第0位。
(4)如果实数是正的,则在第31位放入"0",否则放入"1"。
(5)如果n 是左移得到的,指数部分为127+n,转换成二进制,放入第30到第23位。
(6)如果n是右移得到的, 指数部分为127-n,转换成二进制,放入第30到第23位。
(7)如果n=0即没有移, 指数部分为127,转换成二进制,放入第30到第23位。
将一个计算机里存储的实数格式转化为通常的十进制的格式的方法如下:
(1)将第22位到第0位的二进制数写出来,在最左边补一位"1",得到二十四位有效数字。将小数点点在最左边那个"1"的右边。
(2)取出第29到第23位所表示的值n。当30位是"0"时将n各位求反。当30位是"1"时将n增1。
(3)将小数点左移n位(当30位是"0"时)或右移n位(当30位是"1"时),得到一个二进制表示的实数。
(4)将这个二进制实数化为十进制,并根据第31位是"0"还是"1"加上正号或负号即可。
特别地,实数0用C++的float格式表示是0000000000000000000000000000000
0。
如果还不太明白,这里举几个例子。
一。将23.56化为C++的float格式。
(1)将23.56化为二进制后大约是"10111.1000111101011100001"。
(2)将小数点左移四位,得到"1.01111000111101011100001"。
(3)这已经有了二十四位有效数字,将最左边一位"1"去掉,得到"01111000111101011100001"。将它放入第22到第0位。
(4)因为23.56是正数,因此在第31位放入"0"。
(5)由于我们把小数点左移,因此在第30位放入"1"。
(6)因为我们是把小数点左移4位,因此将4减去1得3,化为二进制,并补足七位得到0000011,放入第29到第23位。
完毕。
如果把最左边定为第31位,最右边定为第0位,那么在C++里,float格式的23.56是这样表示的:01000001101111000111101011100001。相应地-23.56就是这
样表示的:11000001101111000111101011100001。
二。将实数0.2356化为C++的float格式。
(1)将0.2356化为二进制后大约是0.00111100010100000100100000。
(2)将小数点右移三位得到1.11100010100000100100000。
(3)从小数点右边数出二十三位有效数字,即11100010100000100100000放入第22到第0位。
(4)由于0.2356是正的,所以在第31位放入"0"。
(5)由于我们把小数点右移了,所以在第30位放入"0"。
(6)因为小数点被右移了3位,所以将3化为二进制,在左边补"0"补足七位,得到0000011,各位取反,得到1111100,放入第29到第23位。
完毕。因此0.2356用C++的float格式表示是:00111110011100010100000100100000。其中最左边一位是第31位,最右边一位是第0位。
三。将实数1.0化为C++的float格式。
(1)将1.0化为二进制后是1.00000000000000000000000。
(2)这时不用移动小数点了,这就是我们在转化方法里说的n=0的情况。
(3)将小数点右边的二十三位有效数字00000000000000000000000放入第22到第0位。
(4)因为1.0是正的,所以在第31位里放入"0"。
(5)因为n=0,所以在第30位里放入"0"。
(6)因为n=0,所以将0补足七位得到0000000,各位求反得到1111111,放入第29到第23位。
完毕。所以实数1.0用C++的float格式表示是:00111111100000000000000000000000。其中最左边一位是第31位,最右边一位是第0位。
double同理,只是double是64位。
符号位 阶码 尾数 长度
float 1 8 23 32
double 1 11 52 64
临时数 1 15 64 80
关键是指数部分
float型:31位是实数符号位,30位是指数符号位(127+n、127-n、127),29—23是指数位,22—0位是有效数字位。// 指数占8位
double型:63位是实数符号位,62位是指数符号位(1023+n、1023-n、1023),61—52是指数位,51—0位是有效数字位。// 主指数占11位
分享到:
相关推荐
根据给定文件中的标题、描述、标签以及部分内容,我们可以从中提炼出有关`(int)a`与`(int&)a`的关键知识点。 ### (int)a: 强制类型转换 #### 定义 `(int)a`是一种**强制类型转换**的用法,即将变量`a`的值转换为...
根据给定的信息,本文将详细解释“int triangleJudge(int a,int b,int c)”函数的实现原理及三角形类型的判断逻辑。 ### 函数介绍 #### 函数定义:`int triangleJudge(int a,int b,int c)` 该函数接收三个整数参数...
这里,const 关键字的位置决定了修饰的对象是 int 还是 a。 const 和 extern const 变量可以使用 extern 关键字来扩大其作用域,例如: ```cpp extern const int r = 100; ``` 这里,const 变量 r 的作用域扩大到...
例如,`int &Fun(int a)` 中的`a`是一个引用,它绑定到调用时的实参,对`a`的修改会直接影响到原始变量。引用传递通常用于避免值复制的开销,特别是在处理大型对象或需要修改参数的情况。 4. 函数返回值:返回值、...
int *ptr = (int *)(&a + 1); cout *(a+1) ; cout *(ptr - 1) ; ``` **知识点解析:** - `*(a+1)` 输出数组第二个元素的值,即 `2`。 - `ptr` 指向数组 `a` 的下一个数组的位置。 - `*(ptr - 1)` 实际上是指向 `a` ...
数组名`a`和取地址运算符`&a`之间的区别可能会引发一些混淆,但理解它们的本质可以帮助我们更好地编写和理解C语言程序。 首先,让我们澄清数组名的概念。数组名`a`实际上是数组首元素的地址。这意味着当你使用`a`时...
void aMAX_MIN_AVE(int *a, int n, int &max, int &min, int &aver) { max = min = a[0]; // 初始化 int sum = 0; for (int i = 0; i ; i++) { sum += a[i]; if (a[i] > max) max = a[i]; if (a[i] ) min = a...
本文主要探讨了如何在QString、QByteArray、int和double之间进行转换。了解这些转换方法对于编写Qt应用程序至关重要。 首先,QString是Qt提供的一种用于处理文本字符串的类,支持Unicode字符集。QByteArray则是一个...
分别用三个函数:输入...void time_input(int& hour,int& minute);void time_output(int& hour,int& minte,char& noon);void time_change(int& hour,int& minte,char& noon);int main(){ int hour,minute; char p;
2 双击您下载的驱动程序 驱动会解压缩到硬盘的以下位置:C: DRIVERS WIN INT33A0 3 打开设备管理器 4 展开"其他设备"选项 5 在" 未知设备"上点击升级驱动和软件 6 将驱动更新位置指向第2步解...
6. 编写一个方法search(int a[],int x): 若数组a中存在值为x 的元素,则返回该元素的下标值;否则返回-1。 7. 编写一个方法print_MaxMin(int a[]): 打印出数组a中的最大值和最小值。 8. 编写一个递归方法...
**XINT 库详解** XINT 是一个专为数值计算设计的C语言库,它提供了高效、精确且易于使用的整数运算功能。这个库特别适用于需要处理大整数或者需要高性能计算的场合,比如在密码学、数学建模、数据分析等领域。在本...
cout 局部变量a地址为: " (int)&a ; cout 局部变量b地址为: " (int)&b ; cout 全局变量g_a地址为: " (int)&g_a ; cout 全局变量g_b地址为: " (int)&g_b ; // 静态变量 static int s_a = 10; static int...
编写一个类,该类有一个方法public int f(int a,int b),该方法返回a和b的最大公约数,然后再编写一个该类的子类,要求子类重写方法f,而且重写的方法将返回a和b的最小公倍数,要求在重写的方法的方法体中首先调用被...
`stdint.h` 头文件是C语言编程中用于定义固定宽度整型数据类型的重要标准库。这个头文件在C99标准中被引入,目的是为了提供具有确定大小和符号的整数类型,使得代码可以在不同架构和平台之间具有更好的可移植性。在...
void swap(int &a, int &b) { int temp = a; a = b; b = temp; } 这时,swap 函数可以交换 a 和 b 的值。 3. 引用做函数返回值 引用可以作为函数的返回值,作用是引用是可以作为函数的返回值存在的。但需要...
`vector<int>`和`vector<int*>`看似相似,但在实际使用中有着显著的区别,这主要涉及到内存管理和数据存储方式。 首先,`vector<int>`用于存储整型值。在这种情况下,`vector`会负责元素的内存分配和释放。当你通过...
int *ptr = (int *)(&a + 1); printf("%d,%d", *(a + 1), *(ptr - 1)); /*getchar是用VS编写方便查看输出*/ getchar(); return 0; } 请思考一下上面的输出结果,如果你非常自信了,可以不用往下看 题目剖析 这...