- Laravel
- SQL
- Query Syntax
- PHP

Hello,

I have the following function which converts decimal odds to fractional odds. However, I have problems converting odds like 4.33 which should be 10/3 but it returns as 100/333.

Any ideas of how to fix this?

Thanks!

I have the following function which converts decimal odds to fractional odds. However, I have problems converting odds like 4.33 which should be 10/3 but it returns as 100/333.

Any ideas of how to fix this?

Thanks!

```
function odds($decimal)
{
$decimal = $decimal - 1;
if ($decimal == 0) {
$whole = 0;
$numerator = 0;
$denominator = 1;
$top_heavy = 0;
} else {
$sign = 1;
if ($decimal < 0) {
$sign = -1;
}
if (floor(abs($decimal)) == 0) {
$whole = 0;
$conversion = abs($decimal);
} else {
$whole = floor(abs($decimal));
$conversion = abs($decimal);
}
$power = 1;
$flag = 0;
while ($flag == 0) {
$argument = $conversion * $power;
if ($argument == floor($argument)) {
$flag = 1;
} else {
$power = $power * 10;
}
}
$numerator = $conversion * $power;
$denominator = $power;
$hcf = euclid($numerator, $denominator);
$numerator = $numerator / $hcf;
$denominator = $denominator / $hcf;
$whole = $sign * $whole;
$top_heavy = $sign * $numerator;
$numerator = abs($top_heavy) - (abs($whole) * $denominator);
if (($whole == 0) && ($sign == -1)) {
$numerator = $numerator * $sign;
}
}
$top_heavy = round($top_heavy, 2);
$denominator = round($denominator, 2);
//return array($whole, $numerator, $denominator, $top_heavy);
return number_format($top_heavy, 0, '.', '') . "/" . number_format($denominator,
0, '.', '');
}
function euclid($number_one, $number_two)
{
if (($number_one == 0) or ($number_two == 0)) {
$hcf = 1;
return $hcf;
} else {
if ($number_one < $number_two) {
$buffer = $number_one;
$number_one = $number_two;
$number_two = $buffer;
}
$dividend = $number_one;
$divisor = $number_two;
$remainder = $dividend;
while ($remainder > 0) {
if ((floor($dividend / $divisor)) == ($dividend / $divisor)) {
$quotient = $dividend / $divisor;
$remainder = 0;
} else {
$quotient = floor($dividend / $divisor);
$remainder = $dividend - ($quotient * $divisor);
}
$hcf = $divisor;
$dividend = $divisor;
$divisor = $remainder;
}
}
return $hcf;
}
```

But maybe I do not understand what your problem is along mathematical logic thinking on your input and results, although clearly the 100/333 is incorrect, and I would guess has premature rounding errors

I may can redo the math in your function, however, To be more sure of the results you need , if 1.5 went in then 1/2 would be output?

I assume that input values less than ONE (0.5) are not allowed, or how is that translated?

what output would you want for an input of =

2.5

4.2

5.6

sorry for asking, but this is new to me

Reading this:

If 4.33 could be read to mean

1 bet at 5.6 pays 5.6. Now subtracting the one, we get 4.6 payout

2 bet at 5.6 pays 11.2. Now subtracting the two, we get 9.2 payout

3 bet at 5.6 pays 16.8. Now subtracting the three, we get 13.8 payout

4 bet at 5.6 pays 22.4. Now subtracting the four, we get 18.4 payout

5 bet at 5.6 pays 28. Now subtracting the five, we get 23 payout

http://www.sbrforum.com/betting-tools/odds-converter/

and did a few values and got back the fraction bet that it gave on their site

2.8 9/5

4.6 18/5

and a few others, ,

try code below and see if it give wrong results for your tests?

Also, as I remember in betting there are some values like 2/1 and 3/1 that are very often used, This math function is not complex, but I think I would have and array with the most common Decimal Bet values as keys, and just return that frac value, without doing any math, maybe?

```
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;
}
if ($dec > 19){$dec = floor($dec / 10);}
return $dec . '/' . $div;
}
```

if ($dec > 19){$dec = floor($dec / 10);}

to

if ($dec > 29){$dec = floor($dec / 10);}

however this does not change the math error

```
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;
}
if ($dec > 99){$dec = floor($dec / 100); $div = floor($div / 10);}
if ($dec > 29){$dec = floor($dec / 10);}
return $dec . '/' . $div;
}
```

http://www.sbrforum.com/betting-tools/odds-converter/

I am out of time for now, I may do some later or tomorrow, I feel that I will need to come at this from a reverse perspective as I will do a formula to make 23/5 into 5.6 and then do a reverse of that, the while loops in your conversions do not do math so much as they narrow down results to get some sort of near estimate for the return value

http://www.laprbass.com/RAY_temp_infodigger.php

HTH, ~Ray

```
<?php // RAY_temp_infodigger.php
error_reporting(E_ALL);
echo "<pre>";
// TEST DATA SET
$testdata = array
( '1.5' => '1/2'
, '2.5' => '3/2'
, '4.2' => '16/5'
, '5.6' => '23/5'
, '4.3' => '10/3'
, '4.333' => '10/3'
)
;
// VISUALIZE THE TEST DATA
var_dump($testdata);
// TEST EACH VALUE
foreach ($testdata as $dec => $frac)
{
echo PHP_EOL . "$dec $frac ==> ";
echo infodigger($dec);
}
// A FUNCTION
function infodigger($n)
{
// COMPUTE AN ACCEPTABLY CLOSE APPROXIMATION OF AN INTEGER
$a = explode('.', "$n");
$d = strlen($a[1]);
// TENTH OF THE DECIMAL
$f = "0." . str_pad(NULL, $d, '0') . '1';
$f = (float)$f;
$g = $f * 10.0;
// SOMEWHAT ARBITRARY LIMIT ON THE ITERATOR
$thing = 100;
// DETERMINE THE MULTIPLIER
$facto = 1;
$x = 0.0;
while ($thing)
{
$x = $x + $n;
$x = number_format($x, $d);
$z = $x + $g;
$z = number_format($z, $d);
$fx = floor($x);
$fz = floor($z);
if ( $x == $fx ) break;
if ( $z == $fz ) break;
$facto++;
$thing--;
}
// IF THE ITERATOR EXPIRED WE ARE HOSED
if (!$thing) return FALSE;
$new = (int)round($n * $facto)-$facto;
return "$new" . '/' . "$facto";
}
```

I have it as function dec2fracBet($dec)

I will do 2.1 and 2.11 but NOT 2.111 if you enter 2.111 it will return '1/1' as an ERROR indicator

if you want to fully test it with 3 places, you can change

if ($len > 2) return '1/1';

to

if ($len > 3) return '1/1';

```
<?php
function bcgcd($v1, $v2){
if ($v1 < $v2){$sw = $v1;
$v1 = $v2;
$v2 = $sw;}
$md = 1;
while ($md != 0){
$md = bcmod($v1, $v2);
$v1 = $v2;
$v2 = $md;
}
return $v1;
}
function dec2fracBet($dec){--$dec;
$inv = intval($dec);
$tl = $dec-$inv;
$strF = ''.$tl;
$len = (strlen($strF)-2);//*10;
if ($len > 2) return '1/1';
$len = pow(10, $len);
$strF = $dec*$len;
$primeA = array(2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,
79,83,89,97,101,103,107,109,113,127,131,137,139,149,151,157,163,167,173,
179,181,191,193,197,199,211,223,227,229,233,239,241,251,257,263,269,271,
277,281,283,293,307,311,313,317,331,337,347,349,353,359,367,373,379,383,
389,397,401,409,419,421,431,433,439,443,449,457,461,463,467,479,487,491,
499,503,509,521,523,541,547,557,563,569,571,577,587,593,599,601,607,613,
617,619,631,641,643,647,653,659,661,673,677,683,691,701,709,719,727,733,
739,743,751,757,761,769,773,787,797,809,811,821,823,827,829,839,853,857,
859,863,877,881,883,887,907,911,919,929,937,941,947,953,967,971,977,983,991,997);
if(($strF == $len) || ($strF == 0) || ($len == 0)) return '1/1';
if (in_array($strF, $primeA)) $inv = 1; else $inv = bcgcd($len, $strF);
$dec = $len / $inv;
$tl = $strF / $inv;
echo 'ZZ len= ',$len,' tl= ',$tl,' strF ',$strF,' gcd2 ',$inv,'- ',' dec ',$dec,'- ';
return $tl . '/' . $dec;
}
$cn = 4.6;
echo '<br>',dec2fracBet($cn);
$cn = 4.36;
echo '<br>',dec2fracBet($cn);
```

## Premium Content

You need an Expert Office subscription to comment.Start Free Trial