当尝试从非类型化缓冲区获取浮点值时,如何防止无效操作?
考虑一个无类型缓冲区,void*
,我从中取出几个字节将它们视为浮点值,float
或 double
。假设我的机器上的浮点值与 IEEE-754 兼容。因此,缓冲区中可能存在不表示任何有效浮点值的二进制序列。尝试对此类填充有无效二进制文件的浮点变量进行操作将导致程序错误。
在这种情况下,如何防止程序中止 - 也就是说,如何获知浮点变量中的无效二进制文件?
ps 从无类型缓冲区中提取浮点的正确方法是什么?我听说联合铸造的技巧
void* buf;
union U {int i; float f;};
U *u = (U*) buf;
u->i = binvalue;
fpvalue = u->f;`
是无效的,即使 buf
正确对齐。
Consider an untyped buffer, void*
, from which I take several bytes to treat them as a floating-point value, float
or double
. Let's assume that floating-point values are IEEE-754 compatible on my machine. Thus, there might be a binary sequence from a buffer that doesn't represent any valid floating-point value. Attempt to operate on such a floating-point variable stuffed with invalid binary would result in a program fault.
How can I guard against a program abort in such a case - that is, how can I get informed about the invalid binary in floating-point variable?
p.s. What is the correct way to extract floating-point from an untyped buffer? I've heard that the trick with union casting like
void* buf;
union U {int i; float f;};
U *u = (U*) buf;
u->i = binvalue;
fpvalue = u->f;`
is invalid, even if buf
is properly aligned.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
问题之一是,在许多系统上,浮点数必须对齐(例如,对齐到 4 字节的倍数地址),而完全任意的指针可能未对齐(并且该指针甚至可以指向未映射的地址,例如,如果它接近 NULL)。
另一个问题是 IEEE 754 浮点数确实定义了信令而不是数字等等。也许使用 isnan 或 isinf 检查浮点值会有所帮助。
最后,IEEE 754 标准非常复杂,并非每个系统都完全实现它。如果您想防止失败,您可能必须编写非常难以移植的代码。虽然我过去确实读过该标准,但我也忘记了血淋淋的细节。
One of the issues is that on many systems, a float has to be aligned (e.g. to an address multiple of 4 bytes), while an entirely arbitrary pointer might be unaligned (and the pointer could even point into an unmapped address, e.g. if it is close to NULL).
The other issue is that IEEE 754 floats indeed define signaling not a number-s and so forth. Maybe checking the float values with
isnan
orisinf
could help.At last, the IEEE 754 standard is so complex that not every system implements it entirely. You probably have to write very unportable code if you want to be failproof. While I did read in the past that standard, I also forgotten the gory detail.