while que loop for español c++ c algorithm math

c++ - que - Gire while loop en la ecuación matemática?



while loop labview (4)

Tengo dos loops simples en mi programa que creo que deberían ser ecuaciones matemáticas, pero estoy luchando por convertirlos:

float a = someValue; int b = someOtherValue; int c = 0; while (a <= -b / 2) { c--; a += b; } while (a >= b / 2) { c++; a -= b; }

Este código funciona tal cual, pero creo que podría simplificarse en ecuaciones matemáticas. La idea aquí es que este código está tomando un desplazamiento (algún Valor) y ajustando una coordenada (c) para minimizar la distancia desde el centro de un mosaico (de tamaño algo Otro Valor). Cualquier ayuda sería apreciada.


Creo que quieres algo como esto:

c = ((int) a + b / 2 * sign(a)) / b

Eso debería coincidir con sus bucles, excepto en ciertos casos donde b es impar porque el rango de -b / 2 a b / 2 es menor que b cuando b es impar.


Se puede demostrar que lo siguiente es correcto:

c = floor((a+b/2)/b) a = a - c*b

Tenga en cuenta que el piso significa redondear hacia abajo, hacia el infinito negativo: no hacia 0. (Ej. Piso (-3.1) = - 4. Las funciones de biblioteca de floor() harán esto; solo asegúrese de no lanzarlo a int, que generalmente será redondo hacia 0 en su lugar.)

Presumiblemente, b es estrictamente positivo, porque de lo contrario ninguno de los bucles nunca terminará: agregar b no aumentará y restar b no lo hará más pequeño. Con esa suposición, podemos probar que el código anterior funciona. (Y el código de paranoidgeek también es casi correcto, excepto que usa un molde para int en lugar de floor ).

Manera inteligente de probarlo : El código agrega o resta múltiplos de b de a hasta que a está en [-b/2,b/2) , que puede ver como sumar o restar enteros de a/b hasta que a/b esté en [-1/2,1/2) , es decir, hasta que (a/b+1/2) (llámalo x ) esté en [0,1) . Como solo lo está cambiando por enteros, el valor de x no cambia el mod 1 , es decir, va a su resto mod 1 , que es x-floor(x) . Entonces, la cantidad efectiva de sustracciones que haces (que es c ) es floor(x) .

Manera tediosa de probarlo :

Al final del primer ciclo, el valor de c es el negativo del número de veces que se ejecuta el ciclo, es decir:

  • 0 si: a> -b / 2 <=> a + b / 2> 0
  • -1 si: -b / 2 ≥ a> -3b / 2 <=> 0 ≥ a + b / 2> -b <=> 0 ≥ x> -1
  • -2 si: -3b / 2 ≥ a> -5b / 2 <=> -b ≥ a + b / 2> -2b <=> -1 ≥ x> -2 etc.,

donde x = (a+b/2)/b , entonces c es: 0 si x> 0 y "techo (x) -1" en caso contrario. Si el primer bucle se ejecutó en absoluto, entonces era ≤ -b / 2 justo antes de la última vez que se ejecutó el bucle, por lo que ahora es ≤ -b / 2 + b, es decir, ≤ b / 2. Según si es exactamente b / 2 o no (es decir, si x cuando comenzó era exactamente un entero no positivo o no), el segundo ciclo funciona exactamente 1 vez o 0, yc es techo (x) o techo (x) -1. Entonces eso lo resuelve para el caso cuando se ejecutó el primer bucle.

Si el primer ciclo no se ejecutó, entonces el valor de c al final del segundo ciclo es:

  • 0 si: a <b / 2 <=> ab / 2 <0
  • 1 si: b / 2 ≤ a <3b / 2 <=> 0 ≤ ab / 2 <b <=> 0 ≤ y <1
  • 2 si: 3b / 2 ≤ a <5b / 2 <=> b ≤ ab / 2 <2b <=> 1 ≤ y <2, etc.,

donde y = (ab/2)/b , entonces c es: 0 si y <0 y 1 + piso (y) de lo contrario. [Y ahora ahora es <b / 2 y ≥ -b / 2.]

Entonces puedes escribir una expresión para c como:

x = (a+b/2)/b y = (a-b/2)/b c = (x≤0)*(ceiling(x) - 1 + (x is integer)) +(y≥0)*(1 + floor(y))

Por supuesto, al siguiente notará que (ceiling(x)-1+(x is integer)) es lo mismo que floor(x+1)-1 que es floor(x) , y que y es en realidad x-1 , entonces (1+floor(y))=floor(x) , y en cuanto a los condicionales:
cuando x≤0, no puede ser eso (y≥0), entonces c es solo el primer término que es floor(x) ,
cuando 0 <x <1, ninguna de las condiciones se cumple, entonces c es 0 ,
cuando 1 ≤ x, entonces solo 0≤y, entonces c es simplemente el segundo término que es floor(x) nuevamente. Entonces c = floor(x) en todos los casos.


Suponiendo que b es positivo, abs (c) = piso ((abs (a) - b / 2) / b). Luego, aplique el signo de a a c.