在C中的位置MIN和MAX定义,如果有的话?
实现这些的最佳方式是什么,尽可能通用和安全?(首选编译器扩展/内置主流编译器.)
从C++,是min和max优选超过fmin和fmax?为了比较两个整数,它们是否提供基本相同的功能?
您是倾向于使用这些功能集中的一个还是更喜欢自己编写(可能是为了提高效率,可移植性,灵活性等)?
笔记:
提前致谢!
C99添加了一个宏__STDC_IEC_559__,可用于测试编译器和标准库是否符合ISO/IEC/IEEE 60559(或IEEE 754)标准.
根据这个问题的答案,
如何检查-ieee-754-单精度-32位浮点表示,大多数C编译器不设置预处理器宏__STDC_IEC_559__.
根据海湾合作委员会的文件,它没有定义__STDC_IEC_559__.
我用GCC 4.9.2和Clang 3.6.0测试了这两个,使用glibc2.21使用以下代码.
//test.c
//#include <features.h>
int main(void) {
#if defined ( __STDC_IEC_559__ )
//#if defined ( __GCC_IEC_559__ )
return 1;
#else
return 0;
#endif
}
Run Code Online (Sandbox Code Playgroud)
然后
echo $?
Run Code Online (Sandbox Code Playgroud)
这表明此代码__STDC_IEC_559__是使用GCC定义的,而不是使用Clang定义的.然后我做了gcc -E,它显示该文件stdc-predef.h包含在内.这个文件定义__STDC_IEC_559__.
/* glibc's intent is to support the IEC 559 math functionality, real
and complex. If the GCC (4.9 and later) predefined macros
specifying compiler intent …Run Code Online (Sandbox Code Playgroud) 在C中,当±0.0支持-0.0或+0.0分配给a时double通常不会产生算术差异.尽管它们具有不同的位模式,但它们在算术上比较相同.
double zp = +0.0;
double zn = -0.0;
printf("0 == memcmp %d\n", 0 == memcmp(&zn, &zp, sizeof zp));// --> 0 == memcmp 0
printf("== %d\n", zn == zp); // --> == 1
Run Code Online (Sandbox Code Playgroud)
受到@Pascal Cuoq评论的启发,我正在寻找标准C中的一些功能,这些功能提供了算术上不同的结果.
注意:许多功能,如sin(),返回+0.0从f(+0.0)和-0.0从f(-0.0).但这些并不能提供不同的算术结果.这两个结果也不应该同时存在NaN.
我看到VS2013增加了对C99的大量主要核心语言功能的支持.现在它支持复合文字,指定初始化器,可变参数宏,交错声明和语句,仅举几例.
这表明VS开发人员在Visual Studio中为C99支持迈出了重要的一步.然而,其中一些功能并不是C++语言的一部分,这似乎与之前宣布的开发策略有明显的偏差(例如"VS C编译器只支持那些也是C++一部分的C99功能").
那么,有什么官方或半官方的话说明发生了什么?我似乎无法在网上找到任何确定的内容.这些C99功能是否正式公布?是否有任何承诺继续在VS中支持C99?或者这只是某种"流氓"的非官方发展?
当我第一次使用Haswell处理器时,我尝试使用FMA来确定Mandelbrot集.主要算法是这样的:
intn = 0;
for(int32_t i=0; i<maxiter; i++) {
floatn x2 = square(x), y2 = square(y); //square(x) = x*x
floatn r2 = x2 + y2;
booln mask = r2<cut; //booln is in the float domain non integer domain
if(!horizontal_or(mask)) break; //_mm256_testz_pd(mask)
n -= mask
floatn t = x*y; mul2(t); //mul2(t): t*=2
x = x2 - y2 + cx;
y = t + cy;
}
Run Code Online (Sandbox Code Playgroud)
这确定n像素是否在Mandelbrot集中.因此对于双浮点,它运行超过4个像素(floatn = __m256d,intn = __m256i).这需要4个SIMD浮点乘法和4个SIMD浮点加法.
然后我修改了这个就像这样使用FMA
intn n = 0; …Run Code Online (Sandbox Code Playgroud) 我想实现SIMD minmag和maxmag函数.据我所知,这些功能是
minmag(a,b) = |a|<|b| ? a : b
maxmag(a,b) = |a|>|b| ? a : b
Run Code Online (Sandbox Code Playgroud)
我希望这些浮动和双重,我的目标硬件是Haswell.我真正需要的是计算两者的代码.以下是我对SSE4.1 for double的看法(AVX代码几乎完全相同)
static inline void maxminmag(__m128d & a, __m128d & b) {
__m128d mask = _mm_castsi128_pd(_mm_setr_epi32(-1,0x7FFFFFFF,-1,0x7FFFFFFF));
__m128d aa = _mm_and_pd(a,mask);
__m128d ab = _mm_and_pd(b,mask);
__m128d cmp = _mm_cmple_pd(ab,aa);
__m128d cmpi = _mm_xor_pd(cmp, _mm_castsi128_pd(_mm_set1_epi32(-1)));
__m128d minmag = _mm_blendv_pd(a, b, cmp);
__m128d maxmag = _mm_blendv_pd(a, b, cmpi);
a = maxmag, b = minmag;
}
Run Code Online (Sandbox Code Playgroud)
但是,这并不像我想的那样高效.是否有更好的方法或至少值得考虑的替代方案?我想尝试避免端口1,因为我已经使用该端口进行了许多添加/减少.该_mm_cmple_pd禀进入端口1.
我感兴趣的主要功能是:
//given |a| > |b| …Run Code Online (Sandbox Code Playgroud) 标准是否保证函数在所有实现中返回完全相同的结果?
以pow(float,float)32位IEEE浮点数为例.如果传入相同的两个浮点数,则所有实现的结果是否相同?
或者是否有一些灵活性,标准允许根据用于实现的算法的微小差异pow?