[PHP] Bedragen netjes maken

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

Onderwerpen


Acties:
  • 0 Henk 'm!

  • avdwerf
  • Registratie: Maart 2007
  • Laatst online: 10:25
heb een script waarin wat bedragen moeten worden uitgerekend. Als ik nu twee getallen met getallen achter de komma vermenigvuldig, bijvoorbeeld 4.11 x 5.23 = 21,4953, dan kan ik die 21,4953 netjes afronden naar 21,50 met round($getal,2). Echter als ik nu bijvoorbeeld 2,5 x 7 = 17.5 doe, wil ik dat daar dan 17.50 van wordt gemaakt, hoe kan ik dat voor elkaar krijgen? heb al geprobeerd om dat getal ook gewoon door round($getal,2) te halen maar dat werkte niet... Iemand tips?

Acties:
  • 0 Henk 'm!

  • avdwerf
  • Registratie: Maart 2007
  • Laatst online: 10:25
Hmm ik kan de titel niet meer aanpassen, maar dit is dus bedoeld voor PHP, excuses voor de foute titel...

Acties:
  • 0 Henk 'm!

  • Mithrandir
  • Registratie: Januari 2001
  • Laatst online: 09:19
Wat je kunt gebruiken is printf of sprintf. De php handleiding kan je daar mee helpen.

Verbouwing


Acties:
  • 0 Henk 'm!

  • Shuisman
  • Registratie: Maart 2004
  • Laatst online: 01-09 10:12
*NEVERMIND, ik las verkeerd*

[ Voor 77% gewijzigd door Shuisman op 30-03-2007 17:07 ]


Acties:
  • 0 Henk 'm!

  • Plopeye
  • Registratie: Maart 2002
  • Laatst online: 13-08 07:00
Heel simpel, neem even jouw voorbeeld over...

je neemt het bedrag: 21,4953 je telt hier bij op 0,0050 dan heb je dus 21,5003 en dan maak je er een getal met 2 decimalen van... Dan heb je dus je afronding... door met het getal dat je er bij optelt te spelen beïnvloed je of hij naar boven of beneden afrond...

Unix is user friendly, it's only selective about his friends.....


Acties:
  • 0 Henk 'm!

  • Mithrandir
  • Registratie: Januari 2001
  • Laatst online: 09:19
Plopeye schreef op vrijdag 30 maart 2007 @ 17:09:
Heel simpel, neem even jouw voorbeeld over...

je neemt het bedrag: 21,4953 je telt hier bij op 0,0050 dan heb je dus 21,5003 en dan maak je er een getal met 2 decimalen van... Dan heb je dus je afronding... door met het getal dat je er bij optelt te spelen beïnvloed je of hij naar boven of beneden afrond...
Zo moet je het dus absoluut niet doen. Er bestaan gewoon standaard formatted-string-printing functies die gemaakt zijn om dit soort werk goed uit te voeren, zoals printf of sprintf. Eigen huis-, tuin- en keukenoplossingen zijn niet de manier om zoiets te gaan oplossen.

Verbouwing


Acties:
  • 0 Henk 'm!

  • Spockz
  • Registratie: Augustus 2003
  • Laatst online: 10:08

Spockz

Live and Let Live

Kijk eens naar voorbeeld 2331 op deze pagina. :)

C'est le ton qui fait la musique. | Blog | @linkedin
R8 | 18-55 IS | 50mm 1.8 2 | 70-200 2.8 APO EX HSM | 85 1.8


Acties:
  • 0 Henk 'm!

  • D4V3
  • Registratie: Augustus 2003
  • Laatst online: 19-03-2021
sprintf("%1.2f", $bedrag); // je formateert je bedrag naar een float met 2 decimalen en minimaal 1 getal voor de komma

of number format zoals hierboven aangegeven.

op-voorraad.nl - Realtime voorraad updates voor de Playstation 5!


Acties:
  • 0 Henk 'm!

  • stappel_
  • Registratie: Augustus 2000
  • Laatst online: 14-09 12:59
je kan ook number_format() gebruiken: http://nl3.php.net/manual/en/function.number-format.php
er is ook een money_format daar moet je vanaf blijven. Die werkt bijvoorbeeld niet onder windows.

Ubero: #2, Euler: #1, GOT: #1, Des: #1, Zeta: #1, Eon: #3, OGR-24: #3, OGR-25: #7,
LM: #7, AP: #5, DF: #19, D2OL: #37, SOB: #50, TSC: #63, RC5: #96


Acties:
  • 0 Henk 'm!

  • flashin
  • Registratie: Augustus 2002
  • Laatst online: 17-12-2023
Plopeye schreef op vrijdag 30 maart 2007 @ 17:09:
Heel simpel, neem even jouw voorbeeld over...

je neemt het bedrag: 21,4953 je telt hier bij op 0,0050 dan heb je dus 21,5003 en dan maak je er een getal met 2 decimalen van... Dan heb je dus je afronding... door met het getal dat je er bij optelt te spelen beïnvloed je of hij naar boven of beneden afrond...
Ik wil wel eens meer van jouw algoritmes zien :D

Sorry, maar deze vraag is toch echt makkelijk te vinden in de php tutorial / got / google of ligt het aan mij?


edit: om nog meer te flamen, TS wordt eens consequent in wat je doet: zie leestekens
bijvoorbeeld 4.11 x 5.23 = 21,4953, dan kan ik die 21,4953 netjes afronden naar 21,50 met round($getal,2). Echter als ik nu bijvoorbeeld 2,5 x 7 = 17.5 doe
[/stopt hierbij zijn flame]

[ Voor 28% gewijzigd door flashin op 30-03-2007 23:31 ]


Acties:
  • 0 Henk 'm!

  • Jurgle
  • Registratie: Februari 2003
  • Laatst online: 24-06 00:27

Jurgle

100% Compatible

Mithrandir schreef op vrijdag 30 maart 2007 @ 17:13:
Zo moet je het dus absoluut niet doen.
flashin schreef op vrijdag 30 maart 2007 @ 23:28:
Ik wil wel eens meer van jouw algoritmes zien :D
Niet om t een of ander, maar is dat een beetje erbij optellen niet gewoon hoe afronden werkt?

Je wilt afronden op een bepaalde nauwkeurigheid, stel op honderdsten, dan tel je bij je originele waarde de helft van die nauwkeurigheid erbij op, dus een halve honderdste, en dan chop je alles wat nauwkeuriger is eraf, hier dus alles kleiner dan honderdsten.

Ander voorbeeld, afronden op helen:
code:
1
2
3
4
5
6
7
getal = 1.7 //af te ronden getal
getal = getal + .5
getal = alles voor de komma = 2
//----
getal = 4.3 //af te ronden getal
getal = getal + .5
getal = alles voor de komma = 4


Zo voorkom je lange ifs achter elkaar of lange switches. Plopeye was dus nog niet eens zo slecht bezig...

[ Voor 28% gewijzigd door Jurgle op 30-03-2007 23:48 . Reden: Wat netter verwoord ]

My opinions may have changed but not the fact that I am right ― Ashleigh Brilliant


Acties:
  • 0 Henk 'm!

  • kenneth
  • Registratie: September 2001
  • Niet online

kenneth

achter de duinen

Nee schat, het punt is dat je gewoon 'n standaardfunctie moet gebruiken niet het wiel opnieuw moet uitvinden :)

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!

  • Jurgle
  • Registratie: Februari 2003
  • Laatst online: 24-06 00:27

Jurgle

100% Compatible

Zie commentaar:
PHP:
1
2
3
4
5
//Leg mij eens uit waarom:
$afgerond = substr(0, strpos('.') + 2, $getal + .005);
//niet standaardfuncties zijn en
$afgerond = sprintf("%1.2f", $getal);
//wel?


Mijn post was overigens niet heel on topic maar meer gericht aan mithrandir en flashin die Plopeye IMHO onterecht op zijn code aanspreken

[ Voor 3% gewijzigd door Jurgle op 31-03-2007 00:56 ]

My opinions may have changed but not the fact that I am right ― Ashleigh Brilliant


Acties:
  • 0 Henk 'm!

  • kenneth
  • Registratie: September 2001
  • Niet online

kenneth

achter de duinen

avdwerf schreef op vrijdag 30 maart 2007 @ 17:02:
17.5 doe, wil ik dat daar dan 17.50 van wordt gemaakt,
Ja, daar kan je een woud aan functies voor gebruiken, of eentje. Jij kiest :)

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!

  • Jurgle
  • Registratie: Februari 2003
  • Laatst online: 24-06 00:27

Jurgle

100% Compatible

Dat is precies mijn punt.

Overigens vindt ik het met dat woud nog wel meevallen en beide regels in mijn voorbeeld geven hetzelfde resultaat (dus ook met de evt afsluitende 0).

Het kan bijvoorbeeld handig zijn bij het afronden van schoolcijfers of andere bijzondere afrondingen. Als ik me het goed kan herinneren is een 5.5 voldoende en een 5.4 niet, wat inhield dat als je een 5.45 stond, dit onvoldoende was, maar een 5.46 weer wel voldoende. Bij de aanpak die jij 'een woud aan functies' noemt kun je dit simpel afronden door de 0.005 te veranderen.

My opinions may have changed but not the fact that I am right ― Ashleigh Brilliant


Acties:
  • 0 Henk 'm!

Verwijderd

Ze kun je voor iedere functie wel je eigen varianten gaan schrijven...

Waarom denk je dat die standaard libraries er zijn? Precies om ze te gebruiken.

Acties:
  • 0 Henk 'm!

  • kenneth
  • Registratie: September 2001
  • Niet online

kenneth

achter de duinen

Ja, áls :)

Het is ook niet "fout", maar je kiest doorgaans gewoon voor het eenvoudigste.

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!

  • smesjz
  • Registratie: Juli 2002
  • Niet online
Jurgle schreef op zaterdag 31 maart 2007 @ 00:09:
Zie commentaar:
PHP:
1
2
3
4
5
//Leg mij eens uit waarom:
$afgerond = substr(0, strpos('.'), $getal + .005);
//niet standaardfuncties zijn en
$afgerond = sprintf("%1.2f", $getal);
//wel?


Mijn post was overigens niet heel on topic maar meer gericht aan mithrandir en flashin die Plopeye IMHO onterecht op zijn code aanspreken
Bij sprintf() heb je geen overhead van de tweede strpos functie. Het is zonder commentaar ook duidelijk wat de tweede functie doet en niet alleen als je een C achtergrond hebt.

Bij de eerste aanroep behandel je het getal (ok, PHP is niet strict typed) als een string en voer je daar string functies op uit alsof het een pure string is. sprintf() is hier gewoon voor gemaakt en is ontzettend flexibel.

Acties:
  • 0 Henk 'm!

  • Jurgle
  • Registratie: Februari 2003
  • Laatst online: 24-06 00:27

Jurgle

100% Compatible

smesjz schreef op zaterdag 31 maart 2007 @ 00:23:
[...]
Bij sprintf() heb je geen overhead van de tweede strpos functie. Het is zonder commentaar ook duidelijk wat de tweede functie doet en niet alleen als je een C achtergrond hebt.

Bij de eerste aanroep behandel je het getal (ok, PHP is niet strict typed) als een string en voer je daar string functies op uit alsof het een pure string is. sprintf() is hier gewoon voor gemaakt en is ontzettend flexibel.
Ikzelf heb geen C achtergrond. Intern gebeurt bij sprintf natuurlijk ook iets dergelijks, dus de enige overhead is het verschil in dat mijn regeltje niet C compiled is, maar door PHP.

Dat ik in dit voorbeeld loop te type-jugglen zit em inderdaad in PHP, bij C of JAVA is een (int) -cast genoeg.

Java:
1
2
3
4
float getal;
int afgerond;
getal = 4.6;
afgerond = (int) (getal + .5);


Nogmaals, ik reageerde omdat ik vind dat iemand hier onterecht werd afgezeken op een uitleg die imho correct is (het afronden van getallen met halven erbij op tellen). Mijn bedoeling was niet een de thread off-topic maken op deze manier.

My opinions may have changed but not the fact that I am right ― Ashleigh Brilliant


Acties:
  • 0 Henk 'm!

  • kenneth
  • Registratie: September 2001
  • Niet online

kenneth

achter de duinen

Terecht afgezeken, je moet namelijk altijd voor de simpelste oplossing gaan, hoe moeilijk die ook is :+

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!

  • Jurgle
  • Registratie: Februari 2003
  • Laatst online: 24-06 00:27

Jurgle

100% Compatible

laat maar, weltrusten

[ Voor 89% gewijzigd door Jurgle op 31-03-2007 00:42 ]

My opinions may have changed but not the fact that I am right ― Ashleigh Brilliant


Acties:
  • 0 Henk 'm!

  • Creepy
  • Registratie: Juni 2001
  • Laatst online: 15:14

Creepy

Tactical Espionage Splatterer

Laten we het ontopic houden he ;) Z'n vraag was voor het formatteren van 17.5 naar 17.50. Het afronden zelf lukte al prima m.v.b. de round() functie. sprintf kan dan prima voor de formattering worden gebruikt.

"I had a problem, I solved it with regular expressions. Now I have two problems". That's shows a lack of appreciation for regular expressions: "I know have _star_ problems" --Kevlin Henney


Acties:
  • 0 Henk 'm!

  • FragFrog
  • Registratie: September 2001
  • Laatst online: 09:34
Jurgle schreef op zaterdag 31 maart 2007 @ 00:09:
Zie commentaar:
PHP:
1
2
3
4
5
//Leg mij eens uit waarom:
$afgerond = substr(0, strpos('.') + 2, $getal + .005);
//niet standaardfuncties zijn en
$afgerond = sprintf("%1.2f", $getal);
//wel?


Mijn post was overigens niet heel on topic maar meer gericht aan mithrandir en flashin die Plopeye IMHO onterecht op zijn code aanspreken
Heb je de code uberhaupt zelf wel gecontroleerd? Je syntax klopt namelijk niet. Wat jij daadwerkelijk bedoelde:

PHP:
1
$afgerond = substr($getal + .005, 0, strpos($getal, '.') + 3);


ie, je had de argumentlist van zowel substr als strpos omgedraait en je bent vergeten de positie van de punt in je offset mee te nemen.

Of wat dacht je van hele getallen? Strpos zal in dat geval boolean false retouneren, wat je dus daadwerkelijk af MOET vangen, anders krijg je onzinnige resultaten (43564326 bijvoorbeeld zal met jou code nl 435 teruggeven). De code wordt dan al vervelender:
PHP:
1
$afgerond = strpos($getal, '.') === false ? $getal : substr($getal + .005, 0, strpos($getal, '.') + 3);


En zo zijn er nog wel een paar dingen waar je goed op moet letten (komma's bijvoorbeeld, andere tekens in het getal, etc etc). Voor bijna elke specifieke functie in de PHP engine geldt eigenlijk wel dat er aan meer dingen gedacht is dan je op het eerste gezicht zou zeggen, ze dan niet gebruiken is ronduit slecht coden. Plopeye werd in mijn opinie dan ook wel degelijk zeer terecht aangesproken op zijn code.

Creepy, ik neem aan dat je m.b.v. bedoelt ipv m.v.b.? ;) En daarnaast is round() overbodig aangezien sprintf dat zelf al keurig netjes kan. Zoals je in elk college numerieke wiskunde leert: afronden doe je altijd op het aller, allerlaatst - zeker met geld dus pas zodra je het daadwerkelijk als string wilt representeren :)

[ Voor 8% gewijzigd door FragFrog op 31-03-2007 05:19 ]

[ Site ] [ twitch ] [ jijbuis ]


Acties:
  • 0 Henk 'm!

  • NMe
  • Registratie: Februari 2004
  • Laatst online: 09-09 13:58

NMe

Quia Ego Sic Dico.

Wat ik niet helemaal begrijp is waarom iedereen zo aan (s)printf vasthangt, terwijl number_format maar een paar aanhangers lijkt te hebben. Dat terwijl number_format niet alleen doet wat de topicstarter vraagt, maar bovendien ook nog eens komma's kan gebruiken in plaats van punten (zoals het hoort in Nederlandse notatie). :)

@FragFrog: je hebt gelijk dat de standaardfuncties gebruiken je leven een stuk makkelijker maakt, maar over dit soort dingen nadenken zorgt er wel voor dat je ze niet for granted neemt. Het is leuk als je weet dat een standaardfunctie bestaat en hoe je hem moet gebruiken, maar het is leuker als je de werking ervan ook snapt. :)

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


Acties:
  • 0 Henk 'm!

  • smesjz
  • Registratie: Juli 2002
  • Niet online
-NMe- schreef op zaterdag 31 maart 2007 @ 05:24:
Wat ik niet helemaal begrijp is waarom iedereen zo aan (s)printf vasthangt, terwijl number_format maar een paar aanhangers lijkt te hebben. Dat terwijl number_format niet alleen doet wat de topicstarter vraagt, maar bovendien ook nog eens komma's kan gebruiken in plaats van punten (zoals het hoort in Nederlandse notatie). :)
sprintf("%1.2f",$getal) is locale aware en gebruikt dus komma's als setlocale() is gebruikt.

Dus zowel number_format als (s)printf doen hetzelfde. Misschien zou sprintf wat sneller kunnen zijn omdat PHP het gewoon als wrapper gebruikt om vsprintf (stdio.h) heen en number_format veel complexer is qua code.

Maar het verschil is bij normaal gebruik niet te merken denk ik.

Acties:
  • 0 Henk 'm!

Verwijderd

Daarnaast is het geloof ik vrij gebruikelijk om bij geld niet gebruik te maken van floating point getallen maar juist van integers.

Acties:
  • 0 Henk 'm!

  • NMe
  • Registratie: Februari 2004
  • Laatst online: 09-09 13:58

NMe

Quia Ego Sic Dico.

smesjz schreef op zaterdag 31 maart 2007 @ 11:29:
[...]

sprintf("%1.2f",$getal) is locale aware en gebruikt dus komma's als setlocale() is gebruikt.
Hmm, dat wist ik niet. :) Dan zal sprintf inderdaad wel sneller zijn ja; het vereist dan alleen wel dat je je locale netjes instelt. :)
Verwijderd schreef op zaterdag 31 maart 2007 @ 12:30:
Daarnaast is het geloof ik vrij gebruikelijk om bij geld niet gebruik te maken van floating point getallen maar juist van integers.
Dat is inderdaad preciezer in sommige gevallen, als je ermee gaat rekenen in elk geval.

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


Acties:
  • 0 Henk 'm!

  • FragFrog
  • Registratie: September 2001
  • Laatst online: 09:34
-NMe- schreef op zaterdag 31 maart 2007 @ 05:24:
@FragFrog: je hebt gelijk dat de standaardfuncties gebruiken je leven een stuk makkelijker maakt, maar over dit soort dingen nadenken zorgt er wel voor dat je ze niet for granted neemt. Het is leuk als je weet dat een standaardfunctie bestaat en hoe je hem moet gebruiken, maar het is leuker als je de werking ervan ook snapt. :)
Natuurlijk, werking kennen is belangrijk, maar je doet jezelf een groter plezier om daarvoor een echte taal te leren naast PHP :) Daarnaast denk ik dat ik net vrij mooi geillustreerd heb dat ook standaardfuncties niet zo standaard zijn als mensen graag denken ;)

As for number_format, is ook een goede optie natuurlijk, alhoewel je dan nog steeds meer code zit te gebruiken dan nodig is (mits je de locale goed gezet hebt natuurlijk). Kan me toepassingen voorstellen waarbij je de extra functionaliteit ervan wil hebben, maar ik zou niet direct hiernaar grijpen voor een simpele float.

Al met al geldt voor PHP dat er doorgaans tientallen manieren zijn om een gewenst resultaat te bereiken, het verschil tussen goede en slechte code zit hem er in mijn opinie in dat goede code gebruikt maakt van de meest geschikte functie voor de taak. Blijf er dan ook bij bij dat het geen kwaad kan om mensen erop te wijzen als ze een ongeschikte of nodeloos gecompliceerde methode aanraden :)

[ Site ] [ twitch ] [ jijbuis ]

Pagina: 1