我建议你打印浮点值的位,好像它们是十六进制整数,如下面的代码所示,这样你就可以分析这些位,看看它们是否包含你试图计算的值或者是否被错误地修改了一些bug.
该AVR32CU技术参考手册说:"浮点硬件符合C标准,它是基于IEEE 754浮点标准的要求."后者子句是假的; C标准不是基于IEEE 754.C标准确实指定了对IEEE 754的绑定(通过名称IEC 60559)作为C实现的可选特征.我假设您使用的AVR32 CPU型号在某种程度上符合IEEE 754.
IEEE 754中没有"非法"值.有些值不代表数字,其中一些值旨在导致异常.这样的值称为NaN(对于"非数字").有安静的NaNs和信号NaNs.安静的NaN旨在静默地传递操作,产生NaN结果.例如,3 + NaN
应该生产NaN
.信令NaN旨在导致异常,这可能导致程序控制的更改(例如信号或程序中止).
上面引用的技术参考手册也说"没有提供信令NaN,所有NaN都是非信令(安静)."
一个好的vsnprintf
例程应该接受安静的NaN值进行打印,并且应该通过生成诸如"NaN"的字符串来格式化它们.当传递信令NaN进行格式化时,我认为将其格式化或产生异常可能是合理的.
我希望您从支持中收到的消息表明您的软件创建了某种NaN,并且vsnprintf
无法处理这些消息.从措辞来看,我认为他们的反应是推测性的.
如果您通过汇编字节来创建浮点值,那么如果您的软件中存在某些错误,则可能在您不打算创建NaN时创建了NaN.我建议您通过使用vsnprintf
打印浮点值的字节而不是使用浮点格式说明符打印它来调试它.
如果您使用的GCC版本具有GCC的常用功能,并且unsigned int
在您的实现中是32位,则可以使用以下内容将32位float
值的位格式化x
为十六进制值:
vsnprintf(Buffer, BufferLength, "0x%x",
(union { float f; unsigned int u; }) {x} .u);
Run Code Online (Sandbox Code Playgroud)
第二行使用复合文字将值x
放入联合并将其字节重新解释为unsigned int
.(这是C中一种支持的方式来重新解释对象的字节.许多人使用指针别名,如果使用了适当的标志,它在GCC中工作,但C标准通常不支持它.另一种支持的方法是复制字节,与unsigned int u; memcpy(&u, &x, sizeof u);
.)
一旦看到其中的位float
,您可以从IEEE 754标准中的信息或使用在线分析器手动解释它们.(选择"十六进制"按钮输入要解释的十六进制值.)
在IEEE-754 32位二进制浮点对象中,如果出现以下情况,则该值为NaN:
(如果位30到23都是1但位22到0全为零,则该值为无穷大.这不是非法的,但也可能导致低质量vsnprintf
生成异常.)
归档时间: |
|
查看次数: |
609 次 |
最近记录: |