[PHP] Getal naar beneden afronden op veelvoud van 4

Pagina: 1
Acties:
  • 551 views sinds 30-01-2008
  • Reageer

Onderwerpen


Acties:
  • 0 Henk 'm!

  • Reveller
  • Registratie: Augustus 2002
  • Laatst online: 05-12-2022
Zoals de titel al zegt, probeer ik een functie te schrijven die een geval naar beneden afrondt naar een veelvoud van 4. Enkele voorbeelden:
HTML:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
+-----------+----------------+
| getal     | functie return |
+-----------+----------------+
| 0         | 4   (1 x 4)    |
+-----------+----------------+
| 2.5       | 4   (1 x 4)    |
+-----------+----------------+
| 7         | 4   (1 x 4)    |
+-----------+----------------+
| 11        | 8   (2 x 4)    |
+-----------+----------------+
| 18.33     | 16  (4 x 4)    |
+-----------+----------------+
| 2003      | 2000 (500 x 4) |
+-----------+----------------+


Via de search leerde ik dat "modulo" (%) gebruikt wordt om te kijken wat je overhoudt na een deling. Hiermee moet het op te lossen zijn, maar ik zie niet hoe. Welke wiskunde knobbel kan mij helpen?

[ Voor 6% gewijzigd door Reveller op 07-02-2007 00:59 ]

"Real software engineers work from 9 to 5, because that is the way the job is described in the formal spec. Working late would feel like using an undocumented external procedure."


Acties:
  • 0 Henk 'm!

  • TheBorg
  • Registratie: November 2002
  • Laatst online: 20-09 18:24

TheBorg

Resistance is futile.

$jegetal = $jegetal - ($jegetal % 4)

Acties:
  • 0 Henk 'm!

  • Snake
  • Registratie: Juli 2005
  • Laatst online: 07-03-2024

Snake

Los Angeles, CA, USA

PHP:
1
2
3
$getal = 501;
$nieuwgetal = $getal - ($getal%4);
print $nieuwgetal;

Going for adventure, lots of sun and a convertible! | GMT-8


Acties:
  • 0 Henk 'm!

  • Pyrus
  • Registratie: November 2001
  • Laatst online: 21:57

Pyrus

Hardknock life

Reveller schreef op woensdag 07 februari 2007 @ 00:47:
Zoals de titel al zegt, probeer ik een functie te schrijven die een geval naar beneden afrondt naar een veelvoud van 4. Enkele voorbeelden:
HTML:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
+-----------+----------------+
| getal     | functie return |
+-----------+----------------+
| 0         | 4              |
+-----------+----------------+
| 2.5       | 4              |
+-----------+----------------+
| 7         | 4              |
+-----------+----------------+
| 11        | 8              |
+-----------+----------------+
| 18.33     | 16             |
+-----------+----------------+
| 2003      | 500            |
+-----------+----------------+


Via de search leerde ik dat "modulo" (%) gebruikt wordt om te kijken wat je overhoudt na een deling. Hiermee moet het op te lossen zijn, maar ik zie niet hoe. Welke wiskunde knobbel kan mij helpen?
Die eerste afronding klopt niet. Moet dat niet 0 zijn?

getal-(getal%4) is wat je zoekt lijkt me.

LinkedIn


Acties:
  • 0 Henk 'm!

  • b19a
  • Registratie: September 2002
  • Niet online
Je haalt meerdere dingen door elkaar, als je 0 naar beneden afrond naar een veelvoud van 4 (n>1) krijg je inderdaad 4. Echter ga je bij 2003 de fout in, daar zou het getal 2000 uit moeten komen!

Aannemende dat 2003 het getal 2000 op moet leveren krijg je dus ongeveer het volgende:

code:
1
2
3
getal=floor(getal/4);    #delen door 4 en afronden naar beneden
if(getal=0) getal++;
getal=getal*4;

Acties:
  • 0 Henk 'm!

  • lordsnow
  • Registratie: Maart 2000
  • Laatst online: 21:07

lordsnow

I know nothing

Als PHP bitwise-operators heeft kan het het makkelijkst, en het snelst, gedaan worden door de twee laagste bits van $getal op 00 te zetten? (oftewel, $result := $getal AND 252 (voor 8-bit getallen))

[ Voor 67% gewijzigd door lordsnow op 07-02-2007 01:04 ]


Acties:
  • 0 Henk 'm!

  • Opperhoof
  • Registratie: Mei 2003
  • Laatst online: 22:17
antwoord =
(
Getal / 4 = A
A naar beneden afronden
A*4
)


Ik kan verder geen php maar zo werkt het wel.

Wat bouke dus ook zegt.

7/4 = 1,75
afronden = 1
antwoord = 1*4 = 4

345/4 = 86.25
afgerond = 86
antwoord = 86*4 = 344

[ Voor 38% gewijzigd door Opperhoof op 07-02-2007 00:58 ]


Acties:
  • 0 Henk 'm!

  • Reveller
  • Registratie: Augustus 2002
  • Laatst online: 05-12-2022
BoukeHaarsma schreef op woensdag 07 februari 2007 @ 00:52:
Echter ga je bij 2003 de fout in, daar zou het getal 2000 uit moeten komen!
Het is al laat en ik zag net dat ik die fout gemaakt heb. Inmiddels verbeterd in TS :)

Iedereen ontzettend bedankt voor de snelle en goede reakties! Hier kan ik zeker mee verder (maar nu eerst naar bed ;))

[ Voor 66% gewijzigd door Reveller op 07-02-2007 01:02 ]

"Real software engineers work from 9 to 5, because that is the way the job is described in the formal spec. Working late would feel like using an undocumented external procedure."


Acties:
  • 0 Henk 'm!

  • kenneth
  • Registratie: September 2001
  • Niet online

kenneth

achter de duinen

lordsnow schreef op woensdag 07 februari 2007 @ 00:54:
Twee laagste bits van "getal" op 0 zetten?
Dat is een technische 'truc', niet echt een conceptuele benadering van het probleem :)

Look, runners deal in discomfort. After you get past a certain point, that’s all there really is. There is no finesse here.


Acties:
  • 0 Henk 'm!

  • Opperhoof
  • Registratie: Mei 2003
  • Laatst online: 22:17
Reveller schreef op woensdag 07 februari 2007 @ 00:47:

HTML:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
+-----------+----------------+
| getal     | functie return |
+-----------+----------------+
| 0         | 4   (1 x 4)    |
+-----------+----------------+
| 2.5       | 4   (1 x 4)    |
+-----------+----------------+
| 7         | 4   (1 x 4)    |
+-----------+----------------+
| 11        | 8   (2 x 4)    |
+-----------+----------------+
| 18.33     | 16  (4 x 4)    |
+-----------+----------------+
| 2003      | 500 (125 x 4)  |
+-----------+----------------+
Ik vraag me alleen af of je krijgt wat je wilt..? Bij 11 is het dichtst bij zijnde veelvoud afgerond naar beneden namelijk 8.
Bij 7 is dat 4, en bij 18.33 is dat 16.
Bij 2003 zou het in dit geval dus 2000 zijn. Bij 2005 zou het dus 2004 zijn....

:?

Dan krijg je dus de vraag:
" Welk getal, zit het dichtst bij het ingevoerde getal, EN is lager dan het ingevoerde getal, EN is een veelvoud van 4."

[ Voor 8% gewijzigd door Opperhoof op 07-02-2007 01:03 ]


Acties:
  • 0 Henk 'm!

  • TheBorg
  • Registratie: November 2002
  • Laatst online: 20-09 18:24

TheBorg

Resistance is futile.

lordsnow schreef op woensdag 07 februari 2007 @ 00:54:
Als PHP bitwise-operators heeft kan het het makkelijkst, en het snelst, gedaan worden door de twee laagste bits van $getal op 00 te zetten? (oftewel, $result := $getal AND 252 (voor 8-bit getallen))
Beetje bitshiften:
PHP:
1
2
3
4
5
6
$i = 2003;

$i = $i >> 2;
$i = $i << 2;

echo $i; // Geeft 2000


Niet gebenchmarked maar waarschijnlijk de snelste methode.

[ Voor 7% gewijzigd door TheBorg op 07-02-2007 01:09 ]


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 03:42

.oisyn

Moderator Devschuur®

Demotivational Speaker

Jammer joh, maar dat lukt niet voor negatieve getallen ;)
De modulo overigens ook niet, omdat die doorgaans ook een negatief getal teruggeeft - daar zul je dus even op moeten checken.

Iets dat altijd werkt:
PHP:
1
$getal = (int)$getal & ~3;

Maar zoiets was al genoemd

[ Voor 38% gewijzigd door .oisyn op 07-02-2007 01:27 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 22:43
Waarom werkt shiften niet met negatieve getallen? Het effect is hetzelfde: je cleart de laagste twee bits (het maakt niet eens uit of je een logical of een arithmetic right shift gebruikt, omdat je toch weer terug shift).

Waarschijnlijk is één bitwise-and operatie al sneller dan één shift-operatie, dus waarschijnlijk kun je wel beter die and-operatie gebruiken.

Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 03:42

.oisyn

Moderator Devschuur®

Demotivational Speaker

Je hebt gelijk, ik zat verkeerd om te denken. De sign-bit komt er links in, maar die schuif je er ook weer uit.

de 2 shifts vs. 1 and instructie in PHP lijkt me een beetje nutteloos overigens, waarschijnlijk valt het totaal in het niet bij de overhead van de interpreter ;) (hoewel je natuurlijk zou kunnen zeggen dat bij mijn methode de AST kleiner is en daardoor iets sneller geinterpreteerd wordt)

[ Voor 24% gewijzigd door .oisyn op 07-02-2007 02:29 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • Onbekend
  • Registratie: Juni 2005
  • Nu online

Onbekend

...

Voor negatieve getallen zou het volgende moeten werken:

[code=php]
<?php
$getal = 501;
$nieuwgetal = floor( $getal / 4 ) * 4;
print $nieuwgetal;
?>
[/code]

Als hij dan naar boven af moet ronden gebruik je ceil i.c.m. een if-lus


Maar om het eenvoudig te houden:
PHP:
1
2
3
4
5
<?php
$getal = 501;
$nieuwgetal = $getal OR 3 - 3;
print $nieuwgetal;
?>

[ Voor 22% gewijzigd door Onbekend op 07-02-2007 08:05 ]

Speel ook Balls Connect en Repeat


Acties:
  • 0 Henk 'm!

  • Snake
  • Registratie: Juli 2005
  • Laatst online: 07-03-2024

Snake

Los Angeles, CA, USA

.oisyn schreef op woensdag 07 februari 2007 @ 01:23:
Jammer joh, maar dat lukt niet voor negatieve getallen ;)
De modulo overigens ook niet, omdat die doorgaans ook een negatief getal teruggeeft - daar zul je dus even op moeten checken.

Iets dat altijd werkt:
PHP:
1
$getal = (int)$getal & ~3;

Maar zoiets was al genoemd
Nu wil ik niet de slimmerik uithangen, maar modulo geef toch nooit negatief terug?

Het is toch de rest van een deling, en een deling kan nooit negatief zijn!?!

Going for adventure, lots of sun and a convertible! | GMT-8


Acties:
  • 0 Henk 'm!

Verwijderd

Een modulo kan wel negatief zijn, zie hier voor de uitleg:

http://en.wikipedia.org/wiki/Modulo_operation

Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 03:42

.oisyn

Moderator Devschuur®

Demotivational Speaker

Snakiej schreef op woensdag 07 februari 2007 @ 09:10:
Het is toch de rest van een deling, en een deling kan nooit negatief zijn!?!
Waarom kan een deling niet negatief zijn?

-8 / 3 = -2(.66666)
da's toch echt negatief :)

-8 % 3 = -2 of 1, 't is maar net hoe je het definieert.

Aangezien uit de (naar 0 afgeronde) deling -2 komt, wat na vermenigvuldiging met de deler -6 is, hou je dus rest -2 over om op -8 te komen. Deze methode wordt gebruikt in PHP. Als je echter naar beneden afrondt ipv naar 0, dan is de quotient -3, na vermenigvuldiging met de deler -9, en dus rest 1, wat in de wiskunde wat meer gebruikelijk is. Hoe los je dat op? Simpel:

PHP:
1
2
3
4
5
function positive_mod($a, $b)
{
    $c = $a % $b;
    return $c >= 0 ? $c : $c + $b;
}

[ Voor 10% gewijzigd door .oisyn op 07-02-2007 11:58 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.

Pagina: 1