首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用于2个整数常量除法的C++嵌入式平台可读性

用于2个整数常量除法的C++嵌入式平台可读性
EN

Stack Overflow用户
提问于 2016-09-06 11:36:35
回答 3查看 88关注 0票数 1

我有以下代码:

代码语言:javascript
复制
int foo = SamplingSomeValue();
int threshold = foo * 7 / 10;
...

这意味着,算法对一些值进行采样,并将采样值的70%设置为下界阈值,以找到那些相似的值。

然而,常量7/10是丑陋的。通过将其替换为tRatio,它更具可读性,其中tRatio被定义为constexpr float tRatio = 0.7;。然而,在没有浮点运算硬件单元的嵌入式处理器中,它的效率并不高。

很明显,我们不能写constexpr int tRatio = (7/10);,因为它是0。

保持效率和可读性的最好方法是什么?

EN

回答 3

Stack Overflow用户

发布于 2016-09-06 18:35:35

出于可读性和可维护性的考虑,可以定义一个包含以下内容的cFraction

代码语言:javascript
复制
class cFraction
{
    public:
        cFraction( int num, int den ) : m_num(num), m_den(den){ }
        int operator*( int rhs ) const
        {
            return (rhs * m_num) / m_den ;
        }

    private:
        int m_num ;
        int m_den ;
} ;

和非成员重载:

代码语言:javascript
复制
int operator*( int lhs, const cFraction& rhs )
{
    return rhs * lhs ;  // Multiply is commutative, 
                        // swap operands to use member overload
}

然后给出:

代码语言:javascript
复制
const cFraction SEVENTY_PERCENT( 7, 10 ) ;

你可以这样写:

代码语言:javascript
复制
int threshold = foo * SEVENTY_PERCENT ;

或者:

代码语言:javascript
复制
int threshold = SEVENTY_PERCENT * foo ;

当然,虽然这提供了可读性,但考虑到名称相当通用,您可能不得不使用一组完整的重载和类型转换来完成类,以使cFraction看起来像一个完整的算术类型。这在其他情况下可能确实有用,但您可能可以通过只实现上面的代码并将其命名为类似于cIntegerRatio的名称来避免这种情况,以清楚地表明该类具有非常特定的用途,并且只有乘以整数才有意义。

票数 1
EN

Stack Overflow用户

发布于 2016-09-06 19:31:48

这不是对你问题的直接回答,而是一个重要的考虑因素。

关于以下内容的声明

...没有浮点运算硬件单元的嵌入式处理器...

表示代码中的任何除法或模运算都编译为函数调用(该函数通常是随处理器软件开发工具包一起提供的库的一部分)。

如果您要多次执行此foo * 7 / 10操作,那么我建议您采取一些编码优化措施。

例如:foo * 11 / 16,编译器随后可以将其解释为foo * 11 >> 4

选择的分子越高,获得更高准确率的机会就越高:

  • foo * 11 / 16
  • foo * 22 / 32无改进来自previous
  • foo * 44 / 64无改进来自previous
  • foo * 89 / 128
  • foo * 179 / 256
  • foo * 358 / 512无改进来自previous
  • foo * 716 / 1024无改进来自previous
  • foo * 1443 / 2048
  • foo * 2867 / 4096
  • ...

当然,缺点是乘法可能会溢出。

为了决定使用哪个因子,您需要考虑:

  • 平台上foo类型的大小foo在任何程序执行过程中可以保留的最大值
票数 1
EN

Stack Overflow用户

发布于 2016-09-07 19:20:31

你能做的是,

代码语言:javascript
复制
#define FRAC 7/10
#define DIV(x) (x)*FRAC
...
int  threshold = DIV(foo) 

如果您确保只在DIV宏中使用FRAC,则可以省去FRAC定义中的括号(在本例中是一个例外),而在代码中使用DIV宏。

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

https://stackoverflow.com/questions/39340267

复制
相关文章

相似问题

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