阈值的绝对值 [英] Threshold an absolute value

查看:180
本文介绍了阈值的绝对值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下功能:

char f1( int a, unsigned b ) { return abs(a) <= b; }

有关执行速度,我希望把它改写如下:

For execution speed, I want to rewrite it as follows:

char f2( int a, unsigned b ) { return (unsigned)(a+b) <= 2*b; } // redundant cast

或者用此签名,可能有细微的影响甚至对于非负 B

char f3( int a, int b )      { return (unsigned)(a+b) <= 2*b; }

这两种备选方案下,在一个平台上进行简单的测试工作,但我需要它便于携带。假设非负 B 并没有溢出的危险,这是典型的硬件和C编译器有效的优化?是不是也适用于C ++?

Both of these alternatives work under a simple test on one platform, but I need it to portable. Assuming non-negative b and no risk of overflow, is this a valid optimization for typical hardware and C compilers? Is it also valid for C++?

注:由​​于C ++的GCC 4.8 x86_64的与 -O3 F1()使用6机指令和 F2()使用4.说明 F3()是相同的为 F2()。感兴趣的还有:如果 B 是作为一个文字,这两个函数编译成3指令直接映射到)在指定的操作F2(

Note: As C++ on gcc 4.8 x86_64 with -O3, f1() uses 6 machine instructions and f2() uses 4. The instructions for f3() are identical to those for f2(). Also of interest: if b is given as a literal, both functions compile to 3 instructions that directly map to the operations specified in f2().

推荐答案

与原来的code。与签名启动

Starting with the original code with signature

char f2( int a, unsigned b );

这包含了前pression

this contains the expression

a + b

由于这些操作数中的一个已经签署的,其他的(对应)无符号整型(因此它们具有相同的整数转换等级),然后 - 继通常的算术转换(第6.3.1.8) - 有符号整数类型将被转换为无符号的类型另一个操作数。

Since one of these operands has a signed and the other an (corresponding) unsigned integer type (thus they have the same "integer conversion rank"), then - following the "Usual arithmetic conversions" (§ 6.3.1.8) - the operand with signed integer type is converted to the unsigned type of the other operand.

转换为无符号整数类型被很好地定义,即使有问题的值不能被重新由新型psented $ P $

Conversion to an unsigned integer type is well defined, even if the value in question cannot be represented by the new type:

[..]如果新类型是无符号的值被重复地增加或减1比可以重新$ P $在新型psented直到该值处于的范围内的最大值更转换新型。 60

[..] if the new type is unsigned, the value is converted by repeatedly adding or subtracting one more than the maximum value that can be represented in the new type until the value is in the range of the new type. 60

第6.3.1.3/2

§ 6.3.1.3/2

脚注60只是说,所描述的运算工作原理与数学的价值,而不是类型之一。

现在,用更新的code

Now, with the updated code

char f2_updated( int a, int b ); // called f3 in the question

事情会有所不同。但是,由于 B 被认为是非负的,并假设 INT_MAX&LT; = UINT_MAX 你可以转换 b 无符号而不必担心它有一个不同的数学值之后。因此,你可以写

things would look different. But since b is assumed to be non-negative, and assuming that INT_MAX <= UINT_MAX you can convert b to an unsigned without fearing it to have a different mathematical value afterwards. Thus you could write

char f2_updated( int a, int b ) {
  return f2(a, (unsigned)b); // cast unnecessary but to make it clear
}

F2 除权pression 2 * B 进一步限制的允许范围<$再次展望C $ C> b 应不小于 UINT_MAX / 2 (否则的数学结果将是错误的)更大。
所以只要你留在这些范围内,每一件事情都很好。

Looking again at f2 the expression 2*b further limits the allowed range of b to be not larger than UINT_MAX/2 (otherwise the mathematical result would be wrong). So as long as you stay within these bounds, every thing is fine.

注:无符号类型不溢出,他们包装,根据模运算

从N1570(一C11工作草案)报价

最后一点:

IMO的唯一真正合理的选择写这个功能是

IMO the only really reasonable choice to write this function is as

#include <stdbool.h>
#include <assert.h>
bool abs_bounded(int value, unsigned bound) {
  assert(bound <= (UINT_MAX / 2));
  /* NOTE: Casting to unsigned makes the implicit conversion that
           otherwise would happen explicit. */
  return ((unsigned)value + bound) <= (2 * bound);
}

使用已签署类型约束并没有多大意义,因为绝对的值不能小于一个负数。 abs_bounded(值,something_negative)将始终为false。如果有约束的负面的可能性,那么我会抓住这个这个功能之外(否则它不会太多),如:

Using a signed type for the bound does not make much sense, because the absolute of a value cannot be less than a negative number. abs_bounded(value, something_negative) would be always false. If there's the possibility of a negative bound, then I'd catch this outside of this function (otherwise it does "too much"), like:

int some_bound;
// ...
if ((some_bound >= 0) && abs_bounded(my_value, some_bound)) {
  // yeeeha
}

这篇关于阈值的绝对值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆