How to leave a number always negative in php?

Asked

Viewed 290 times

2

I have an "A" and "B" rating. If it’s "A," I want the number to always be positive, if it’s "B," I want it to always be negative.

I’m using a code in this logic:

if($classificacao==="A") 
    $sinal="abs";
elseif($classificacao==="B") 
    $sinal="-1*abs";

And the number is written the way: $valor_final = $sinal($valor);

However, in doing so, it causes the following error:

"Fatal error: Call to Undefined Function -1*abs()".

He recognizes as if -1*abs is a non-existent function. Already in case the "A" rating is working. Someone could help me?

2 answers

3

It seems to me to be a very inelegant solution and does not work precisely for the reason that the error says: PHP will try to interpret the value -1*abs as the function name. Not only will the function not exist, it is an invalid name. You could use eval, but gets as bad as and is completely unnecessary.

The simplest solution I see for your problem is to define only the multiplier within the if:

if ($classificacao === "A") {
    $sinal = 1;
} else {
    $sinal = -1;
}

Note: if you have only two ratings, you do not need to check that the value is equal to B when it is different from A.

And display the result as follows:

$valor_final = $sinal * abs($valor);

Obviously there are many variations of this code that produce the same result. For example:

$valor_final = abs($valor);

if ($classificacao === "B") {
    $valor_final *= -1;
}

Given the existence of the C rating, as stated in the comments, which should maintain the original value, something like:

function valueByClassification ($valor, $classificacao) {

    if ($classificacao === 'C') {

        $valor_final = $valor;

    } else {

        $valor_final = abs($valor);

        if ($classificacao === 'B') {
            $valor_final *= -1;
        }

    }

    return $valor_final;
}

I consider this form the best because you use only once the function abs in the code. In terms of performance it makes no difference, but in terms of code maintenance it is better, because if there is a need to change the function called, you need to do this in only one part of the code, not several.

See the function test below:

$tests = [
    // {valor}        {classificacao}        {esperado}
    [    5,                  'A',                5     ],    
    [   -3,                  'A',                3     ],
    [    0,                  'A',                0     ],    

    [    5,                  'B',               -5     ],    
    [   -3,                  'B',               -3     ],    
    [    0,                  'B',                0     ],    

    [    5,                  'C',                5     ],    
    [   -3,                  'C',               -3     ],    
    [    0,                  'C',                0     ],    
];

foreach($tests as $i => $test) {
    list($valor, $classificacao, $esperado) = $test;

    $obtido = valueByClassification($valor, $classificacao);

    if ($obtido === $esperado) {
        echo "Teste $i foi aprovado.", PHP_EOL;
    } else {
        echo "Teste $i foi reprovado. Era esperado {$esperado}, mas foi obtido {$obtido}.", PHP_EOL;
    }
}

See working on Ideone.

The output generated is:

Teste 0 foi aprovado.
Teste 1 foi aprovado.
Teste 2 foi aprovado.
Teste 3 foi aprovado.
Teste 4 foi aprovado.
Teste 5 foi aprovado.
Teste 6 foi aprovado.
Teste 7 foi aprovado.
Teste 8 foi aprovado.
  • I hastened the question, there is in my case a "C" rating in which it would leave the original value, so I could not put the "abs" outside the "$sign" variable. But with the use of the suggested function, I was able to solve the problem! Thank you!!

0

I would rewrite your code with this function:

function myFunction($classificacao, $valor){
    if($classificacao==="A") 
        $valor_final = abs($valor);
    elseif($classificacao==="B") 
        $valor_final = abs($valor)*(-1);

    return $valor_final;
}

Browser other questions tagged

You are not signed in. Login or sign up in order to post.