Get Percentage of 2 decimals - php

Seems simple but can't figure this out:
$goal = 10.000;
$actual = 55.32;
$percentChange = number_format(( $actual / $goal) * 100, 2);
echo $percentChange;
OUTPUT
553.20
WANTED OUTPUT
0.5532
The problem occurs only when output is less than 1 0.XXXX code is working fine from 1 above.

Remove the dot in $goal variable as is taking it as 10 with 4 decimals
Change this:
$goal = 10.000;
$actual = 55.32;
$percentChange = number_format(( $actual / $goal) * 100, 2);
echo $percentChange;
To this:
$goal = 10000;
$actual = 55.32;
$percentChange = number_format(( $actual / $goal) * 100, 4);
echo $percentChange;

Related

PHP generate rgb color to object based on unique value

I know this has been asked before, but I need a little more help than the other answers on SO provide.
I currently have a foreach loop that iterates over records in my DB. Each row contains a unique "id" primary attribute (1,2,3,4,5,etc.).
In my loop, I need to generate a UNIQUE RGB value for each record based on its ID. The resulting RGB value will be applied to the HTML element's text bound to that record. The generated color must be unique to the record itself (via "id"), which is why I am not using the loop iterator.
I have already created a working function to do this for me, but I need one more thing - I need the rgb value to have a contrast ratio greater than 4:5:1 on a white background. The function I have generates colors that are too bright, making the text hard to read. How can I modify my function to produce darker colors that contrast well on a white background?
function makeRgbFromValue(int $value){
$hash = md5($value);
return implode(", ", [
hexdec(substr($hash, 0, 2)), // r
hexdec(substr($hash, 2, 2)), // g
hexdec(substr($hash, 4, 2)) // b
]);
}
// Example output: "100, 201, 20"
// My html, using Laravel Blade syntax:
#foreach($categories as $cat)
<a
href="/blog/channels/{{ $cat->slug }}"
style="color: rgb(
{{ makeRgbFromValue($cat->id) }}
)"
>
{{ $cat->name }}
</a>
#endforeach
Maybe this isnt possible... but I'm hoping one of you Math geniuses can help me out :)
You can calculate brightness:
function lumdiff($R1,$G1,$B1,$R2,$G2,$B2){
$L1 = 0.2126 * pow($R1/255, 2.2) +
0.7152 * pow($G1/255, 2.2) +
0.0722 * pow($B1/255, 2.2);
$L2 = 0.2126 * pow($R2/255, 2.2) +
0.7152 * pow($G2/255, 2.2) +
0.0722 * pow($B2/255, 2.2);
if($L1 > $L2){
return ($L1+0.05) / ($L2+0.05);
}else{
return ($L2+0.05) / ($L1+0.05);
}
}
The returned value should be bigger than 5 for best readability.
Function was found here
But you should get another chars from a hash to get another color, so collision more probable.
function makeRgbFromValue($value){
$hash = md5($value);
$brightness = 0;
$shift = 0;
while($brightness < 5 && $shift<26) {
$color = [
hexdec(substr($hash, $shift, 2)), // r
hexdec(substr($hash, $shift+2, 2)), // g
hexdec(substr($hash, $shift+4, 2)) // b
];
$brightness = lumdiff($color[0], $color[1], $color[2], 255,255,255);
$shift++;
}
return implode(", ", $color);
}
I believe that a color will be found in 25 cycles :)
While it's a pain to translate, HSV is probably a better color space for this. I like to pick a set Saturation [0.75 is nice] and then play with the Hue and Value.
Lifting the HSV/RGB conversion function from this gist:
function HSV_TO_RGB ($H, $S, $V) {
$RGB = array();
if($S == 0) {
$R = $G = $B = $V * 255;
} else {
$var_H = $H * 6;
$var_i = floor( $var_H );
$var_1 = $V * ( 1 - $S );
$var_2 = $V * ( 1 - $S * ( $var_H - $var_i ) );
$var_3 = $V * ( 1 - $S * (1 - ( $var_H - $var_i ) ) );
if ($var_i == 0) { $var_R = $V ; $var_G = $var_3 ; $var_B = $var_1 ; }
else if ($var_i == 1) { $var_R = $var_2 ; $var_G = $V ; $var_B = $var_1 ; }
else if ($var_i == 2) { $var_R = $var_1 ; $var_G = $V ; $var_B = $var_3 ; }
else if ($var_i == 3) { $var_R = $var_1 ; $var_G = $var_2 ; $var_B = $V ; }
else if ($var_i == 4) { $var_R = $var_3 ; $var_G = $var_1 ; $var_B = $V ; }
else { $var_R = $V ; $var_G = $var_1 ; $var_B = $var_2 ; }
$R = $var_R * 255;
$G = $var_G * 255;
$B = $var_B * 255;
}
$RGB['R'] = $R;
$RGB['G'] = $G;
$RGB['B'] = $B;
return $RGB;
}
And then:
$fmt = '<span style="background-color: #%s" title="%s">%s</span>' . "\n";
$fill = str_repeat(' ', 5);
$S = 0.75;
for($i=0; $i<25; $i++) {
$hash = md5(mt_rand());
$H = hexdec(substr($hash, 0, 2))/255;
$V = ( hexdec(substr($hash, 2, 2))/255 ) / 2 + 0.5; // pick from the brighter half
$rgb = implode('', array_map(
function($a){
return str_pad(dechex(intval($a)), 2, '0', STR_PAD_LEFT);
}, HSV_TO_RGB($H, $S, $V)));
printf($fmt, $rgb, sprintf("HSV(%0.2f,%0.2f,%0.2f)", $H, $S, $V), $fill);
}
Gives us something like:

Maths in php giving wrong answer

I have a simple equation written in PHP. I have tried to replicate the equation bellow.
When I work out the Equation on pager using the variables I have provided in the PHP I get 2,467.86 (using equation A).
But when I run it in PHP I get 4,2267.11, where have I gone wrong in my PHP ?
Equation A
PHP Equation
<?php
$p = 0;
$i = 0.06;
$c = 12;
$n = 1;
$r = 200;
$x = $i / $c;
$y = pow((1 + $x), ($n * $c));
$vf = $p * $y + (($r * $y - 1) / $x);
?>
<p>Answer:<?php echo $vf; ?></p>
Here:
$vf = $p * $y + ($r * ($y - 1) / $x);
// outputs 2467.1124745799
Your equation was:
$vf = $p * $y + (($r * $y - 1) / $x); // <- NOT $r*$y -1 , but $r*($y-1)
You can see it here - 3v4l

Getting the weight(percentage) of 1 variable from 3 numbers

I am building a feedback system: positive, neutral and nagative, I want to get the positive percentage somehow.
$positive = 4;
$neutral = 1;
$negative = 1
So I am trying to get something like 50%. I have tried
$positive / $neutral + $negative;
$positive / $neutral + $negative * 10;
None seem to get the right value.
This should work for you:
<?php
$positive = 4;
$neutral = 1;
$negative = 1;
$total = $positive + $neutral + $negative;
$percentage = ($positive - $negative) / $total * 100;
echo sprintf("%02.2f%%", $percentage);
?>
Output:
50.00%
EDIT:
If you want to count $neutral to positive feedback use this:
$total = $positive + $neutral + $negative;
$percentage = ($positive + $neutral - $negative) / $total * 100;
echo sprintf("%02.2f%%", $percentage);

PHP Round function - round up to 2 dp?

In PHP how would i round up the value 22.04496 so that it becomes 22.05? It seems that
round(22.04496,2) = 22.04. Should it not be 22.05??
Thanks in advance
you can do it using ceil and multiplying and dividing by a power of 10.
echo ceil( 1.012345 * 1000)/1000;
1.013
Do not do multiplication inside a ceil, floor or round function! You'll get floating point errors and it can be extremely unpredictable. To avoid this do:
function ceiling($value, $precision = 0) {
$offset = 0.5;
if ($precision !== 0)
$offset /= pow(10, $precision);
$final = round($value + $offset, $precision, PHP_ROUND_HALF_DOWN);
return ($final == -0 ? 0 : $final);
}
For example ceiling(2.2200001, 2) will give 2.23.
Based on comments I've also added my floor function as this has similar problems:
function flooring($value, $precision = 0) {
$offset = -0.5;
if ($precision !== 0)
$offset /= pow(10, $precision);
$final = round($value + $offset, $precision, PHP_ROUND_HALF_UP);
return ($final == -0 ? 0 : $final);
}
The round function of PHP can handle an additional argument, which controls how the rounding is done: http://php.net/manual/en/function.round.php
Examples from the link:
echo round(9.5, 0, PHP_ROUND_HALF_UP); // 10
echo round(9.5, 0, PHP_ROUND_HALF_DOWN); // 9
echo round(9.5, 0, PHP_ROUND_HALF_EVEN); // 10
echo round(9.5, 0, PHP_ROUND_HALF_ODD); // 9
I think the best way:
echo ceil(round($value * 100)) / 100;
Example:
$value = 77.4;
echo ceil($value * 100) / 100; // 77.41 - WRONG!
echo ceil(round($value * 100)) / 100; // 77.4 - OK!
It's not working well.
round(1.211,2,PHP_ROUND_HALF_UP);
// Res: 1.21
My Solution:
$number = 1.211;
echo myCeil($number,2);
function myCeil($number,$precision = 0){
$pow = pow(10,$precision);
$res = (int)($number * $pow) / $pow;
if($number > $res){
$res += 1 / $pow;
}
return $res;
}
// Res 1.22
Why should it be 22.05? The third decimal is less than 5, hence when you round it to 2 decimal precision it's rounded down to 22.04

Rounding to the Nearest Ending Digits

I have the following function that rounds a number to the nearest number ending with the digits of $nearest, and I was wondering if there is a more elegant way of doing the same.
/**
* Rounds the number to the nearest digit(s).
*
* #param int $number
* #param int $nearest
* #return int
*/
function roundNearest($number, $nearest, $type = null)
{
$result = abs(intval($number));
$nearest = abs(intval($nearest));
if ($result <= $nearest)
{
$result = $nearest;
}
else
{
$ceil = $nearest - substr($result, strlen($result) - strlen($nearest));
$floor = $nearest - substr($result, strlen($result) - strlen($nearest)) - pow(10, strlen($nearest));
switch ($type)
{
case 'ceil':
$result += $ceil;
break;
case 'floor':
$result += $floor;
break;
default:
$result += (abs($ceil) <= abs($floor)) ? $ceil : $floor;
break;
}
}
if ($number < 0)
{
$result *= -1;
}
return $result;
}
Some examples:
roundNearest(86, 9); // 89
roundNearest(97, 9); // 99
roundNearest(97, 9, 'floor'); // 89
Thanks in advance!
PS: This question is not about rounding to the nearest multiple.
This works for me:
function roundToDigits($num, $suffix, $type = 'round') {
$pow = pow(10, floor(log($suffix, 10) + 1));
return $type(($num - $suffix) / $pow) * $pow + $suffix;
};
$type should be either "ceil", "floor", or "round"
I think this should work, and it's more elegant to me, at least:
function roundNearest($number, $nearest, $type = null)
{
if($number < 0)
return -roundNearest(-$number, $nearest, $type);
$nearest = abs($nearest);
if($number < $nearest)
return $nearest;
$len = strlen($nearest);
$pow = pow(10, $len);
$diff = $pow - $nearest;
if($type == 'ciel')
$adj = 0.5;
else if($type == 'floor')
$adj = -0.5;
else
$adj = 0;
return round(($number + $diff)/$pow + $adj)*$pow - $diff;
}
Edit: Added what I think you want from negative inputs.

Categories