浮点数的比较

liuzu2016 2012-06-20 06:11:51
int val=....;

float val1= * ((float*) val);

float val2=(float)val;

val1 ,val2 相等吗???


...全文
315 26 打赏 收藏 转发到动态 举报
写回复
用AI写文章
26 条回复
切换为时间正序
请发表友善的回复…
发表回复
Joseph-Growth 2012-07-11
  • 打赏
  • 举报
回复
从结果倒着看,可以断定Test2只识别了int类型。很有可能跟编译器有关。也贴一个我的好奇
#include "iostream.h"
struct Test2
{
typedef int int32;
};
void main()
{
cout << sizeof(Test2) << endl;
}
结果是1.
ken_scott 2012-06-23
  • 打赏
  • 举报
回复
[Quote=引用 21 楼 的回复:]
我也不记得之前在什么书上看到过的这种写法,也不知道这符不符合C的标准,符不符合C++的标准...
[/Quote]
依据用途来分析的话:
C中可能会有这种东西: 因为如果在C中定义一个内部struct/union类型而没有对象, 这是没有任何意义的行为;
C++中则可能没有这种东西, 因为在C++中定义的内部struct/union类型, 可能在外部的类型的成员函数中用到.
具体是否为标准语法, 要去相应的标准资料.
N0bug 2012-06-21
  • 打赏
  • 举报
回复
我是说你这套理论。。。来自什么书或者手册吗?
[Quote=引用 14 楼 的回复:]
出处是:
union中最大的类型是char 数组,所以是整个union是8


vs2010下,

一个结构体的起始地址是偶数开始,整个是 cpu寻址。

把整个union看做一个整体放在结构体中。。。

由于其是8,那么 他在结构体中的起始地址就是8的倍数。
//我怀疑的就是这个话........ 到底是什么规定了这一点

比如一个int在 结构体中的其实地址,是4的倍数。

float也是4

short int 是2

……
[/Quote]
liuzu2016 2012-06-21
  • 打赏
  • 举报
回复
出处是:
union中最大的类型是char 数组,所以是整个union是8


vs2010下,

一个结构体的起始地址是偶数开始,整个是 cpu寻址。

把整个union看做一个整体放在结构体中。。。

由于其是8,那么 他在结构体中的起始地址就是8的倍数。

比如一个int在 结构体中的其实地址,是4的倍数。

float也是4

short int 是2

这个你应该懂的



vs2010默认一个结构体是8的倍数。。。。但union不是。。。


如果在结构体中嵌套结构体,那么该这么计算:

讲 内存结构体展开,和本结构体中的成员 来 做 字节对齐。。

但是union不一样,作为一个整体,然后和本结构体中的成员,进行自己对齐。




[Quote=引用 13 楼 的回复:]

引用 12 楼 的回复:
struct Test2
{
int b;
char cc;
int arr[5];
union Test
{
int a;
char c[8];
float d;
}u;
float dd;



};



int main()
{
cout<<sizeof(Test2)<<endl;
return 0;
}

……
[/Quote]
赵4老师 2012-06-21
  • 打赏
  • 举报
回复
VC调试(TC或BC用TD调试)时按Alt+8、Alt+6和Alt+5,打开汇编窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应内存和寄存器变化,这样过一遍不就啥都明白了吗。
对VC来说,所谓‘调试时’就是编译连接通过以后,按F10或F11键单步执行一步以后的时候,或者在某行按F9设了断点后按F5执行停在该断点处的时候。
(Linux或Unix下可以在用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。)
想要从本质上理解C指针,必须学习汇编以及C和汇编的对应关系。
从汇编的角度理解和学习C语言的指针,原本看似复杂的东西就会变得非常简单!
指针即地址。“地址又是啥?”“只能从汇编语言和计算机组成原理的角度去解释了。”

提醒:
“学习用汇编语言写程序”

“VC调试(TC或BC用TD调试)时按Alt+8、Alt+6和Alt+5,打开汇编窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应内存和寄存器变化,这样过一遍不就啥都明白了吗。
(Linux或Unix下可以在用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。)
想要从本质上理解C指针,必须学习C和汇编的对应关系。”
不是一回事!

不要迷信书、考题、老师、回帖;
要迷信CPU、编译器、调试器、运行结果。
并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。
任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实!

不要写连自己也预测不了结果的代码!
nice_cxf 2012-06-21
  • 打赏
  • 举报
回复
这根本是2回事,一个是把内存数据作为float格式,另外一个是把整型强制转换为为float
ljhhh0123 2012-06-21
  • 打赏
  • 举报
回复
尽量不要用强制类型转换,除非你确实知道你在干什么!
qq120848369 2012-06-21
  • 打赏
  • 举报
回复
好一个扯, 楼主被误导的一塌糊涂.
cbzjzsb123 2012-06-21
  • 打赏
  • 举报
回复
字节对齐
ken_scott 2012-06-21
  • 打赏
  • 举报
回复
[Quote=引用楼主 的回复:]
val1, val2 相等吗???
[/Quote]
先看代码:

#include <iostream>
using namespace std;

int main()
{
int i = 0x1234;
// float val1 = *(float *)i; /* code1 */
float val2 = (float)i; /* code2 */
float val3 = *(float *)&i; /* code3 */
cout << val2 << endl;
cout << val3 << endl;
return(0);
}

请看code 1 2 3:
code1的意思是:找到0x1234那个地址,以它为头,取sizeof(float)长,解析出一个float值,赋给val1;
code2的意思是:将0x1234赋给val2的整数部分,小数部分赋0 (大致这么理解吧)
code3的意思是:找到i的地址,取sizeof(float)长,解析出一个float值,(我们知道,在那个地址上,取sizeof(int)长,解析出一个int值的话,会是0x1234)

code2与code3得到的结果一般是不等的(大多数情况下),也有相等的情况,比如(i = 0)时。
code1与code2/code3则毫无可比性.

一家之言,不可全信。
ken_scott 2012-06-21
  • 打赏
  • 举报
回复
关于字节对齐问题,可以看看我原来发的这个帖子:
http://topic.csdn.net/u/20110831/16/de4771ee-071f-4de2-a31d-e83c38e7ed30.html
ken_scott 2012-06-21
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 的回复:]
sizeof(Test2)结果是4,为什么????
[/Quote]
首先这种写法,叫"无名struct/union"(这里的无名指的是对象无名):

struct S {
char c;
union { /* 无名 */
int i;
double d;
}; /* 无对象 */
};

我也不记得之前在什么书上看到过的这种写法,也不知道这符不符合C的标准,符不符合C++的标准,
好处是我们可以这样用:
S s;
s.c = '.';
s.i = 100;
s.d = 3.1;
你还可以正常输出s.c(.), s.i(不再是100了), s.d(3.1),这说明,默认是会在S中存在一个无名的union的对象的,大四时在CFree上这么做过一个小东西,用Dev-C++刚不可以,听说gcc也可以,没试

S中的union占不占空间,就看编译器会不会在S中加一个无名的union对象

下面是我刚找的一个帖子,好像这种写法是不符合标准的,具体不清楚是不是真的:
http://bbs.chinaunix.net/thread-1284967-1-1.html
不过,既然很多编译器不支持这种写法(暂不管它标不标准了),为了可移植性,我们也不应该这么写!

如果你执意看重它的那"点"好处。也是可以在现有标准的代码方式下,自己来实现的:

#include <iostream>
using namespace std;

struct S {
char c;
union { /* 无名 */
int i;
double d;
} u; /* 现在我们显式地定义对象 */
/* 下面两行就是我们的魔法了 */
#define i u.i
#define d u.d
};

int main()
{
S s;
cout << sizeof(s) << endl;
s.i = 100;
cout << s.i << endl;
return(0);
}

上面两行,模仿了socket中的sockaddr_t(不记得是不是这个了? 反正是套接字相关的某个类型的定义)

类似上面那种花哨的技巧,仅供娱乐,不可用于现实工作项目中!
ForestDB 2012-06-21
  • 打赏
  • 举报
回复
int val=....;
float val1= * ((float*) val);
float val2=(float)val;
val1 ,val2 相等吗???

照LZ的写法,铁定的segmentation fault,因为val是个野指针。
如果这样写:
int val = ...;
float val1 = *((float *)&val);
float val2 = (float)val;
val1和val2是不等的。
前者是将int的字节用float来解释,后者只是简单的cast。
N0bug 2012-06-20
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 的回复:]
struct Test2
{
int b;
char cc;
int arr[5];
union Test
{
int a;
char c[8];
float d;
}u;
float dd;



};



int main()
{
cout<<sizeof(Test2)<<endl;
return 0;
}


这个是40

诡异 啊
……
[/Quote]我已经回帖说明了,结构体成员变量占空间大小没有任何公式,而且除了一些菜逼出的试题会考这个,否则很难在实际工作中直接使用(如果为了压缩空间,要在对应的编译器上做实验)。
对于本题的执行结果,起码可以推断“union的大小是8,其地址必须是8的偶数倍”话不妥。
1.没必要是8的偶数倍
2.没必要是8的倍数
另外求证“union的大小是8,其地址必须是8的偶数倍”的出处。
liuzu2016 2012-06-20
  • 打赏
  • 举报
回复

struct Test2
{
int b;
char cc;
int arr[5];
union Test
{
int a;
char c[8];
float d;
}u;
float dd;



};



int main()
{
cout<<sizeof(Test2)<<endl;
return 0;
}


这个是40

诡异 啊


个人认为:

4+1+3(空)+5*4+4(空)+8+4
arr[5]和Test::a之间插入4个空, 原因是:
union的大小是8,其地址必须是8的偶数备








[Quote=引用 9 楼 的回复:]

引用 2 楼 的回复:
再贴一个问题:


C/C++ code


struct Test2
{
int b;
union Test
{
int a;
char b[8];
};


};
sizeof(Test2)结果是4,为什么????
在vs2010下



union Test3
{
int ……

你其中的联合只是定义并没有实例……
[/Quote]
N0bug 2012-06-20
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 的回复:]
引用 7 楼 的回复:
引用 2 楼 的回复:

再贴一个问题:

C/C++ code

struct Test2
{
int b;
union Test
{
int a;
char b[8];
};


};
sizeof(Test2)结果是4,为什么????
在vs2010下



union Test3
{
int a;
char b[8……
[/Quote]错别字:“数组”->“成员变量”
N0bug 2012-06-20
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 的回复:]
引用 2 楼 的回复:

再贴一个问题:

C/C++ code

struct Test2
{
int b;
union Test
{
int a;
char b[8];
};


};
sizeof(Test2)结果是4,为什么????
在vs2010下



union Test3
{
int a;
char b[8];
};
s……
……
[/Quote]结构体数组排布基本没有什么公式,面试宝典之流解答完全是误人子弟。我们只能就题论题的说这个结构大概(可能、也许、推测)是个什么样。
N0bug 2012-06-20
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 的回复:]
再贴一个问题:


C/C++ code


struct Test2
{
int b;
union Test
{
int a;
char b[8];
};


};
sizeof(Test2)结果是4,为什么????
在vs2010下



union Test3
{
int ……
[/Quote]
你其中的联合只是定义并没有实例化,所以它不占据空间,不信你试试下面的代码:
#include <iostream>


using namespace std;

struct Test2
{
int b;
union Test
{
int a;
char c[8];
}u;


};

union Test
{
int a;
char b[8];
};

int main()
{

cout<<sizeof(Test2)<<endl;
cout<<sizeof(Test)<<endl;
return 0;
}
liuzu2016 2012-06-20
  • 打赏
  • 举报
回复
楼上是错误的, 你试试,无论实例化否,都一样
Joseph-Growth 2012-06-20
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 的回复:]

再贴一个问题:

C/C++ code

struct Test2
{
int b;
union Test
{
int a;
char b[8];
};


};
sizeof(Test2)结果是4,为什么????
在vs2010下



union Test3
{
int a;
char b[8];
};
s……
[/Quote]
union类型在结构体中只声明,没有定义。好像编译器不认为他存在实体。然后就没有大小了。如果Test2给一个实体的话,大小就变成了12.看样子貌似应该是8和4.还是等着高手来解答吧。
加载更多回复(6)

69,322

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧