Math 无条件比较的数学求最大值

Math 无条件比较的数学求最大值,math,conditional,max,algebra,min,Math,Conditional,Max,Algebra,Min,----------更新------------ 到目前为止,codymanix和moonshadow提供了很大的帮助。我可以用这些方程来解决我的问题,而不是用右移除以29。因为32位带符号的2^31=溢出到29。真管用 PHP中的原型 $r = $x - (($x - $y) & (($x - $y) / (29))); 潜在客户的实际代码(每行只能执行一个数学函数!!!啊哈!!!) ----------原始问题------------ 由于我的应用程序的局限性,我认为这不太可能,但

----------更新------------

到目前为止,codymanix和moonshadow提供了很大的帮助。我可以用这些方程来解决我的问题,而不是用右移除以29。因为32位带符号的2^31=溢出到29。真管用

PHP中的原型

$r = $x - (($x - $y) & (($x - $y) / (29)));
潜在客户的实际代码(每行只能执行一个数学函数!!!啊哈!!!)

----------原始问题------------
由于我的应用程序的局限性,我认为这不太可能,但我认为值得一试

我会尽量让这件事简单化。我需要找到两个数字之间的最大值,而不需要使用IF或任何条件语句

为了找到最大值,我只能执行以下功能

Divide, Multiply, Subtract, Add, NOT, AND ,OR
假设我有两个数字

A = 60;
B = 50;

现在,如果A总是大于B,那么很容易找到最大值

MAX = (A - B) + B;
ex. 
10 = (60 - 50)
10 + 50 = 60 = MAX
问题是A并不总是大于B。我无法使用正在使用的脚本应用程序执行ABS、MAX、MIN或条件检查


是否有任何方法可以使用上面的有限操作来查找非常接近最大值的值?

这取决于您使用的语言,但可能会有用


但是,如果您不能在“脚本应用程序”中执行条件检查,您可能没有三元运算符。

Hmmm。我假设没有,AND、AND或是按位的?如果是这样,将有一个位表达式来解决这个问题。请注意,A | B将给出一个>=A和>=B的数字。可能有一种修剪方法用于选择位最多的数字

为了扩展,我们需要以下来确定A(0)还是B(1)更大

真值表:

0|0 = 0  
0|1 = 1
1|0 = 0
1|1 = 0

!A and B
因此,将给出更大位的索引。因此,比较两个数字中的每个位,当它们不同时,使用上面的表达式(不是A和B)来确定哪个数字更大。从最高有效位开始,然后向下执行两个字节。如果没有循环构造,请手动比较每个位

实施“当它们不同时”:


(A!=B)和(我的逻辑在此)

如果您不能信任您的环境在无分支操作可用时生成适当的无分支操作,请参阅以了解如何继续。注意输入范围的限制;如果无法保证输入符合要求,请使用较大的整数类型进行操作。

max=a-((a-b)和((a-b)>>31))

其中>>是按位右移(根据符号性也称为SHR或ASR)

使用数字的位数减去1,而不是31。

试试这个(但要注意溢出) (代码用C#表示)


仅使用逻辑运算、短路评估,并假设向零舍入的C约定,可以表示为:

int lt0(int x) {
    return x && (!!((x-1)/x));
}

int mymax(int a, int b) {
    return lt0(a-b)*b+lt0(b-a)*a;
}
基本思想是实现一个返回0或1的比较运算符。如果您的脚本语言像python一样遵循向下限值四舍五入的惯例,则可以执行类似的技巧。

#region GetMaximumNumber
#region GetMaximumNumber
/// <summary>
/// Provides method to get maximum values.
/// </summary>
/// <param name="values">Integer array for getting maximum values.</param>
/// <returns>Maximum number from an array.</returns>
private int GetMaximumNumber(params int[] values)
{
  // Declare to store the maximum number.
  int maximumNumber = 0;
  try
  {
    // Check that array is not null and array has an elements.
    if (values != null &&
        values.Length > 0)
    {
      // Sort the array in ascending order for getting maximum value.
      Array.Sort(values);

      // Get the last value from an array which is always maximum.
      maximumNumber = values[values.Length - 1];
    }
  }
  catch (Exception ex)
  {
    throw ex;
  }
  return maximumNumber;
}
#endregion
/// ///提供获取最大值的方法。 /// ///用于获取最大值的整数数组。 ///数组中的最大值。 私有int GetMaximumNumber(参数int[]值) { //声明以存储最大数量。 int最大数=0; 尝试 { //检查数组是否不为null,以及数组是否包含元素。 如果(值!=null)&& 值(长度>0) { //按升序对数组排序以获得最大值。 数组。排序(值); //从始终为最大值的数组中获取最后一个值。 maximumNumber=值[values.Length-1]; } } 捕获(例外情况除外) { 掷骰子; } 返回最大数; } #端区
如果我们能找到两个数字之间的差异(只有大小而不是符号),我想这是最简单的一个


其中
|a-b |
a
b

无条件解之间的差值。投射到uint,然后返回到int以获得abs

function Min(x,y:integer):integer;
  Var
   d:integer;
   abs:integer;
 begin
  d:=x-y;
  abs:=d*(1-2*((3*d) div (3*d+1)));
  Result:=(x+y-abs) div 2;
 end;
int abs (a) { return (int)((unsigned int)a); }
int max (a, b) { return (a + b + abs(a - b)) / 2; }

int max3 (a, b, c) { return (max(max(a,b),c); }

您可以将其表示为一系列算术和位运算,例如:

int myabs(const int& in) {
  const int tmp = in >> ((sizeof(int) * CHAR_BIT) - 1);
  return tmp - (in ^ tmp(;
}

int mymax(int a, int b) {
    return ((a+b) + myabs(b-a)) / 2;
}

请看这个节目。。这可能是本页迄今为止最好的答案

#include <stdio.h>

int main()
{
    int a,b;
    a=3;
    b=5;
    printf("%d %d\n",a,b);
    b = (a+b)-(a=b); // this line is doing the reversal
    printf("%d %d\n",a,b);
    return 0;
}
#包括
int main()
{
INTA,b;
a=3;
b=5;
printf(“%d%d\n”,a,b);
b=(a+b)-(a=b);//此行正在进行反转
printf(“%d%d\n”,a,b);
返回0;
}
如果A总是大于B。。[我们可以使用]<代码>最大=(A-B)+B

没必要。只需使用:
intmaxa(inta,intb){returna;}

(1) 如果允许使用条件,您是否执行
max=a>b?a:b

(2) 任何其他方法要么使用定义的数字集,要么依赖隐式条件检查

(2a)
max=a-((a-b)和((a-b)>>31))
这很简洁,但只有在使用32位数字时才起作用。您可以将其展开为任意大的数字N,但如果尝试查找max(N-1,N+1),该方法将失败。该算法适用于有限状态自动机,但不适用于图灵机

(2b)震级
|a-b
是一种条件
|a-b |=a-b>0a-b:b-a

关于:

平方根也是一个条件。无论何时
c>0
c^2=d
我们都有第二个解决方案
-c
,因为
(-c)^2=(-1)^2*c^2=1*c^2=d
。平方根返回一对中最大的一个。我附带了一个内置的
intmax(intc1,intc2){returnmax(c1,c2);}


没有比较运算符,数学是非常对称的,并且在能力上是有限的。如果没有某种类型的
,则无法区分正数和负数

这是我仅使用
+,-,*,%,/
运算符的实现

//Assuming 32 bit integers 
int is_diff_positive(int num)
{
    ((num & 0x80000000) >> 31) ^ 1; // if diff positive ret 1 else 0
}
int sign(int x)
{
   return ((num & 0x80000000) >> 31);
}

int flip(int x)
{
   return x ^ 1;
}

int max(int a, int b)
{
  int diff = a - b;

  int is_pos_a = sign(a);
  int is_pos_b = sign(b);

  int is_diff_positive = diff_positive(diff);
  int is_diff_neg = flip(is_diff_positive);

  // diff (a - b) will overflow / underflow if signs are opposite
  // ex: a = INT_MAX , b = -3 then a - b => INT_MAX - (-3) => INT_MAX + 3
  int can_overflow = is_pos_a ^ is_pos_b;
  int cannot_overflow = flip(can_overflow);
  int res = (cannot_overflow * ( (a * is_diff_positive) + (b * 
            is_diff_negative)) + (can_overflow * ( (a * is_pos_a) + (b * 
            is_pos_b)));

  return res;

}
using static System.Console;

int Max(int a, int b) => (a + b + Abs(a - b)) / 2;
int Abs(int x) => x * ((2 * x + 1) % 2);

WriteLine(Max(-100, -2) == -2); // true
WriteLine(Max(2, -100) == 2);   // true

我刚想出一个表达方式 (a-b)-(a-b)/(2(a-b))*b+((b-a)-(b-a)/(2(b-a))*a 如果a>b和
#include <stdio.h>

int main()
{
    int a,b;
    a=3;
    b=5;
    printf("%d %d\n",a,b);
    b = (a+b)-(a=b); // this line is doing the reversal
    printf("%d %d\n",a,b);
    return 0;
}
//Assuming 32 bit integers 
int is_diff_positive(int num)
{
    ((num & 0x80000000) >> 31) ^ 1; // if diff positive ret 1 else 0
}
int sign(int x)
{
   return ((num & 0x80000000) >> 31);
}

int flip(int x)
{
   return x ^ 1;
}

int max(int a, int b)
{
  int diff = a - b;

  int is_pos_a = sign(a);
  int is_pos_b = sign(b);

  int is_diff_positive = diff_positive(diff);
  int is_diff_neg = flip(is_diff_positive);

  // diff (a - b) will overflow / underflow if signs are opposite
  // ex: a = INT_MAX , b = -3 then a - b => INT_MAX - (-3) => INT_MAX + 3
  int can_overflow = is_pos_a ^ is_pos_b;
  int cannot_overflow = flip(can_overflow);
  int res = (cannot_overflow * ( (a * is_diff_positive) + (b * 
            is_diff_negative)) + (can_overflow * ( (a * is_pos_a) + (b * 
            is_pos_b)));

  return res;

}
using static System.Console;

int Max(int a, int b) => (a + b + Abs(a - b)) / 2;
int Abs(int x) => x * ((2 * x + 1) % 2);

WriteLine(Max(-100, -2) == -2); // true
WriteLine(Max(2, -100) == 2);   // true
using System;
namespace ConsoleApp2
{
    class Program
    {
        static void Main(string[] args)
        {
            float a = 101, b = 15;
            float max = (a + b) / 2 + ((a > b) ? a - b : b - a) / 2;            
        }
    }
}