我试图将小数转换为分数运动赔率。我通过搜索找到了一个运行良好的PHP函数,但某些小数会导致问题,例如2.1最大化服务器:
function dec2frac($dec) {
$decBase = --$dec;
$div = 1;
do {
$div++;
$dec = $decBase * $div;
} while (intval($dec) != $dec);
if ($dec % $div == 0) {
$dec = $dec / $div;
$div = $div / $div;
}
return $dec.'/'.$div;
}
$decimal = 2.3;
echo $decimal.' --> '.dec2frac($decimal);
小数几率为6应该给出5/1。这被计算为6-1 = 5 = 5/1
我发现2.2和2.3的十进制输入使函数跳起来但其他值似乎没问题。造成这种异常现象的原因是什么呢?
感谢。
答案 0 :(得分:4)
此问题包含两个单独的步骤
让我们从后者开始: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
修改强>
原始版本在搜索限制计算中存在错误,导致某些分数(例如,completeley缩短)无法缩短。更新版本解决了这个问题。
修改2
同样是一个固定的错误:round()
在intval()
之前的第一步中获得的值未能round()
在分数上给出错误的结果,这在浮点数上具有非常差的保真度。通过应用缺少的{{1}}
答案 1 :(得分:0)
立即触发的第一件事就是你在那里使用'.1'。对我来说,这表明我们正在处理浮点问题......检查你的代码......是的,看起来像浮点问题。这里的问题是你的数字是以二进制形式存储的,并且二进制文件没有方便的方法来使用大量的十进制值。当你开始使用简单的数学时,你得不到精确的结果,你得到快捷方式估计。
该链接应该为您提供有关出错的详细信息,指向更多页面的链接,这些页面将为您提供更多信息,以及指向现有库以修复它的链接。