c - 嵌入式应用中浮点除零的高效校验

标签 c performance embedded division zero

对于微 Controller 上的嵌入式 SW 应用程序,我必须为 float 编写某种自定义除法运算符。下面简要介绍了我想要采用的解决方案。

事实上,对于具有高性能要求的嵌入式应用程序,我不确定这种方法在执行时间方面是否足够有效。

有没有人有过处理 float 被零除的不同方法的经验,这对于嵌入式应用程序是有效的/优化的?

typedef union MyFloatType_
{
   unsigned long  Ulong;
   float          Float;
}MyFloatType;

float div_float(float a, float b)
{ 
   float numerator = a;
   MyFloatType denominator;
   denominator.Float= b;
   float result = 0.0f;

   if((denominator.Ulong & 0x7fffffffUL) != 0UL)
   {
      result = numerator / denominator.Float;

   } else 
   {
       /*handle devision by zero, for example:*/
       result = 0.0f;
   }
return result;
}

最佳答案

在大多数应用程序中,会有一些值,低于该值的 float “也可能”为零。例如,考虑如下内容:

float intensity(float dx, float dy)
{
  float result = 1/(dx*dx + dy*dy);
  if (result > 65535.0f) result = 65535.0f;
  return result;
}

如果除数小于 1/65535.0f,则在距离不完全为零的情况下,无论除数的实际值如何,函数都应返回 65535.0f,这种行为可能很有用,即使它为零。因此,该函数可以重写为:

float intensity(float dx, float dy)
{
  float distSq = dx*dx + dy*dy;
  if (distSq <= (1.0f/65535.0f))
    return 65535.0;
  else
    return 1/distSq;
}

请注意,此类代码的极端情况处理可能略有不完善。虽然对于 65535.0f 不是问题,但可能会出现 distSq 恰好等于最大值的倒数,但其倒数小于最大值的情况。例如,如果最大值为 46470.0f 且 distSq 为 0.0000215238924f,则正确结果为 46459.9961f,但函数将返回 46470.0f。这些问题在实践中不太可能造成问题,但人们应该意识到它们。请注意,如果比较使用小于而不是小于或等于,并且最大值为 46590.0f,则 distSq 值为 0.0000214642932f 将产生结果 46589.0039,超过最大值。

顺便说一句,在许多系统上,计算除数的近似倒数并乘以被除数的成本可能比执行浮点除法的成本低得多。这种方法在其精度足够的许多情况下可能很有用。

关于c - 嵌入式应用中浮点除零的高效校验,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55635837/

相关文章:

performance - MongoDB 性能

c - 模拟中的 stub 函数

c++ - 注册为模板参数

c - 原始硬盘访问/dev/sda] vs/dev/sg[y]?

c - C 中的字符串处理——指针和引用调用问题

c - 有没有办法定义一个将表达式(即 int)转换为字符串文字的宏?

performance - MongoDB 嵌入式与大数据文档的引用模式

c# - 如何在 C# Windows 应用程序中使用 RichEdit20W 控件?

ruby - 将 JRuby 用于 Ruby Web 应用程序?这值得么?

c - 从一个字符中读取单个位