最小和最大签署零 [英] Minimum and maximum of signed zero

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

问题描述

我关注下列情况下

min(-0.0,0.0)
max(-0.0,0.0)
minmag(-x,x) 
maxmag(-x,x)

根据维基百科IEEE 754-2008 说,在关于MIN和MAX

According to Wikipedia IEEE 754-2008 says in regards to min and max

最小值和最大值操作定义,但留有一定的余地,其中输入值相等,但在重新presentation不同的情况。特别是:

The min and max operations are defined but leave some leeway for the case where the inputs are equal in value but differ in representation. In particular:

分(+ 0,-0)或分钟(-0,+ 0)必须出示与零值的东西,但总是可以返回第一个参数。

min(+0,−0) or min(−0,+0) must produce something with a value of zero but may always return the first argument.

我做了一些测试比较 FMIN 的fmax 分及以下>

I did some tests compare fmin, fmax, min and max as defined below

#define max(a,b) \
   ({ __typeof__ (a) _a = (a); \
       __typeof__ (b) _b = (b); \
     _a > _b ? _a : _b; })
#define min(a,b) \
   ({ __typeof__ (a) _a = (a); \
       __typeof__ (b) _b = (b); \
     _a < _b ? _a : _b; })

_mm_min_ps _mm_max_ps 调用其中的SSE MINPS maxps 指令。

and _mm_min_ps and _mm_max_ps which call the SSE minps and maxps instruction.

下面是结果(code我用来测试这个下面贴)

Here are the results (the code I used to test this is posted below)

fmin(-0.0,0.0)       = -0.0
fmax(-0.0,0.0)       =  0.0
min(-0.0,0.0)        =  0.0
max(-0.0,0.0)        =  0.0
_mm_min_ps(-0.0,0.0) =  0.0
_mm_max_ps(-0.0,0.0) = -0.0

正如你可以看到每个情况下返回不同的结果。 所以我的主要问题是什么的C和C ++标准库说?确实 FMIN(-0.0,0.0)必须等于 -0.0 FMAX(-0.0,0.0)必须等于 0.0 或在不同的实现允许不同的定义呢? 如果它被定义执行,这是否意味着,以确保code是不同的实现C标准库(来自不同的编译器.eg)支票必须完成的兼容,以确定他们是如何实现的最小值和最大值<? / STRONG>

As you can see each case returns different results. So my main question is what does the C and C++ standard libraries say? Does fmin(-0.0,0.0) have to equal -0.0 and fmax(-0.0,0.0) have to equal 0.0 or are different implementations allowed to define it differently? If it's implementation defined does this mean that to insure the code is compatible with different implementation of the C standard library (.e.g from different compilers) that checks must be done to determine how they implement min and max?

关于 minmag什么(-x,X) maxmag(-x,X)?这些在IEEE 754-2008共同定义。 是IEEE 754-2008至少定义这些实现?我从Wikepdia对最小值和最大值评论推断,这些都是实现定义。但C标准库不因为据我所知定义这些功能。在 OpenCL的这些功能​​被定义为

What about minmag(-x,x) and maxmag(-x,x)? These are both defined in IEEE 754-2008. Are these implementation defined at least in IEEE 754-2008? I infer from Wikepdia's comment on min and max that these are implementation defined. But the C standard library does not define these functions as far as I know. In OpenCL these functions are defined as

maxmag返回x如果| X | > | Y |,或y如果| Y | > | X |,否则fmax的(X,Y)

maxmag Returns x if | x| > |y|, or y if |y| > |x|, otherwise fmax(x, y).

minmag返回x如果| X | &LT; | Y |,或y如果| Y | &LT; | X |,否则FMIN(X,Y)。

minmag Returns x if |x| < |y|, or y if |y| < |x|, otherwise fmin(x, y).

x86指令集没有minmag和maxmag指令,因此我不得不实现它们。但对我来说,我需要的性能和创造的情况下的分支时的大小是相等的效率不高。

The x86 instruction set has no minmag and maxmag instructions so I had to implement them. But in my case I need performance and creating a branch for the case when the magnitudes are equal is not efficient.

该Itaninum指令集minmag和maxmag指令(法民 famax ),在这种情况下,只要我可以告诉大家(从阅读)在这种情况下它返回第二个参数。这不是什么 MINPS maxps 显示,虽然做的事情。这是奇怪的是, _mm_min_ps(-0.0,0.0)= 0.0 _mm_max_ps(-0.0,0.0)= -0.0 。我本来期望他们要么返回在两种情况下或第二的第一个参数。 为什么以这种方式定义的 MINPS maxps 指令?

The Itaninum instruction set has minmag and maxmag instructions (famin and famax) and in this case as far as I can tell (from reading) in this case it returns the second argument. That's not what minps and maxps appear to be doing though. It's strange that _mm_min_ps(-0.0,0.0) = 0.0 and _mm_max_ps(-0.0,0.0) = -0.0. I would have expected them to either return the first argument in both cases or the second. Why are the minps and maxps instructions defined this way?

#include <stdio.h>
#include <x86intrin.h>
#include <math.h>

#define max(a,b) \
   ({ __typeof__ (a) _a = (a); \
       __typeof__ (b) _b = (b); \
     _a > _b ? _a : _b; })

#define min(a,b) \
   ({ __typeof__ (a) _a = (a); \
       __typeof__ (b) _b = (b); \
     _a < _b ? _a : _b; })

int main(void) {
    float a[4] = {-0.0, -1.0, -2.0, -3.0};   
    float b[4] = {0.0, 1.0, 2.0, 3.0};
    __m128 a4 = _mm_load_ps(a);
    __m128 b4 = _mm_load_ps(b);
    __m128 c4 = _mm_min_ps(a4,b4);
    __m128 d4 = _mm_max_ps(a4,b4);
    { float c[4]; _mm_store_ps(c,c4); printf("%f %f %f %f\n", c[0], c[1], c[2], c[3]); }
    { float c[4]; _mm_store_ps(c,d4); printf("%f %f %f %f\n", c[0], c[1], c[2], c[3]); }

    printf("%f %f %f %f\n", fmin(a[0],b[0]), fmin(a[1],b[1]), fmin(a[2],b[2]), fmin(a[3],b[3]));
    printf("%f %f %f %f\n", fmax(a[0],b[0]), fmax(a[1],b[1]), fmax(a[2],b[2]), fmax(a[3],b[3]));

    printf("%f %f %f %f\n", min(a[0],b[0]), min(a[1],b[1]), min(a[2],b[2]), min(a[3],b[3]));
    printf("%f %f %f %f\n", max(a[0],b[0]), max(a[1],b[1]), max(a[2],b[2]), max(a[3],b[3]));    
}
//_mm_min_ps: 0.000000, -1.000000, -2.000000, -3.000000
//_mm_max_ps: -0.000000, 1.000000, 2.000000, 3.000000
//fmin: -0.000000, -1.000000, -2.000000, -3.000000
//fmax: 0.000000, 1.000000, 2.000000, 3.000000
//min: 0.000000, -1.000000, -2.000000, -3.000000
//max: 0.000000, 1.000000, 2.000000, 3.000000

编辑:

在关于C ++我测试的std ::分钟(-0.0,0.0)的std :: MAX(-0.0,0.0)和都返回 -0.0 。这表明了的std ::分钟是不一样的 FMIN 的std ::最大是不一样的的fmax

In regards to C++ I tested std::min(-0.0,0.0) and std::max(-0.0,0.0) and the both return -0.0. Which shows that that std::min is not the same as fmin and std::max is not the same as fmax.

推荐答案

为什么不读的标准自己吗?维基百科的文章 IEEE 包含指向标。

Why not read the standard yourself? The Wikipedia article for IEEE contains links to the standard.

请注意:在C的标准文件的不可自由。但是的最终草案的是(这是我的联系,搜索,找到的PDF版本)。不过,我从来没见过这里被引用的最后文件和AFAIK曾有大多了一些错别字纠正;没有改变。 IEEE然而,免费提供的。

Note: The C standard document is not available freely. But the final draft is (that's what I linked, search to find the pdf version). However, I've not seen the final document being cited here and AFAIK there had mostly been some typos corrected; nothing changed. IEEE is, however, available for free.

请注意,一个编译器不必坚持标准(一些嵌入式的编译器/版本比如没有实现IEEE-符合浮点值,但仍C-一致 - 只是阅读的细节标准)。故见编译器文档查看兼容。 MS-VC比如是不是甚至C99兼容(永远不会BEN),而gcc和铛/ LLVM是(大部分)在当前版本的C11兼容(GCC 4.9.2,因为至少在自4.7份)。

Note that a compiler need not stick to the standards (some embedded compilers/versions for instance do not implement IEEE-conforming floating point values, but are still C-conforming - just read the standard for details). So see the compiler documentation to see the compatibility. MS-VC for instance is not even compatible to C99 (and will never ben), while gcc and clang/llvm are (mostly) compatible to C11 in the current versions (gcc since 4.9.2 at least, in parts since 4.7).

在一般情况下,使用MS-VC时,检查它是否真正的确实的使用的所有标准功能的支持。它实际上是不能完全兼容当前的标准,也不是C99。

In general, when using MS-VC, check if it actually does support that all standard features used. It is actually not fully compliant to the current standard, nor C99.

这篇关于最小和最大签署零的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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