2013-02-15 17 views
26

Potrzebuję utworzyć następujące funkcje, ale moja głowa nie może myśleć o żadnej możliwości w PHP bez skomplikowanej matematyki.Zaokrąglanie do najbliższej frakcji (pół, ćwiartka, itp.)

  • okrągły zawsze do najbliższej dziesiętną (1,81 = 1,90, 1,89 = 1,90, 1,85 = 1,90)
  • okrągły zawsze do najbliższego dziesiętną (1,81 = 1,80, 1,89 = 1,80, 1,85 = 1,80)
  • okrągły zawsze do najbliższej X.25/x.50/X.75/x.00 (1,81 = 2, 1,32 = 1,50)
  • okrągły zawsze do najbliższego X .25/x.50/x.75/x.00 (1,81 = 1,75, 1,32 = 1.25)
  • okrągły zawsze do najbliższej x.50/1 (1,23 = 1,50, 1,83 = 2)
  • okrągłego zawsze w dół do najbliższej x.50/1 (= 1,23 1 1,83 = 1.50)

Mam wyszukiwane w Google przez 2 godziny teraz i jedyne rzeczy, które pojawiły się były fora Excel. Czy jest to możliwe z kilkoma prostymi liniami PHP?

+0

Poszukaj '' ceil' round' ... w PHP. net – fedorqui

+0

Wiem, że jest to możliwe z zaokrągleniem i sufitem, ale nie mogę w jakiś sposób stworzyć funkcji. –

+2

2 godziny szukania w Google mógłby napisać jakieś skomplikowane, ale działające algorytmy. – Catfish

Odpowiedz

71

Skoro szuka czwartych (.00, .25, .50, .75), należy pomnożyć swój numer 4, przez okrągły do najbliższej liczby całkowitej w pożądanej (floor jeśli dół ceil jeśli w górę), a następnie podzielić przez 4.

1,32, w porównaniu do najbliższego IV:

1,32 * 4 = 5,28
podłoga (5,28) = 5,00
5,00/4 = 1,25

sama zasada ma zastosowanie w przypadku innych frakcji, takich jak trzecie lub ósemki (.0, .125, .25, .375, .5, .625, .75, .875). Np

1,77, do najbliższego ósmy:

1,77 * 8 = 14.16
ceil (14.16) = 15,00
15,00/= 8 1.875


Tak dla zabawy, można napisać funkcję tak:

function floorToFraction($number, $denominator = 1) 
{ 
    $x = $number * $denominator; 
    $x = floor($x); 
    $x = $x/$denominator; 
    return $x; 
} 

echo floorToFraction(1.82);  // 1 
echo floorToFraction(1.82, 2); // 1.5 
echo floorToFraction(1.82, 3); // 1.6666666666667 
echo floorToFraction(1.82, 4); // 1.75 
echo floorToFraction(1.82, 9); // 1.7777777777778 
echo floorToFraction(1.82, 25); // 1.8 
+0

Jesteście moimi bohaterami. Dzięki. (I nie wiem, który z nich muszę, z wyjątkiem teraz jako odpowiedź). –

+0

Poszedłbym z odpowiedzią, która zawiera kod rozwiązania, a nie tylko link w innym miejscu. Możesz też zaakceptować ten, który został wysłany jako pierwszy. – Barmar

+0

Żałuję, że nie mogę dać ci setek przegranych! – Horst

3

Należy pamiętać, że odpowiedź nie jest naprawdę napięty wody. Ponieważ mamy tu do czynienia z floatami, nie ma gwarancji, że gdy podzielimy zaokrągloną liczbę przez mianownik, to zwraca ona dokładnie okrągłą liczbę. Może zwrócić 1,499999999999 zamiast 1,5. Jest to natura liczb zmiennoprzecinkowych.

Konieczna jest kolejna runda przed zwróceniem numeru z funkcji.

wszelki wypadek ktoś ląduje tutaj z google jak ja :)

+0

napotkał ten problem, dziękuję za zrobienie notatki –

+1

Nie dodając przykładu? – Simon

+1

@ Simon 'round (round (2.24 * 4)/4, 2)': Wewnętrzna funkcja rundy sprawia, że ​​jest przyciągana do najbliższej liczby całkowitej. Podział może prowadzić do dziwnych ruchów, więc zewnętrzna funkcja zaokrągla je do 2 miejsc dziesiętnych. – Fx32

1

Według funkcji w Excelu mround():

function MRound($num,$parts) { 
    $res = $num * $parts; 
    $res = round($res); 
    return $res /$parts; 
} 
echo MRound(-1.38,4);//gives -1.5 
echo MRound(-1.37,4);//gives -1.25 
echo MRound(1.38,4);//gives 1.5 
echo MRound(1.37,4);//gives 1.25