math - resueltos - estadística elemental johnson r
Encuentra matemáticamente el valor máximo sin comparación condicional (14)
Si A siempre es mayor que B .. [podemos usar] ..
MAX = (A - B) + B;
No hay necesidad. Solo use: int maxA(int A, int B){ return A;}
(1) Si los condicionales están permitidos, haces max = a>b ? a : b
max = a>b ? a : b
.
(2) Cualquier otro método usa un conjunto definido de números o confía en las verificaciones condicionales implícitas.
(2a) max = a-((ab)&((ab)>>31))
esto es bueno, pero solo funciona if
utiliza números de 32 bits. Puede expandirlo arbitrariamente a un gran número N, pero el método fallará si intenta encontrar el máximo (N-1, N + 1). Este algoritmo funciona para autómatas de estados finitos, pero no para una máquina de Turing.
(2b) Magnitud |ab|
es una condición |ab| = ab>0 ab : ba
|ab| = ab>0 ab : ba
La raíz cuadrada es también una condición. Cuando c>0
y c^2 = d
tenemos la segunda solución -c
, porque (-c)^2 = (-1)^2*c^2 = 1*c^2 = d
. La raíz cuadrada devuelve la mayor de la pareja. I viene con una compilación en int max(int c1, int c2){return max(c1, c2);}
Sin comparación, el operador matemático es muy simétrico y limitado en potencia. Los números positivos y negativos no pueden distinguirse sin if
de algún tipo.
----------Actualizado ------------
Codymanix y Moonshadow han sido de gran ayuda hasta el momento. Pude resolver mi problema usando las ecuaciones y en lugar de usar el cambio a la derecha, me dividí por 29. Porque con 32 bits firmados 2 ^ 31 = desbordamientos a 29. ¡Lo que funciona!
Prototipo en PHP
$r = $x - (($x - $y) & (($x - $y) / (29)));
Código real para LEADS (solo puedes hacer una función matemática POR LÍNEA !!! AHHHH !!!)
DERIVDE1 = IMAGE1 - IMAGE2;
DERIVED2 = DERIVED1 / 29;
DERIVED3 = DERIVED1 AND DERIVED2;
MAX = IMAGE1 - DERIVED3;
---------- Pregunta original -----------
No creo que esto sea muy posible con las limitaciones de mi aplicación, pero pensé que vale la pena preguntar.
Voy a tratar de hacer esto simple. Necesito encontrar los valores máximos entre dos números sin poder usar un IF o cualquier declaración condicional.
Para encontrar los valores MAX solo puedo realizar las siguientes funciones
Divide, Multiply, Subtract, Add, NOT, AND ,OR
Digamos que tengo dos números
A = 60;
B = 50;
Ahora, si A es siempre mayor que B, sería sencillo encontrar el valor máximo
MAX = (A - B) + B;
ex.
10 = (60 - 50)
10 + 50 = 60 = MAX
El problema es que A no siempre es mayor que B. No puedo realizar controles ABS, MAX, MIN o condicionales con la aplicación de scripting que estoy usando.
¿Hay alguna manera posible utilizando la operación limitada anterior para encontrar un valor MUY cercano al máximo?
Depende del idioma que utilice, pero el operador ternario puede ser útil.
Pero entonces, si no puede realizar verificaciones condicionales en su ''aplicación de scripting'', es probable que no tenga el operador ternario.
Hmmm Supongo que NO, Y, y O son bitwise? Si es así, habrá una expresión en modo de bits para resolver esto. Tenga en cuenta que A | B le dará un número> = A y> = B. Quizás haya un método de recorte para seleccionar el número con la mayor cantidad de bits.
Para ampliar, necesitamos lo siguiente para determinar si A (0) o B (1) es mayor.
mesa de la verdad:
0|0 = 0
0|1 = 1
1|0 = 0
1|1 = 0
!A and B
Por lo tanto, le dará el índice del bit mayor. Vaya, compare cada bit en ambos números, y cuando sean diferentes, use la expresión anterior (No A y B) para determinar qué número fue mayor. Comience desde el bit más significativo y baje ambos bytes. Si no tiene una construcción de bucle, compare manualmente cada bit.
Implementando "cuando son diferentes":
(A! = B) Y (mi lógica aquí)
Puede expresar esto como una serie de operaciones aritméticas y bitwise, por ejemplo:
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;
}
Si no puede confiar en su entorno para generar las operaciones sin sucursales adecuadas cuando estén disponibles, consulte esta página para saber cómo proceder. Tenga en cuenta la restricción en el rango de entrada; use un tipo de entero más grande para la operación si no puede garantizar que sus entradas encajen.
Solución sin condicionales. Eche a la uint y luego vuelva a la int para obtener abdominales.
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); }
Supongo que este sería el más simple si logramos encontrar la diferencia entre dos números (solo la magnitud no firme)
max = ((a+b)+|a-b|)/2;
donde |ab|
Es una magnitud de diferencia entre a
y b
.
Usando solo operaciones lógicas, evaluación de cortocircuitos y asumiendo la convención de C de redondeo hacia cero, es posible expresar esto como:
int lt0(int x) {
return x && (!!((x-1)/x));
}
int mymax(int a, int b) {
return lt0(a-b)*b+lt0(b-a)*a;
}
La idea básica es implementar un operador de comparación que devuelva 0 o 1. Es posible hacer un truco similar si su lenguaje de scripting sigue la convención de redondear hacia el valor mínimo, como lo hace python.
intente esto, (pero tenga en cuenta los desbordamientos) (Código en C #)
public static Int32 Maximum(params Int32[] values)
{
Int32 retVal = Int32.MinValue;
foreach (Int32 i in values)
retVal += (((i - retVal) >> 31) & (i - retVal));
return retVal;
}
mire este programa ... esta podría ser la mejor respuesta hasta la fecha en esta página ...
#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;
}
encontrando el máximo de 2 variables:
max = a-((ab)&((ab)>>31))
donde >> es a la derecha en el modo a la derecha (también llamado SHR o ASR que depende de la firma).
En lugar de 31 usas la cantidad de bits que tus números tienen menos uno.
#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
//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;
}
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;