I need to return a result of (1 / n!) * (1! + 2! + 3! + ... + n!), n>=1.
This is a CodeWars challenge! The code below returns 1.146652 for n = 8, but the correct result is 1.1466510000000001 or 1.146651.
How can I truncate this number correctly?
function factorial($val){
$factor = 1;
for($i=1;$i<=$val;$i++){
$factor *= $i;
}
return $factor;
}
function going($n) {
$val = 1/factorial($n);
$somatorio = 0;
for($i=1;$i<=$n;$i++){
$somatorio += factorial($i);
}
return round($val * $somatorio,6);
}
Related
I have next situation, I have some qty it can be very big or very small float like:
3698541.2569854 or 0.569875255456.
Also, I have some scale
or min step, like
0.0001 or 1000.00.
My challenge is round my qty to nearest down number by step. Example:
$qty = 323.659;
$step = 0.1;
// result must be 323.6
I have my own solution, it work well, but i have problem with wery large nums.
private function roundDownByStep($qty, $stepSize) {
$stepSize = sprintf('%.16f', $stepSize);
$stepSize = preg_replace('/|\\..+?\\K0+$/', "", $stepSize);
$precision = strlen(substr(strrchr($stepSize, "."), 1));
if ($precision == 1 && $stepSize >= 1) {
$precision = 0;
}
if ($precision == 0) {
$subArg = 1/$stepSize;
return floor(($qty * $subArg)) / $subArg;
} else {
$subArg = bcdiv('1', $stepSize, $precision);
$result = floor(bcmul($qty, $subArg, $precision));
$result = sprintf('%.16f', $result);
$result = preg_replace('/|\\..+?\\K0+$/', "", $result);
return bcdiv($result, $subArg, $precision);
}
}
You can try it on
http://sandbox.onlinephpfunctions.com/code/333f58c1487e86e53dde64c26930b57e1f9e0fe8
You are over complicating a simple task:
function cutAtPrecision($number, $precision) {
return intval($number * (1 / $precision)) / (1 / $precision);
}
echo cutAtPrecision(323.659, 0.01); // 323.65
I've been searching all over and cannot find anything about this.
I'm looking for a function that will convert a Z-Score to a Probability using a two tailed table, preferably in PHP.
(Like this one: http://www.sjsu.edu/faculty/gerstman/StatPrimer/z-two-tails.pdf)
My only other option is to make an array based on that table and comparing the Z-Score.. There must be a better way.
Edit:
Below is a slab of code found on the PHP.net statistics function page. These functions are really poorly documented.
The functions below will accurately calculate a one-tailed z-score into a probability.
function erf($x)
{
$pi = 3.1415927;
$a = (8*($pi - 3))/(3*$pi*(4 - $pi));
$x2 = $x * $x;
$ax2 = $a * $x2;
$num = (4/$pi) + $ax2;
$denom = 1 + $ax2;
$inner = (-$x2)*$num/$denom;
$erf2 = 1 - exp($inner);
return sqrt($erf2);
}
function cdf($n)
{
if($n < 0)
{
return (1 - erf($n / sqrt(2)))/2;
}
else
{
return (1 + erf($n / sqrt(2)))/2;
}
}
Found a solution:
function erf($x)
{
$pi = 3.1415927;
$a = (8*($pi - 3))/(3*$pi*(4 - $pi));
$x2 = $x * $x;
$ax2 = $a * $x2;
$num = (4/$pi) + $ax2;
$denom = 1 + $ax2;
$inner = (-$x2)*$num/$denom;
$erf2 = 1 - exp($inner);
return sqrt($erf2);
}
function cdf($n)
{
return (1 - erf($n / sqrt(2)))/2;
//I removed the $n < 0 test which inverses the +1/-1
}
function cdf_2tail($n)
{
return 2*cdf($n);
//After a little more digging around, the two tail test is simply 2 x the cdf.
}
I tested my results against: http://vassarstats.net/tabs.html#z and the z-score table.
It is correct to 0.1%
I have a value like this:
$value = 2.3333333333;
and I want to round up this value into like this:
$value = 2.35;
I already tried round, ceil and etc but the result is not what I expected.
Please anyone help.
Thanks
Taking your question literally, this will do it:
$value = (round($original_value / 0.05, 0)) * 0.05
i.e. will round to the nearest 0.05.
If, for some reason, you want to always round up to 0.05, use
$value = (round(($original_value + 0.025) / 0.05, 0)) * 0.05
you have 3 possibility : round(), floor(), ceil()
for you :
$step = 2; // number of step 3th digit
$nbr = round(2.333333333 * $step, 1) / $step; // 2.35
$step = 4; // number of step on 3th digit
$nbr = round(2.333333333 * $step, 1) / $step; // 2.325
round
<?php
echo round(3.4); // 3
echo round(3.5); // 4
echo round(3.6); // 4
echo round(3.6, 0); // 4
echo round(1.95583, 2); // 1.96
echo round(1241757, -3); // 1242000
echo round(5.045, 2); // 5.05
echo round(5.055, 2); // 5.06
?>
floor
<?php
echo floor(4.3); // 4
echo floor(9.999); // 9
echo floor(-3.14); // -4
?>
ceil
<?php
echo ceil(4.3); // 5
echo ceil(9.999); // 10
echo ceil(-3.14); // -3
?>
Complementary functions to round up / down to arbitrary number of decimals:
/**
* Round up to specified number of decimal places
* #param float $float The number to round up
* #param int $dec How many decimals
*/
function roundup($float, $dec = 2){
if ($dec == 0) {
if ($float < 0) {
return floor($float);
} else {
return ceil($float);
}
} else {
$d = pow(10, $dec);
if ($float < 0) {
return floor($float * $d) / $d;
} else {
return ceil($float * $d) / $d;
}
}
}
/**
* Round down to specified number of decimal places
* #param float $float The number to round down
* #param int $dec How many decimals
*/
function rounddown($float, $dec = 2){
if ($dec == 0) {
if ($float < 0) {
return ceil($float);
} else {
return floor($float);
}
} else {
$d = pow(10, $dec);
if ($float < 0) {
return ceil($float * $d) / $d;
} else {
return floor($float * $d) / $d;
}
}
}
Try:
$value = 2.3333333333;
echo number_format($value, 2);
You can use this code:
$value = 2.3333333333;
$value = round ( $value, 2, PHP_ROUND_HALF_UP);
best document is in here
Since i'm more of a "noob" at PHP than i'd hope, Is it possible to inverse the following function for example:
public function baseID($resourceid){
$rid = $resourceid;
$version = 0;
while ($rid > 16777216){
$version++;
if ($version == 1){
//the constant applied to all items
$rid -= 1342177280;
}elseif ($version == 2){
//the value added to the first updated version
$rid -= 50331648;
}else{
//the value added on all subsequent versions
$rid -= 16777216;
}
}
//$returnable = array('baseID'=>$rid,'version'=>$version);
return $rid;
}
Would it be possible to input the "baseID" and return a "resourceID" instead of the current way ?
I apologize if this is the wrong place to be asking such question
Not really. Your function returns the same value for all rids that are of the form:
5 * 2^28 + (3 + n) * 2^24
Where n is a positive integer.
>>> baseID(5 * 2**28 + (3 + 1) * 2**24)
16777216
>>> baseID(5 * 2**28 + (3 + 2) * 2**24)
16777216
>>> baseID(5 * 2**28 + (3 + 3) * 2**24)
16777216
So given just 16777216, you won't be able to determine what went into your function.
This function only works to a limited range, however at a certain point the resource IDs will start returning the same results.
public function resourceID($baseid){
$bid = $baseid;
$version = 0;
while ($bid <= 16777216){
++$version;
if ($version === 1){
$bid += 1342177280;
} elseif ($version === 2){
$bid += 50331648;
} else {
$bid += 16777216;
}
}
return $bid;
}
I want to generate alphanumeric unique numbers but the format should be like this
that should be starts from AA001 to AA999 after that AB001 to AB999 .... BA001 to BA999 end with ZZ999. if i give the input is
1 = result AA001
999 = result AA999
1000 = result AB001
any one can help this ?
Complete solution (see it running):
function formatNum1000($num) {
$tail = $num % 1000;
$head = (int)($num / 1000);
$char1 = chr(ord('A') + (int)($head / 26));
$char2 = chr(ord('A') + ($head % 26));
return sprintf('%s%s%03d', $char1, $char2, $tail);
}
function formatNum999($num) {
$tail = (($num - 1 ) % 999) + 1;
$head = (int)(($num - $tail) / 999);
$char1 = chr(ord('A') + (int)($head / 26));
$char2 = chr(ord('A') + ($head % 26));
return sprintf('%s%s%03d', $char1, $char2, $tail);
}
$ns = array(1, 500, 999, 1000, 1998, 1999, 2000, 25974, 25975, 25999, 26000, 675324, 675999);
foreach($ns as $n) {
$formatted1000 = formatNum1000($n);
$formatted999 = formatNum999 ($n);
echo "Num: $n => $formatted1000 / $formatted999\n";
}
Note: you need to make sure that the input number is within the valid range (0...675999 when including 000-numbers, 1...675324 otherwise)
Note: answer revised, missed the point earlier that 000 is not allowed
How about:
$start = 'AA997';
for($i = 0; $i < 5; $i++) {
$start++;
if (substr($start, 2) == '000') continue;
echo $start,"\n";
}
output:
AA998
AA999
AB001
AB002