From: Rick Dwyer on 22 Jan 2010 14:24 Hello List. In an earlier post, I received help with a custom function to round decimals off (the custom function provided by Adam Richardson is below). However in my MySQL db, when I have values with only 1 decimal point, I need the value PHP returns to display as 2. For example, 3.8 needs to display as 3.80. My line of code that calls the custom function looks like this: $my_price = round_to_half_cent(number_format($my_price, 3, '.', ',')); When the value of $my_price is 3.81, it returns 3.81. However, when the value of $my_price is 3.8 that is what it returns. How can I force the formatting of my_price to always contain either 2 or 3 decimal points (3 if the original number contains 3 or more decimal points to begin with) Thanks, --Rick On Jan 11, 2010, at 10:39 PM, Adam Richardson wrote: > On Mon, Jan 11, 2010 at 7:45 PM, Mattias Thorslund <mattias(a)thorslund.us > >wrote: > >> tedd wrote: >> >>> At 2:55 PM -0500 1/11/10, Rick Dwyer wrote: >>> >>>> I have been asked to further modify the value to the nearest half >>>> cent. >>>> >>>> So if the 3rd decimal spot ends in 1 or 2, it gets rounded down >>>> to 0 >>>> If it ends in 3, 4, 5, 6 it gets rounded to 5. And if it 7, 8 or >>>> 9 it >>>> gets rounded up to full cents. >>>> >>>> Can this be done fairly easily? Not knowing PHP well, I am not >>>> aware of >>>> the logic to configure this accordingly. >>>> >>>> Thanks, >>>> --Rick >>>> >>> >>> >>> --Rick: >>> >>> The above described rounding algorithm introduces more bias than >>> simply >>> using PHP's round() function, which always rounds down. IMO, >>> modifying >>> rounding is not worth the effort. >>> >>> The "best" rounding algorithm is to look at the last digit and do >>> this: >>> >>> 0 -- no rounding needed. >>> 1-4 round down. >>> 6-9 round up. >>> >>> In the case of 5, then look to the number that precedes it -- if >>> it is >>> even, then round up and if it is odd, then round down -- or vise >>> versa, it >>> doesn't make any difference as long as you are consistent. >>> >>> Here are some examples: >>> >>> 122.4 <-- round down (122) >>> 122.6 <-- round up (123) >>> 122.5 <-- round up (123) >>> >>> 123.4 <-- round down (123) >>> 123.6 <-- round up (124) >>> 123.5 <-- round down (123) >>> >>> There are people who claim that there's no difference, or are at >>> odds with >>> this method, but they simply have not investigated the problem >>> sufficiently >>> to see the bias that rounding up/down causes. However, that >>> difference is >>> very insignificant and can only be seen after tens of thousands >>> iterations. >>> PHP's rounding function is quite sufficient. >>> >>> Cheers, >>> >>> tedd >>> >>> >> However that's not what Rick is asking for. He needs a function >> that rounds >> to the half penny with a bias to rounding up (greedy bosses): >> >> >> Actual Rounded Diff >> .011 .010 -.001 >> .012 .010 -.002 >> .013 .015 +.002 >> .014 .015 +.001 >> .015 .015 .000 >> .016 .015 -.001 >> .017 .020 +.003 >> .018 .020 +.002 >> .019 .020 +.001 >> .020 .020 .000 >> Bias +.005 >> >> This could easily be implemented by getting the 3rd decimal and >> using it in >> a switch() statement. >> >> An unbiased system could look like: >> >> Actual Rounded Diff >> .011 .010 -.001 >> .012 .010 -.002 >> .013 .015 +.002 >> .014 .015 +.001 >> .015 .015 .000 >> .016 .015 -.001 >> .017 .020 -.002 >> .018 .020 +.002 >> .019 .020 +.001 >> .020 .020 .000 >> Bias .000 >> >> The only difference is the case where the third decimal is 7. >> >> Cheers, >> >> Mattias >> >> >> -- >> PHP General Mailing List (http://www.php.net/) >> To unsubscribe, visit: http://www.php.net/unsub.php >> >> > Here you go, Rick. Just send the check in the mail ;) > > function round_to_half_cent($amount) > { > if (!is_numeric($amount)) throw new Exception('The amount received > by the > "round_to_half_cent" function was not numeric'); > $parts = explode('.', str_replace(',', '', (string)$amount)); > if (count($parts) >= 3) throw new Exception('The amount received by > the > "round_to_half_cent" function had too many decimals.'); > if (count($parts) == 1) > { > return $amount; > } > $digit = substr($parts[1], 2, 1); > if ($digit == 0 || $digit == 1 || $digit == 2) > { > $digit = 0; > } > elseif ($digit == 3 || $digit == 4 || $digit == 5 || $digit == 6) > { > $digit = .005; > } > elseif ($digit == 7 || $digit == 8 || $digit == 9) > { > $digit = .01; > } > else > { > throw new Exception('OK, perhaps we are talking about different > types of > numbers :( Check the input to the "round_to_half_cent" function.'); > } > return (double)($parts[0].'.'.substr($parts[1], 0, 2)) + $digit; > } > > echo "5.002 = ".round_to_half_cent(5.002); > echo "<br />70,000.126 = ".round_to_half_cent("70000.126"); > echo "<br />55.897 = ".round_to_half_cent(55.897); > // should cause exception > echo "<br />One hundred = ".round_to_half_cent("One hundred"); > > -- > Nephtali: PHP web framework that functions beautifully > http://nephtaliproject.com --Rick
From: tedd on 22 Jan 2010 16:24 >Hello List. > >In an earlier post, I received help with a custom function to round >decimals off (the custom function provided by Adam Richardson is >below). > >However in my MySQL db, when I have values with only 1 decimal >point, I need the value PHP returns to display as 2. For example, >3.8 needs to display as 3.80. > >My line of code that calls the custom function looks like this: > >$my_price = round_to_half_cent(number_format($my_price, 3, '.', ',')); > >When the value of $my_price is 3.81, it returns 3.81. However, when >the value of $my_price is 3.8 that is what it returns. > >How can I force the formatting of my_price to always contain either >2 or 3 decimal points (3 if the original number contains 3 or more >decimal points to begin with) > > >Thanks, > >--Rick Rick: Okay so 3.8 is stored in the database and not as 3.80 -- but that's not a problem. What you have is a display problem so use one of the many PHP functions to display numbers and don't worry about how it's stored. Cheers, tedd -- ------- http://sperling.com http://ancientstones.com http://earthstones.com
From: Rick Dwyer on 22 Jan 2010 16:45 On Jan 22, 2010, at 4:24 PM, tedd wrote: >> Hello List. >> >> In an earlier post, I received help with a custom function to round >> decimals off (the custom function provided by Adam Richardson is >> below). >> >> However in my MySQL db, when I have values with only 1 decimal >> point, I need the value PHP returns to display as 2. For example, >> 3.8 needs to display as 3.80. >> >> My line of code that calls the custom function looks like this: >> >> $my_price = round_to_half_cent(number_format($my_price, 3, '.', >> ',')); >> >> When the value of $my_price is 3.81, it returns 3.81. However, >> when the value of $my_price is 3.8 that is what it returns. >> >> How can I force the formatting of my_price to always contain either >> 2 or 3 decimal points (3 if the original number contains 3 or more >> decimal points to begin with) >> >> >> Thanks, >> >> --Rick > > > Rick: > > Okay so 3.8 is stored in the database and not as 3.80 -- but that's > not a problem. What you have is a display problem so use one of the > many PHP functions to display numbers and don't worry about how it's > stored. Hi Ted. This is exactly what I am trying to do, some of the values in the DB are going to have 3 decimals, some 2 and some 1. On my page I pull the value from the db with: $my_price = $row['my_price']; This returns 3.80... even though my db has it as 3.8. No problem. But once I run the variable $my_price through the following line of code, it is truncating the 0: $my_price = round_to_half_cent(number_format($my_price, 3, '.', ',')); Again, the above call to the custom function works fine for 2 and 3 decimal points.... just not 1 decimal point. Because I call this function over many pages, I would prefer if possible to fix it at the custom function level rather than recode each page. But I will do whatever is necessary. I afraid with my current understanding of PHP I am not able to successfully modify the custom function to tack on a 0 when the decimal place is empty. Will keep trying and post if I am successful Thanks, --Rick I'm afraid with my current understanding of PHP, I am not able to come up with the logic to --Rick
From: Nathan Rixham on 22 Jan 2010 19:30 Rick Dwyer wrote: > > On Jan 22, 2010, at 4:24 PM, tedd wrote: > >>> Hello List. >>> >>> In an earlier post, I received help with a custom function to round >>> decimals off (the custom function provided by Adam Richardson is below). >>> >>> However in my MySQL db, when I have values with only 1 decimal point, >>> I need the value PHP returns to display as 2. For example, 3.8 needs >>> to display as 3.80. >>> >>> My line of code that calls the custom function looks like this: >>> >>> $my_price = round_to_half_cent(number_format($my_price, 3, '.', ',')); >>> your doing the number format before the rounding.. here's a version of the function that should fit the bill: function round_to_half_cent( $value ) { $value *= 100; if( $value == (int)$value || $value < ((int)$value)+0.3 ) { return number_format( (int)$value/100 , 2); } else if($value > ((int)$value)+0.6) { return number_format( (int)++$value/100 , 2); } return number_format( 0.005+(int)$value/100 , 3); } echo round_to_half_cent( 12.1 ); // 12.10 echo round_to_half_cent( 12.103 ); // 12.105 echo round_to_half_cent( 12.107 ); // 12.11 echo round_to_half_cent( 123456.789 ); // 123,456.79
From: Rick Dwyer on 22 Jan 2010 19:57 On Jan 22, 2010, at 7:30 PM, Nathan Rixham wrote: Thanks Nathan I'll give it a shot. --Rick >>>> > > your doing the number format before the rounding.. here's a version of > the function that should fit the bill: > > function round_to_half_cent( $value ) > { > $value *= 100; > if( $value == (int)$value || $value < ((int)$value)+0.3 ) { > return number_format( (int)$value/100 , 2); > } else if($value > ((int)$value)+0.6) { > return number_format( (int)++$value/100 , 2); > } > return number_format( 0.005+(int)$value/100 , 3); > } > > > echo round_to_half_cent( 12.1 ); // 12.10 > echo round_to_half_cent( 12.103 ); // 12.105 > echo round_to_half_cent( 12.107 ); // 12.11 > echo round_to_half_cent( 123456.789 ); // 123,456.79 > >
|
Next
|
Last
Pages: 1 2 Prev: Help on compiling PHP for MIPS, Bus Error thrown Next: Weird Array Issue... |