我想要一个函数为负数返回-1,为正数返回+1。 http://en.wikipedia.org/wiki/Sign_function 我自己编写它很容易,但它似乎应该存在于某个标准库中。
编辑:具体来说,我正在寻找一个函数工作在浮动。
我想要一个函数为负数返回-1,为正数返回+1。 http://en.wikipedia.org/wiki/Sign_function 我自己编写它很容易,但它似乎应该存在于某个标准库中。
编辑:具体来说,我正在寻找一个函数工作在浮动。
当前回答
一般来说,在C/ c++中没有标准的signum函数,缺少这样一个基本函数说明了很多关于这些语言的信息。
除此之外,我相信关于定义这样一个函数的正确方法的两种主流观点在某种程度上是正确的,而且一旦你考虑到两个重要的警告,关于它的“争议”实际上是没有争议的:
A signum function should always return the type of its operand, similarly to an abs() function, because signum is usually used for multiplication with an absolute value after the latter has been processed somehow. Therefore, the major use case of signum is not comparisons but arithmetic, and the latter shouldn't involve any expensive integer-to/from-floating-point conversions. Floating point types do not feature a single exact zero value: +0.0 can be interpreted as "infinitesimally above zero", and -0.0 as "infinitesimally below zero". That's the reason why comparisons involving zero must internally check against both values, and an expression like x == 0.0 can be dangerous.
对于C语言,我认为使用整型的最佳方法确实是使用(x > 0) - (x < 0)表达式,因为它应该以一种无分支的方式进行转换,并且只需要三个基本操作。最好定义强制返回类型与实参类型匹配的内联函数,并添加C11 define _Generic来将这些函数映射到公共名称。
With floating point values, I think inline functions based on C11 copysignf(1.0f, x), copysign(1.0, x), and copysignl(1.0l, x) are the way to go, simply because they're also highly likely to be branch-free, and additionally do not require casting the result from integer back into a floating point value. You should probably comment prominently that your floating point implementations of signum will not return zero because of the peculiarities of floating point zero values, processing time considerations, and also because it is often very useful in floating point arithmetic to receive the correct -1/+1 sign, even for zero values.
其他回答
在C/ c++中是否存在标准符号函数(signum, sgn) ?
是的,这取决于定义。
C99及以后版本在<math.h>中有signbit()宏
Int符号位(实浮点x); signbit宏当且仅当其参数值的符号为负时返回一个非零值。C11§7.12.3.6
然而OP想要一些不同的东西。
我想要一个函数,返回-1的负数和+1的正数. ...处理浮点数的函数。
#define signbit_p1_or_n1(x) ((signbit(x) ? -1 : 1)
更深层次的问题:
OP的问题在以下情况下不是特定的:x = 0.0, -0.0, +NaN, -NaN。
经典的signum()在x>0时返回+1,在x<0时返回-1,在x==0时返回0。
许多答案已经涵盖了这一点,但没有涉及x = -0.0, +NaN, -NaN。许多都是针对通常缺少Not-a-Numbers (NaN)和-0.0的整数观点。
典型答案函数如signnum_typical()在-0.0,+NaN, -NaN上,它们返回0.0,0.0,0.0。
int signnum_typical(double x) {
if (x > 0.0) return 1;
if (x < 0.0) return -1;
return 0;
}
相反,我建议这样的功能:在-0.0,+NaN, -NaN上,它返回-0.0,+NaN, -NaN。
double signnum_c(double x) {
if (x > 0.0) return 1.0;
if (x < 0.0) return -1.0;
return x;
}
显然,最初的帖子的问题的答案是否定的。没有标准的c++ sgn函数。
我的《C in a Nutshell》揭示了一个叫做copysign的标准函数的存在,它可能很有用。看起来,copyysign(1.0, -2.0)将返回-1.0,而copyysign(1.0, 2.0)将返回+1.0。
很接近吧?
如果boost可用,可以使用boost/math/special_functions/sign.hpp中的boost::math::sign()方法。
如果您只想测试符号,则使用signbit(如果参数有负号则返回true)。 不知道为什么你特别想要返回-1或+1;复印件更方便 但在某些平台上,它会在负0时返回+1 仅部分支持负0,其中signbit可能会返回true。