【问题标题】:Change default divide by 0 behavior in C++/iOS在 C++/iOS 中更改默认除以 0 行为
【发布时间】:2014-04-26 15:57:45
【问题描述】:

我正在构建一个 iOS 应用程序。

我有以下代码:

if(pbCB == 0) { //Don't divide by 0
    c = 1;
} else {
    c = sqrt(pb / pbCB) * PROTANOPIA_WBP;
}

我真的很想去掉 if 语句(上面的代码在一个 for 循环中)。

我知道将浮点除以 0,然后将该值转换为无符号字符(使用 gdb 进行测试):

//floating-point division by 0
p 10.0/0
$1 = inf

//casted to an unsigned char
p (unsigned char) (10.0/0)
$2 = 0 '\000'

我想知道是否有办法将除以 0 的定义更改为返回 1?一位教授告诉我这是一个硬件/架构问题,没有办法做到这一点,但我想看看可能不是这样。感谢您提供任何答案/想法/建议。

【问题讨论】:

  • 您可以使用NSDecimalNumber 并实现自己的舍入行为,在执行除法时返回1exceptionDuringOperation:error:leftOperand:rightOperand:。编辑:但是,是的,艾伦所说的可能更相关......!
  • 为什么要删除if?对于pbCB,输入中有多少比例为零?如果它很低,则条件测试几乎不会花费您(分支预测会做正确的事情)。
  • @AlanStokes 检查仍然必须每次都进行。此代码在循环中遍历实时 720p 视频源的每一帧的每个像素。 pbCB 是根据 RGB 像素值计算得出的,如果 RGB = (0,0,0),它将为 0。用户很有可能将相机对准黑色物体。
  • @Matt 优化的第一条规则是衡量。 (实际上,第一条规则是“不要”,第二条规则是测量。)您需要一些标准图像来尝试您的算法,并且您需要能够准确测量您正在运行的代码需要多长时间。然后,您可以尝试进行更改以查看有效的方法,或者计算的各个部分的成本是多少。
  • @JoachimIsaksson if 在一个紧密的循环中意味着您将在分支预测出错时否定流水线的好处。这可能比 sqrt 甚至几个三角函数调用的成本要高得多。

标签: c++ ios arm clang divide-by-zero


【解决方案1】:

就像 Alan Stokes 提到的那样,您无法有效地更改除零的处理方式。

但根据您正在使用的值的语义和范围,可能会提升和/或缩放您的输入,这样就不会剩下 0。

编辑: 通过语义,我指的是相关相机实际产生的值范围。许多数码相机实际上无法产生完整的 RGB 范围。如果没有,您可以使用该信息将您的输入转移到所需的范围内。

如果您没有此类信息,或者您的相机确实产生 (0,0,0)-(255,255,255),则另一种选择是将您的输入提升为浮点数,并根据需要移动和/或缩放以那种格式。这将需要更多的计算,但它可能比失败的分支预测更便宜。在做出任何最终决定之前,请务必测量对代表性输入样本的影响。

【讨论】:

  • 我所有的值都是 RGB,0-255(无符号字符)
  • 理想情况下,您还想知道这些值的语义。即,将相机指向黑色物体实际上会产生(0,0,0)吗?并且将相机对准相当明亮的白光实际上会产生(255,255,255)吗?我会在一分钟内用更多信息编辑我的答案。
【解决方案2】:

不,你不能。它由浮点规范指定并在硬件中实现。

【讨论】:

    猜你喜欢
    • 2017-10-19
    • 2016-07-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多