C 中三个浮点数中最快的最小最大

发布于 2024-12-15 18:28:25 字数 56 浏览 2 评论 0原文

我认为问题很清楚:我有三个数字,我有两个函数,最小值和最大值。

最快的实施是什么?

I think the question is pretty clear: I have three numbers, I have two functions, min and max.

What are the fastest implementations?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

围归者 2024-12-22 18:28:25

C 标准 (C99) 提供了 fmaxf标准 C 中的fminf 函数math.h 标头。我首先使用它来查找三个浮点数中最大的一个,然后检查它是否足够快以满足您的需求:

float max = fmaxf(a, fmaxf(b, c));
float min = fminf(a, fminf(b, c));

The C standard (C99) provides the fmaxf and fminf functions in the standard C math.h header. I'd start by just using it to find the largest of three floats and then check whether it's fast enough for your needs:

float max = fmaxf(a, fmaxf(b, c));
float min = fminf(a, fminf(b, c));
浅唱ヾ落雨殇 2024-12-22 18:28:25

天真的解决方案是使用两次比较来找到最小值,然后使用两次比较来找到最大值。这是次优的,因为三个比较就足够了(后面是返回 (min, max) 元组的伪代码):(

function minmax(float a, float b, float c): (float, float)
begin
  boolean altb = (a < b);
  boolean bltc = (b < c);
  if altb and bltc then return (a, c);
  if not altb and not bltc then return (c, a);
  if altb then // Also: c <= b, so b is known to be max
  begin
    if a < c then return (a, b);
    return (c, b);
  end
  if bltc then // Also: b <= a, so b is known to be min
  begin
    if a < c then return (b, c);
    return (b, a);
  end
  // Unreachable.
end

这是为了最具可读性而编写的,而不是为了最小化分支计数)

这会执行 2 到 3 次比较。不可能只使用 2 次比较,因为有 3 次比较! = 3 个浮点数的 6 次重新排序和 2 次比较只能区分 4 个不同的浮点数。这在问题的决策树上很容易看出。

在实践中,我们应该依赖编译器上的这样的优化。

Naive solution is two use two comparisons to find the min and then two comparisons to find the max. This is suboptimal since three comparisons suffice (pseudocode returning (min, max) tuple follows):

function minmax(float a, float b, float c): (float, float)
begin
  boolean altb = (a < b);
  boolean bltc = (b < c);
  if altb and bltc then return (a, c);
  if not altb and not bltc then return (c, a);
  if altb then // Also: c <= b, so b is known to be max
  begin
    if a < c then return (a, b);
    return (c, b);
  end
  if bltc then // Also: b <= a, so b is known to be min
  begin
    if a < c then return (b, c);
    return (b, a);
  end
  // Unreachable.
end

(This is written to be most readable, rather than to minimize the branch count)

This performs between 2 and 3 comparisons. It is impossible to use only 2 comparisons since there are 3! = 6 reorderings of 3 floats and 2 comparisons can only differentiate between 4 different ones. This is easily seen on a decision tree of the problem.

In practice one should rely for optimizations like this one on the compiler.

聚集的泪 2024-12-22 18:28:25

查找三个数字中最大的代码。

#includ<stdio.h>

void main()

{
    float a,b,c;
    printf("enter a,b,c:");
    scanf("%f%f%f",&a,&b,&c); 
    printf("Greatest no: %f"(a>b)?((a>c)?a:c):((c>b)?c:b)); 
}

反转逻辑以找到最少的:)

Code to find the greatest of three numbers.

#includ<stdio.h>

void main()

{
    float a,b,c;
    printf("enter a,b,c:");
    scanf("%f%f%f",&a,&b,&c); 
    printf("Greatest no: %f"(a>b)?((a>c)?a:c):((c>b)?c:b)); 
}

Reverse the logic to find the least :)

木落 2024-12-22 18:28:25

我非常喜欢 Adam Zalcman 的方法,我用 C 重写了它,这次也最小化了分支(所以最多 3 个比较和 3 个分支)。

struct Pair
{
    float min_value;
    float max_value;
};

struct Pair minmax(float a, float b, float c)
{
    /* truth table:
     * a<b b<c a<c
     *  T   T   *  => (a, c)
     *  T   F   T  => (a, b)
     *  T   F   F  => (c, b)
     *  F   T   T  => (b, c)
     *  F   T   F  => (b, a)      
     *  F   F   *  => (c, a)
     */
    if (a < b) {
        if (b < c) 
            return (struct Pair) {a, c};
        else {
            if (a < c)
                return (struct Pair) {a, b};
            else
                return (struct Pair) {c, b};
        }
    } else {
        if (b < c) {
            if (a < c)
                return (struct Pair) {b, c};
            else
                return (struct Pair) {b, a};
        } else
            return (struct Pair) {c, a};
    }
}

void foo()
{
    struct Pair result = minmax(1.0, 2.0, 3.0);
}

(不过现在这可能会退化为代码高尔夫......)

I liked Adam Zalcman's approach so much, I rewrote it in C, this time minimising branches too (so at most 3 comparisons and 3 branches).

struct Pair
{
    float min_value;
    float max_value;
};

struct Pair minmax(float a, float b, float c)
{
    /* truth table:
     * a<b b<c a<c
     *  T   T   *  => (a, c)
     *  T   F   T  => (a, b)
     *  T   F   F  => (c, b)
     *  F   T   T  => (b, c)
     *  F   T   F  => (b, a)      
     *  F   F   *  => (c, a)
     */
    if (a < b) {
        if (b < c) 
            return (struct Pair) {a, c};
        else {
            if (a < c)
                return (struct Pair) {a, b};
            else
                return (struct Pair) {c, b};
        }
    } else {
        if (b < c) {
            if (a < c)
                return (struct Pair) {b, c};
            else
                return (struct Pair) {b, a};
        } else
            return (struct Pair) {c, a};
    }
}

void foo()
{
    struct Pair result = minmax(1.0, 2.0, 3.0);
}

(this may be degenerating into code golf now though ...)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文