TODOPIC
Microcontroladores PIC => Todo en microcontroladores PIC => Mensaje iniciado por: Nocturno en 02 de Noviembre de 2021, 07:55:25
-
No se me ocurre ninguna operación matemática que pueda realizar lo mismo que este programa:
if (NumeroReal>0)
return (NumeroReal);
else
return (0)
El objetivo es que si el número es positivo, me quedo con él, pero si es negativo tengo que obtener un 0.
He estado dándole vueltas con multiplicaciones por -1, con valores absolutos, pero no encuentro la manera.
-
Hola, en que IDE o compilador quieres hacerlo?
Conociendo el formato de la variable en dónde se aloja el valor. Sabemos que el bit más significativo es el signo. Por lo tanto si vale 1, deberás hacer igual a cero el valor del número.
-
Me da igual el lenguaje. No quiero utilizar un condicional, porque eso ya lo tengo resuelto.
Mi pregunta es si se puede resolver con una operación matemática que no incluya condicionales.
-
Asi, rápido, se me ocurre:
(Número real + ABS(Número real))/2
Si es negativo, se anula el numerador y devuelve 0.
Si es positivo, se suman y se divide por dos, con lo que queda el valor original.
-
¡Brillante!
Muchas gracias Fuente
-
Ingeniosa solución la que aportó fuente, pero puede haber un problema, pues si el núm. es mayor a la mitad del que la variable puede almacenar, al sumarlo dos veces, se desbordará!
-
Pues entonces:
(Número Real / 2) + (ABS (Número Real) / 2)
-
Pues entonces:
(Número Real / 2) + (ABS (Número Real) / 2)
Yo llegué a esa conclusión con un sistema de 2 ecuaciones con dos incógnitas:
xm + cte =x
(-x)m + cte = 0
Donde x es el número, m es una constante que se debe multiplicar al número y cte un valor que se debe sumar o restar al producto de xm.
Resolviendo este sistema tienes que cte = x/2 (donde X es su valor absoluto )y m = 1/2
-
No se me ocurre ninguna operación matemática que pueda realizar lo mismo que este programa:
if (NumeroReal>0)
return (NumeroReal);
else
return (0)
El objetivo es que si el número es positivo, me quedo con él, pero si es negativo tengo que obtener un 0.
He estado dándole vueltas con multiplicaciones por -1, con valores absolutos, pero no encuentro la manera.
No entiendo por qué lo querés implementar con operaciones mateméticas. Si es una inquietud... perfecto! Pero fuera de eso son puras desventajas pues las operaciones en punto flotante consumen mas recursos y demoran mucho mas que las enteras o lógicas.
A modo de ejemplo, cada línea hace lo mismo, pero una con un número positivo y la siguiente con uno negativo.
A la derecha están los ciclos que demora cada una.
#include<18F4550.h>
#use delay(internal=4MHz)
float xn=-2.445 ,xp=34.23 , y1 ;
void main(void){
// Usando operaciones en punto flotante
// Cuantas mas sean... mas tiempo
y1 = (xp+abs(xp))/2. ; // 1157 ciclos
y1 = (xn+abs(xn))/2. ; // 217 ciclos
y1 = (xp/2+abs(xp)/2) ; // 2150 ciclos
y1 = (xn/2+abs(xn)/2) ; // 2118 ciclos
// Usando solo una multiplicacion
y1 = xp*(xp>0) ; // 253 ciclos
y1 = xn*(xn>0) ; // 96 ciclos
// Sin multiplicaciones ni sumas
y1 = xp>0 ? xp : 0 ; // 52 ciclos
y1 = xn>0 ? xn : 0 ; // 42 ciclos
// Eliminando todas las operaciones en punto flotante
// salvo la asignación
//
// El #define testea el bit de signo de la variable
// (formato Microchip)
#define GT0(x) !(*(byte*)(&x+1)&0x80)
y1 = GT0(xp) ? xp : 0 ; // 24 ciclos
y1 = GT0(xn) ? xn : 0 ; // 19 ciclos
if(GT0(xp)) y1=xp ; else y1=0 ; // 16 ciclos
if(GT0(xn)) y1=xn ; else y1=0 ; // 14 ciclos
// Se el ajuste se debe hacer sobre la misma variable
// solamente hay que dejarla en 0 si es negativa
if(!GT0(xp)) xp=0 ; // 10 ciclos
if(!GT0(xn)) xn=0 ; // 13 ciclos
}
Salvo el #define que es medio críptico, el resto de las expresiones es igualmente legible.
-
Pues lo necesitaba porque no podía meter una condición IF dentro de una cláusula SQL de InfluxDB.
La idea es representar en Grafana la energía que mis placas fotovoltaicas entregan a la red (excedente), pero no quiero que la gráfica dibuje la parte negativa, cuando mi consumo excede mi producción de energía.
(https://i.imgur.com/VeTFeU0.jpeg)
-
Por lo que vi InfluxDB tiene condicionales como if, y tambien otros como filter() que permite poner una condicion.
-
¡Qué bueno!, pues no lo había investigado. Gracias Killer