首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >非法浮动值

非法浮动值
EN

Stack Overflow用户
提问于 2013-12-09 11:32:32
回答 2查看 983关注 0票数 5

我目前正在开发一个嵌入式微控制器,并使用自定义printf例程。工具链是用于AVR32体系结构的GCC工具链。

我遇到的问题是,当第二次调用vsnprintf或类似程序时,CPU进入异常状态。

我从支持中得到的答复是:

我们找不到任何明显的理由做出这样的行为。但是,通过逐字节写入创建浮点溢出条件是不安全的。我们无法确保由此产生的值,建议使用“FLT_MAX”进行检查。

现在我在想:什么是“非法”浮动值?难道不应该所有的位组合至少代表一些值吗?如果相关的话: sizeof(float)是4个字节。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-12-09 13:01:22

摘要

我建议您像打印十六进制整数一样打印浮点值,如下面的代码所示,这样您就可以对这些位进行分析,看看它们是否包含您试图计算的值或由于某些错误而被错误修改的值。

详细信息

AVR32CU技术参考手册说:“浮点硬件符合基于IEEE754浮点标准的C标准的要求。”后一条是错误的,C标准不是基于IEEE754。C标准确实指定绑定到IEEE754(通过名称IEC 60559)作为C实现的一个可选特性。我假设您使用的AVR32 CPU模型在某种程度上符合IEEE754。

IEEE 754中没有“非法”值。有些值不表示数字,其中一些值的目的是导致异常。这样的值被称为NaN (表示“不是数字”)。有安静的NaNs和信号NaNs。安静的NaN打算默默地通过操作,产生一个NaN结果。例如,3 + NaN应该生产NaN。信令NaNs的目的是导致异常,这可能会导致程序控制的更改(例如信号或程序中止)。

上面引用的技术参考手册还说:“信令NaN不提供,所有的NaN都是非信令的(安静)。”

一个好的vsnprintf例程应该接受安静的NaN值进行打印,并通过生成一个字符串(如“NaN”)来格式化它们。当传递信令NaN进行格式化时,我认为格式化它或产生异常可能是合理的。

我希望您从支持中得到的信息是,您的软件创建了某种NaN,而vsnprintf无法处理这些问题。从措辞上看,我认为他们的反应是推测性的。

如果您正在通过组装字节来创建浮点值,那么如果您的软件中有一些错误,那么您可能在不打算创建浮点值的时候创建了一个NaN。我建议您使用vsnprintf来打印浮点值的字节,而不是用浮点格式说明符打印它。

如果您使用的GCC版本具有GCC的通常特性,并且实现中的unsigned int为32位,则可以使用以下方法将32位floatx的位格式化为十六进制值:

代码语言:javascript
复制
vsnprintf(Buffer, BufferLength, "0x%x",
    (union { float f; unsigned int u; }) {x} .u);

第二行使用复合文本将值x放入一个联合中,并将其字节重新解释为unsigned int。(这是C语言中支持的重新解释对象字节的方法。许多人使用指针混叠,如果使用适当的旗子,这在GCC中是有效的,但它一般不受C标准的支持。另一个受支持的方法是复制字节,就像对unsigned int u; memcpy(&u, &x, sizeof u);一样。)

一旦您看到了float中的位数,就可以从IEEE754标准中的信息或使用在线分析仪来手动解释它们。(选择“十六进制”按钮输入要解释的十六进制值。)

在IEEE-754 32位二进制浮点对象中,如果:

  • 位31有任何价值。(这是符号位,与识别NaN无关。)
  • 第30至23位都是第一位。
  • 位22到0并不都是零。

(如果位30至23都是1,而位22至0都是零,则该值为无穷大。这不是非法的,但也可能导致低质量的vsnprintf生成异常。)

票数 5
EN

Stack Overflow用户

发布于 2013-12-09 12:04:34

我没有在AVR32上工作,但是“非法”浮点数,通常情况下,浮点数(单精度算法)是数字方法中的重要话题。浮动的最大数目是:

代码语言:javascript
复制
FLT_MAX = 3.40282e+38

但浮点数也有浮动值的限制。您越接近于零,可以指定的浮点数越多。

例如:

1,2之间的最小值是1.19209e-07 (它是2^-23),也称为砍刀(机器感受器( FLT_EPSILON ),从float.h )。

2,4之间的最小值是2 * 1.19209e-07 = 2 * 2^-23,它也适用于oder端: 1/2,1之间的最小值是2^-24

为什么会发生这种事?让数字定义为beforedot.afterdot

较大的数字是,需要更多位才能写入beforedot数字,而对于较少的数字则需要进行测量。

最后:

Min:1.0842e-19

最大浮点数:3.40282e+38

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20469565

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档