Redian新闻
>
问题: C++ static_cast between int and float
avatar
i*h
2
需要用一个float存整数:
int i = 0x24240102;
float f = static_cast(i);
std::cout << std::hex << static_cast(f) << std::endl;
结果出来是:
24240100
尾巴上那个02变成00了.
为什么?
avatar
S*I
3
Learn how float numbers are represented in binary forms first, then you'll
understand.

【在 i***h 的大作中提到】
: 需要用一个float存整数:
: int i = 0x24240102;
: float f = static_cast(i);
: std::cout << std::hex << static_cast(f) << std::endl;
: 结果出来是:
: 24240100
: 尾巴上那个02变成00了.
: 为什么?

avatar
t*t
4
你这么老的鸟问这么幼齿的问题不应该啊.

【在 i***h 的大作中提到】
: 需要用一个float存整数:
: int i = 0x24240102;
: float f = static_cast(i);
: std::cout << std::hex << static_cast(f) << std::endl;
: 结果出来是:
: 24240100
: 尾巴上那个02变成00了.
: 为什么?

avatar
i*h
5
被鄙视鸟.
这种东西, 平时用着不出错就用了, 没深入学习过.
理解中就是把这个当memcpy使的, 看来是不对的
整数是0x24240102, 就是
(24) 0010 0100 (24) 0010 0100 (01) 0000 0001 (01) 0000 0010
浮点表示是 1 bit sign, 8 bit exponent, 23 bit significant
上面就变成:
(0) (010 0100 0) (010 0100 0000 0001 0000 0010)
呣... 还是看不出为什么最后的 0010 会变成 0000
求解释

【在 t****t 的大作中提到】
: 你这么老的鸟问这么幼齿的问题不应该啊.
avatar
t*t
6
no, try to google static_cast.

【在 i***h 的大作中提到】
: 被鄙视鸟.
: 这种东西, 平时用着不出错就用了, 没深入学习过.
: 理解中就是把这个当memcpy使的, 看来是不对的
: 整数是0x24240102, 就是
: (24) 0010 0100 (24) 0010 0100 (01) 0000 0001 (01) 0000 0010
: 浮点表示是 1 bit sign, 8 bit exponent, 23 bit significant
: 上面就变成:
: (0) (010 0100 0) (010 0100 0000 0001 0000 0010)
: 呣... 还是看不出为什么最后的 0010 会变成 0000
: 求解释

avatar
F5
7

10

this is from head to toe?


【在 i***h 的大作中提到】
: 被鄙视鸟.
: 这种东西, 平时用着不出错就用了, 没深入学习过.
: 理解中就是把这个当memcpy使的, 看来是不对的
: 整数是0x24240102, 就是
: (24) 0010 0100 (24) 0010 0100 (01) 0000 0001 (01) 0000 0010
: 浮点表示是 1 bit sign, 8 bit exponent, 23 bit significant
: 上面就变成:
: (0) (010 0100 0) (010 0100 0000 0001 0000 0010)
: 呣... 还是看不出为什么最后的 0010 会变成 0000
: 求解释

avatar
S*I
8
If you use double type intead of float, you can get what you want (still not
safe though).

【在 i***h 的大作中提到】
: 被鄙视鸟.
: 这种东西, 平时用着不出错就用了, 没深入学习过.
: 理解中就是把这个当memcpy使的, 看来是不对的
: 整数是0x24240102, 就是
: (24) 0010 0100 (24) 0010 0100 (01) 0000 0001 (01) 0000 0010
: 浮点表示是 1 bit sign, 8 bit exponent, 23 bit significant
: 上面就变成:
: (0) (010 0100 0) (010 0100 0000 0001 0000 0010)
: 呣... 还是看不出为什么最后的 0010 会变成 0000
: 求解释

avatar
i*h
9
也就是说static_cast 读了整数
然后试图把数字用浮点表达, 最后几位因为精度不够被舍弃了
除了用指针或者memcpy(), 还有别的办法把int 的内容直接理解成浮点么?
float f = reinterpret_cast(i);
编译不通过

【在 t****t 的大作中提到】
: no, try to google static_cast.
avatar
b*i
10
float一共就32bit, 其中指数要占用多少位,符号一位,一共就没多少位,最多7位有
效数字吧。这种问题应该自己一看到就明白那种。

【在 i***h 的大作中提到】
: 需要用一个float存整数:
: int i = 0x24240102;
: float f = static_cast(i);
: std::cout << std::hex << static_cast(f) << std::endl;
: 结果出来是:
: 24240100
: 尾巴上那个02变成00了.
: 为什么?

avatar
F5
11
想起来了...任何一本书上都这么写这,6-7位...

【在 b***i 的大作中提到】
: float一共就32bit, 其中指数要占用多少位,符号一位,一共就没多少位,最多7位有
: 效数字吧。这种问题应该自己一看到就明白那种。

avatar
t*t
12
union {
int i;
float f;
};
reinterpret_cast<> is to convert between pointers and integral types. no
float allowed.
using float* to access int* (no matter cast with reinterpret_cast or (type)
cast) is undefined, don't try that. it is subtle and not easy to discover,
but will blow up eventually.

【在 i***h 的大作中提到】
: 也就是说static_cast 读了整数
: 然后试图把数字用浮点表达, 最后几位因为精度不够被舍弃了
: 除了用指针或者memcpy(), 还有别的办法把int 的内容直接理解成浮点么?
: float f = reinterpret_cast(i);
: 编译不通过

avatar
i*h
13
没办法, legacy code, 改API很麻烦
要用已有的data field存新的东西
我也不想玩这种把戏

)

【在 t****t 的大作中提到】
: union {
: int i;
: float f;
: };
: reinterpret_cast<> is to convert between pointers and integral types. no
: float allowed.
: using float* to access int* (no matter cast with reinterpret_cast or (type)
: cast) is undefined, don't try that. it is subtle and not easy to discover,
: but will blow up eventually.

avatar
t*t
14
let me repeat, it's undefined if you do it directly instead of union. it
will backfire. compiler may even IGNORE what you write. if you want to do it
, do it correctly and do it safe, use union.

【在 i***h 的大作中提到】
: 没办法, legacy code, 改API很麻烦
: 要用已有的data field存新的东西
: 我也不想玩这种把戏
:
: )

avatar
i*h
15
看来用union 搞定浮点,
然后把这个浮点放API比较安全
用memcpy也可以吧?

it

【在 t****t 的大作中提到】
: let me repeat, it's undefined if you do it directly instead of union. it
: will backfire. compiler may even IGNORE what you write. if you want to do it
: , do it correctly and do it safe, use union.

avatar
i*h
16
嗯, 用memcpy效率不如union

【在 i***h 的大作中提到】
: 看来用union 搞定浮点,
: 然后把这个浮点放API比较安全
: 用memcpy也可以吧?
:
: it

avatar
a*n
17
int i = 0x24240102;
float f = *reinterpret_cast(&i);
std::cout << std::hex << *reinterpret_cast(&f) << std::endl;
avatar
t*t
18
as i said, this is undefined.

【在 a***n 的大作中提到】
: int i = 0x24240102;
: float f = *reinterpret_cast(&i);
: std::cout << std::hex << *reinterpret_cast(&f) << std::endl;

avatar
h*f
19
casting to void* to trick the compiler not to do anything:
int i = 0x24240102;
float f = *(float*)(void*)(&i);
std::cout << std::hex << *(int*)(void*)&f << std::endl;
avatar
t*t
20
this is undefined as well.

【在 h*****f 的大作中提到】
: casting to void* to trick the compiler not to do anything:
: int i = 0x24240102;
: float f = *(float*)(void*)(&i);
: std::cout << std::hex << *(int*)(void*)&f << std::endl;

avatar
h*f
21
Really?
I thought casting to void* always made it point to the first byte -- defined
behavior, and then casting back also made it point to the first byte --
defined behavior as well.
No?
avatar
t*t
22
casting itself is defined. but using casted pointer to access a different
type of value is undefined, unless certain conditions are met. specifically,
using floating pointer to access integer value, or vice versa, are both
undefined.

defined

【在 h*****f 的大作中提到】
: Really?
: I thought casting to void* always made it point to the first byte -- defined
: behavior, and then casting back also made it point to the first byte --
: defined behavior as well.
: No?

相关阅读
logo
联系我们隐私协议©2024 redian.news
Redian新闻
Redian.news刊载任何文章,不代表同意其说法或描述,仅为提供更多信息,也不构成任何建议。文章信息的合法性及真实性由其作者负责,与Redian.news及其运营公司无关。欢迎投稿,如发现稿件侵权,或作者不愿在本网发表文章,请版权拥有者通知本网处理。