这个问题包括两个单独的步骤
让我们从后者开始:投注赔率5
意味着,每投资 1 美元,如果您赢了,您将获得 5 美元。由于您投资了 1 美元,因此您的实际赢利仅为 4 美元。所以赔率是 4-1 或4/1
类似的,平均投注赔率2.5
,您每投资 1 美元,您赢取 1.5 美元,给您 1.5-1 或 3-2 或3/2
这使我们得出结论,我们需要的是($odds-1)
下一部分:分馏。我没有分析给定的算法,但写了一个非常糟糕(但易于阅读)的算法:
function dec2frac($val) {
//first pump denominator up
$tmp=strstr("$val",'.');
if ($tmp) $tmp=strlen($tmp)-1;
else $tmp=0;
$n=$val;
$d=1;
for (;$tmp>0;$tmp--) {
$n*=10;
$d*=10;
}
$n=intval(round($n));
$d=intval(round($d));
//Now shorten the fraction
//Find limit for pseudoprime search
$min=$n;
if ($d<$n) $min=$d;
$min=ceil($min/2);
if (ceil($d/2)>$min) $min=ceil($d/2);
if (ceil($n/2)>$min) $min=ceil($n/2);
$pseudoprime=2;
while ($pseudoprime<=$min) {
//Shorten by current pseudoprime as long as possible
while (true) {
$nn=$n/$pseudoprime;
if ($nn!=round($nn)) break;
$dd=$d/$pseudoprime;
if ($dd!=round($dd)) break;
$n=intval($nn);
$d=intval($dd);
}
//Move on to next pseudoprime
$pseudoprime+=($pseudoprime==2)?1:2;
if ($pseudoprime>3)
if (($pseudoprime/3)==floor($pseudoprime/3)) $pseudoprime+=2;
}
return "$n/$d";
}
经测试,这可以使用值 0.25、2.5、3.1、3.14、3.141、3.1415、3.14159 和 3.141592。
该算法非常未经优化的性质是一个不太重要的限制,因为投注赔率往往没有很多小数位数。
和...一起
function odds2fract($odds) {
return dec2frac($odds-1);
}
从其他步骤导出,我们成功转换
5 --> 4/1
2.5 --> 3/2
2.1 --> 11/10
2.2 --> 6/5
编辑
原始版本在搜索限制计算中存在错误,导致某些分数(例如完全可缩短)未能缩短。更新的版本解决了这个问题。
编辑 2
又是一个固定的错误:未能round()
在第一步中获得的值在intval()
ing 之前给出了错误的分数结果,这些结果在浮点方面的保真度非常差。通过应用缺失来修复round()