-3

I write a logic to round value based on fraction part value. When i execute this code, elseif block is not executed. Here is my code

<?php

    function roundRating($rating)
   {

    if($rating>=5 && $rating<0){
             $rating=0;
         }

        $a=(int)$rating/1;
        $b= $rating-$a;

        if(($b>=.1) && ($b<=.2)){
            $b=0;
            $rating=$a;
        }
        elseif(($b>=.3 && $b<=.4)|| ($b>=.6 && $b<=.7)){
            $b=.5;
            $rating=$a+$b;
        }
        elseif(($b>=.8) && ($b<=.9)){
            $b=1;
            $rating=$a+$b;
            $a=$rating;
        }
        else{}


         return $rating;       
   }

  echo  roundRating(3.3);
?>

for this value 3.3, the output should be 3.5. But currently it will return passed value 3.3 instead of 3.5. Kindly help me to find out the problem in the above code. Thanks in advance.

Janaki
  • 145
  • 2
  • 16
  • Have you checked value of `$b`? Is it what you expect? – u_mulder May 15 '16 at 08:59
  • I check your functions, No conditions met for your value. [Online Check](https://3v4l.org/FUeWZ) – Murad Hasan May 15 '16 at 09:08
  • 3
    `$rating>=5 && $rating<0` is always false - use `or` instead – splash58 May 15 '16 at 09:08
  • @Frayne Konok then his code will work. right or not - i don't now. But now all if statement maybe removed at all – splash58 May 15 '16 at 09:18
  • @FrayneKonok The first if-statement is just plain wrong, because `$rating` can never be greater than or equal to 5 and less than zero at the same time! – Oldskool May 15 '16 at 09:21
  • Also `$a=(int)$rating/1;` --> a number divisible by 1 is always the original number, so not sure what that line of code is trying to achieve. – Mantis Support May 15 '16 at 09:21
  • @splash58, You got a good point. It must be `OR`. – Murad Hasan May 15 '16 at 09:26
  • @Mantis Team, the reason for this $a=(int)$rating/1; is i am splitting whole value. I want to print the star based on whole value. Assume my $a vlaue is 3, i want to print 3 full yellow shaded star and my $b value is .5 i want to print half yellow shaded star. – Janaki May 15 '16 at 09:38

6 Answers6

1

I've done my own version of the function which might be cleaner, and i think generates the output required:

 function roundRating($rating) {
    if( $rating > 5) {
          return 5; // Note: assuming the >5 case of 0 was a bug and it was meant to cap it to 5
    } elseif( $rating < 0 ) {
          return 0;
    }

    $number = floor($rating);
    $remainder =  $rating * 10 % 10;

    if( $remainder <= 2 ) {
      return $number;
    } elseif( $remainder >= 8 ) {
      return $number + 1;
    } else {
      return $number + 0.5;
    }
  }

  echo roundRating(3.4); // 3.5
  echo roundRating( 3.0) ; // 3
  echo roundRating( 6) ; // 5
  echo roundRating( 3.8) ; // 4
Mantis Support
  • 344
  • 2
  • 6
1

Please follow the following code given bellow.we some times face problem in floating value comparison. So, it is useful to specify how much number we will consider after decimal point. In the following code value of b is specified that it takes only 3 numbers after decimal point.

For details please visit: is-floating-point-math-broken

To check online please visit: Online check

    function roundRating($rating)
   {

    if($rating>=5 && $rating<0){
             $rating=0;
         }

        $a=(int)$rating/1;
        $b= sprintf('%3f',$rating-$a);

        if(($b>=.1) && ($b<=.2)){
            $b=0;
            $rating=$a;
        }
        elseif(($b>=.3 && $b<=.4)|| ($b>=.6 && $b<=.7)){
            $b=.5;
            $rating=$a+$b;
        }
        elseif(($b>=.8) && ($b<=.9)){
            $b=1;
            $rating=$a+$b;
            $a=$rating;
        }
        else{}


        return $rating;       
   }

   echo roundRating(3.3); // 3.5
?>
Community
  • 1
  • 1
Arzon Barua
  • 494
  • 7
  • 11
0

Floating point numbers have hidden/limited precision in C - so you can't trust them to the last digit. There's more of a writeup on this at http://php.net/manual/en/language.types.float.php

If you were to round it to 1 decimal place, you'll get 3.5:

$b= round($rating-$a, 1);
Mantis Support
  • 344
  • 2
  • 6
0

Replace your code with below code.

<?php

    function roundRating($rating)
    {

        if($rating >= 5 && $rating < 0){
            $rating=0;
        }
        else
        {
            $a=(int)$rating/1;
            $b= $rating-$a;
            echo $a ."</br>";
            echo $b."</br>";
            if(($b >= 0.1) && ($b <= 0.2)){
                $b=0;

                $rating=$a;
            }
            elseif(($b >=0.3 || $b<=0.4) && ($b>=0.6 || $b<=0.7)){
                $b=.5;
                $rating=$a+$b;
            }
            elseif(($b>=.8) || ($b<=.9)){
                $b=1;
                $rating=$a+$b;
                $a=$rating;
            }
            else{}
        }

        return $rating;       
    }

    echo  roundRating(3.3);
?>

Here i have did two change first add else condition your rating calculation work if $rating is not greater than 5 or less than 0. and second in one of your else if condition is change which is given below.

elseif(($b >=0.3 || $b<=0.4) && ($b>=0.6 || $b<=0.7)){
           //echo "here";
            $b=.5;
            $rating=$a+$b;
        }

i hope it will helps you.

Denis Bhojvani
  • 817
  • 1
  • 9
  • 18
0

To start with :

if($rating>=5 && $rating<0)

will always be false . A variable can't be greater than 5 and less than 0 at the same time.

Regarding

elseif(($b>=.3 && $b<=.4)|| ($b>=.6 && $b<=.7)){
        $b=.5;
        $rating=$a+$b;
    } 

what practical differece would it make with :

elseif(($b>=.3 && $b<=.7)){
        $b=.5;
        $rating=$a+$b;
    }

unless you write :

else{
     $rating+=some_value;// forthe inifinite number of values between .4 & .6?
}

Regarding,

elseif(($b>=.8) && ($b<=.9)){
        $b=1;
        $rating=$a+$b;
        $a=$rating; // This statement is redundant
    }

Since you return $rating from the function, $a=$rating; is redundant.

Having said the above things, I feel below would be a much simpler implementation, with results almost identical to desired one :

<?php
function round_rating($rating){

    if($rating<0 || $rating>5){
        $rating=0;
        return $rating;
    }
    $t_rating=(int)$rating; //$t_rating short for trimmed_rating :)
    $dif=$rating-$t_rating; //$dif is the short for difference :)

    if($dif <= .2){
        return($t_rating);
    }
    elseif($dif <= .7){
        return((float)$t_rating+.5);
    }
    else{
        return((float)$t_rating+1); 
    }
} // round_rating function ends here :)

 /*Test time*/

 printf("Round rating for %0.2f : %0.2f\n",6,round_rating(6));
 printf("Round rating for %0.2f : %0.2f\n",0.2,round_rating(0.2));  
 printf("Round rating for %0.2f : %0.2f\n",1.4,round_rating(1.4));      
 printf("Round rating for %0.2f : %0.2f\n",2.8,round_rating(2.8));
 printf("Round rating for %0.2f : %0.2f\n",4.6,round_rating(4.6));
 printf("Round rating for %0.2f : %0.2f\n",-1,round_rating(-1));        

?>

Output :

Round rating for 6.00 : 0.00
Round rating for 0.20 : 0.00
Round rating for 1.40 : 1.50
Round rating for 2.80 : 3.00
Round rating for 4.60 : 4.50
Round rating for -1.00 : 0.00
sjsam
  • 21,411
  • 5
  • 55
  • 102
  • You got a point, but here is another problem, there are several `if`, `else if` statements, there is the possibility to meet more than one statement true at the same time. So need a return on each conditions. I make a answer with checking all of them. – Murad Hasan May 15 '16 at 09:30
  • @FrayneKonok : I am on it pal.. Will be back shortly..:) – sjsam May 15 '16 at 09:32
  • @FrayneKonok No two conditions in the original code can be true at the same time.. – sjsam May 15 '16 at 10:01
  • My head stuck doing these and some other work, so i can't figure out why these not work, so i quite. – Murad Hasan May 15 '16 at 10:05
0

Thank you all for your answers. Finally i got the answer. Here is my answer.

function roundRating($rating)
   {
   if($rating>5 ){
        $rating=0;
        return $rating;   
    }
    elseif($rating<=0)
    {
        $x=0;
        return $rating;   
    }
    $a=(int)$rating/1;
    $b= $rating-$a;

    $b= (int)round(($b*10),0); 

      if($b<=2)
      {
          $rating=$a;
            return $rating;   
      }
      elseif($b>=3 && $b<=7){
          $rating=$a+.5;
            return $rating;   
      }
      elseif($b>=8){
          $rating=$a+1;
            return $rating;   
      }
      else{}
}


echo roundRating(3.2); //3
echo roundRating(3.3); //3.5
echo roundRating(3.7);  //3.5
echo roundRating(3.8); //4
Janaki
  • 145
  • 2
  • 16