Obter maior valor negativo

Boa noite. Algum dos senhores conhece ou já possui uma função que retorne o maior valor negativo entre três números?

Algo muito parecido com a solução dessa postagem, voltado para o excel:

Basicamente, tenho três números e preciso retornar o maior valor negativo.
A princípio usei a função max

int a = max(max(x,y),z)

Essa função só funciona caso todos os valores (x, y e z) sejam negativos. Se um deles for positivo, então esse valor é que será retornado, e isso é um problema.

Para contornar a situação, fiz lógicas com if (que funciona, mas queria evitar, por isso abri o tópico)

if (x < 0 && y < 0 && z < 0) { //Todos os valores negativos
    a = max(max(x, y), z);
  } else if (x < 0 && y < 0 && z > 0) { //Valores x e y negativos
    a = max(x, y);
  } else if (x < 0 && y > 0 && z < 0) { //Valores x e z negativos
    a = max(x, z);
  } else if (x > 0 && y < 0 && z < 0) { //Valores y e z negativos
    a = max(y, z);
  } else if (x < 0 && y > 0 && z > 0) { //Apenas valor x negativo
    a = x;
  } else if (y < 0 && x > 0 && z > 0) { //Apenas valor y negativo
    a = y;
  } else if (z < 0 && x > 0 && y > 0) { //Apenas valor z negativo
    a = z;
  }

Exemplo de aplicação prática (caso queiram saber o motivo disso tudo):

Imagine um sistema de despertador, que tem três horários programados por dia.
O arduino fica em modo sleep, e desperta quando o alarme do RTC (modelo DS3231) dispara. Esse alarme é configurado para quando o horário atual == horário programado.
Depois que o alarme desperta, o arduino retornará ao modo sleep, mas antes, precisa atualizar o horário do próximo alarme, e para isso, precisa saber qual é o próximo horário programado.
Para saber qual é o próximo horário programado faz-se uma subtração entre horário atual e horário programado 1, 2 e 3 (vulgo x, y e z usados acima).
O resultado dessa subtração determina qual é o próximo horário a ser definido no alarme do RTC. Se o resultado for negativo, significa que esse horário programado ainda não foi disparado hoje. Se for positivo, significa que esse horário já foi disparado hoje. Ou seja, priorizo os valores negativos, e procuro pelo maior (mais próximo de 0). Caso todos sejam positivos, aí procuro pelo maior entre eles (o que corresponderia ao primeiro alarme do dia seguinte).

tl;dr Função ou forma de obter o maior valor NEGATIVO entre três números inteiros aleatórios com valores de -x à +x

Se calhar sou eu que não sei muito, mas o maior número negativo, não será por acaso o menor número absoluto??

-5< -2 < -1 < 0 < 3 < 6 e por aí adiante?

Desculpe, não consegui entender muito bem.

Se eu tiver (-5, -3, 1), o menor número absoluto não será 1? Porém o maior número negativo é -3.

Não.

O menor número desses todos é o -5. Logo se fizeres min(-5, (min(-3,1)) vais ter o que pretendes.

Se calhar absoluto não é bem a palavra correcta pois dá a entender que é o módulo do número.

Nada como experimentar... :wink:

Exatamente o que pensei quando disse absoluto.. Até fiz uns testes com a função abs(), que retorna o módulo do número. Mas não deu certo pra minha aplicação pois entra no problema que mencionei

Se eu tiver (-5, -3, 1), o menor número absoluto não será 1? Porém o maior número negativo é -3.

Desses três números (-5, -3 e 1), o menor é sim o -5, mas o que preciso é o maior número menor que 0, que é o -3 (acredito que isso é que tenha ficado confuso), ou seja, o número negativo mais próximo de 0..

Com a função min(), vai retornar -5, e com a função max(), vai retornar 1.. A função max() só funcionaria se todos os três números fossem negativos.

O que tu pretendes não existe já feito pois não há grande utilidade para uma função dessas.

Então vais mesmo ter de criar uma. Dependendo do que estás à procura eu aconselharia a usar vectores para procurar os números. Muito mais fácil do que com variáveis soltas.

Entendo.. Acabei por fazer algo genérico, que serviria pra qualquer quantidade de valores a ser analisado, usando seu conselho de trabalhar com vetores.

Mas é como você disse, não é uma função muito útil.. Para minha aplicação, o uso dos IFs teriam me consumido muito menos tempo.

int valores[] = {-8, -10, 16, 14};
int sizeValores = sizeof(valores) / sizeof(valores[0]);
int sizeValoresNegativos = 0;
int resultado;

void setup() {

  Serial.begin(9600);

  //CONTA QUANTOS NÚMEROS NEGATIVOS TEM
  for (int i = 0; i < sizeValores; i++) {
    if (valores[i] < 0) {
      sizeValoresNegativos++;
    }
  }

  int valoresNegativos[sizeValoresNegativos];

  //SE NÃO HÁ VALOR NEGATIVO
  if (sizeValoresNegativos == 0) {
    for (int i = 0; i < (sizeValores - 1); i++) {
      if (i == 0) {
        resultado = valores[i];
      }
      resultado = min(resultado, valores[i + 1]);
    }
  } else { //CASO TENHA ALGUM VALOR NEGATIVO
    //PREENCHE VETOR DE VALORES NEGATIVOS
    for (int i, j = 0; i < sizeValores; i++) {
      if (valores[i] < 0) {
        valoresNegativos[j] = valores[i];
        j++;
      }
    }

    //OBTER RESULTADO

    //SE SÓ HOUVER UM VALOR NEGATIVO
    if (sizeValoresNegativos == 1) {
      resultado = valoresNegativos[0];
    } else {
      for (int i = 0; i < (sizeValoresNegativos - 1); i++) {
        if (i == 0) {
          resultado = valoresNegativos[i];
        }
        resultado = max(resultado, valoresNegativos[i + 1]);
      }
    }
  }

  Serial.print("Resultado: ");
  Serial.print(resultado);

}

void loop() {
}

Não sei se foi o melhor caminho, mas basicamente:

Conto quantos números negativos tem no vetor 1
Crio o vetor 2 com o tamanho obtido anteriormente
Movo todos os valores negativos do vetor 1 para o vetor 2
Faço uma varredura no vetor 2 e com a função max(), obtenho o resultado

Boas,
Para desenferrujar fui tentar fazer em C ...

#include <stdio.h>
int getMin(int *array, int size);
int main() {
    int valores[] = {-40, 1, -5, -199, 78};
    printf("Lower value is %d", getMin(valores, sizeof(valores)));
    return 0;
}

int getMin(int *array, int size) {
     int minValue = 0;
     int evaluated = 0;
    for (int i = 0; i < size; i++) {
        evaluated = array[i];
        if (evaluated < 0) {
            //A negative number is present ...
            if (minValue == 0)minValue = evaluated;
            //printf(" Number found %d \n", evaluated);
            if (evaluated > minValue) {
                minValue = evaluated;
            } else {
                continue;
            }
            minValue = evaluated;
        }
    }
    return minValue;
}

Com o vector que atribui o resultado dá o numero negativo mais proximo de 0 que neste caso é -5

Uma forma mais simples e lógica que a minha. Menos confusa.

Espero que sirva pra alguém algum dia..