This is a discussion on sprintf problem... within the PHP General forums, part of the PHP Programming Forums category; Hello, I'm trying to write a invoice script but I have encountered a slight problem. Each product needs to ...
|
|||||||
| FAQ | Members List | Calendar | Search | Today's Posts | Mark Forums Read |
|
|||
|
Hello, I'm trying to write a invoice script but I have encountered a
slight problem. Each product needs to be listed without tax, and at the end of the file I need to show the VAT. In France VAT is 19.6% So €10.03 without vat = €12.00 with vat. So I do this : $totalwithoutvat = 0; $totalwithoutvat = 0; $totalvat =0; while ( $itemwithoutvat) = each( $px ) ) { $totalwithoutvat += $itemwithoutvat; $totalwithoutvat += sprintf("%0.2f", $itemwithoutvat * ( 1 + 19.6/100 )); $totalvat += sprintf("%0.2f",$itemwithoutvat * 19.6/100); } print ("Total Vat =".sprintf("%0.2f",$totalvat)." - Total without vat = ".sprintf("%0.2f",$totalwithoutvat)." - Total with vat = ".sprintf("%0.2f",$totalwithvat)); But I'm not sure I am using sprintf correctly, maybe I should use a different function because : When I have one item at 10.03, the result is : Total Vat = 1.97 - Total without vat = 10.03 Total with vat = 12.00 but if I have two items at 10.03 the result is : Total vat = 3.93 - Total without vat = 20.06 Total with vat = 23.99 but I need it to be : Total vat = 3.94 - Total without vat = 20.06 Total with vat = 24.00 So from what I can see, sprintf only seems to work for printing and the actual result is kept in memory, is this correct ? if so what function should I use instead? Thanks in advance :) Richard |
|
|||
|
Here is a simplifie version of my code :
<?php $total = 0; $ht = 10.03; $vat = 19.6; $total += $ht*($vat/100+1); print("Total = ".sprintf("%0.2f", $total)); $total += $ht*($vat/100+1); print(" - Total 2 = ".sprintf("%0.2f", $total)); ?> I get 12.00 and 23.99 ... what should I do to get 12.00 and 24.00 ? Richard a écrit : > Hello, I'm trying to write a invoice script but I have encountered a > slight problem. > Each product needs to be listed without tax, and at the end of the > file I need to show the VAT. In France VAT is 19.6% > So €10.03 without vat = €12.00 with vat. > So I do this : > > $totalwithoutvat = 0; > $totalwithoutvat = 0; > $totalvat =0; > while ( $itemwithoutvat) = each( $px ) ) > { > $totalwithoutvat += $itemwithoutvat; > $totalwithoutvat += sprintf("%0.2f", $itemwithoutvat * ( 1 + 19.6/100 )); > $totalvat += sprintf("%0.2f",$itemwithoutvat * 19.6/100); > } > print ("Total Vat =".sprintf("%0.2f",$totalvat)." - Total without vat > = ".sprintf("%0.2f",$totalwithoutvat)." - Total with vat = > ".sprintf("%0.2f",$totalwithvat)); > > But I'm not sure I am using sprintf correctly, maybe I should use a > different function because : > When I have one item at 10.03, the result is : Total Vat = 1.97 - > Total without vat = 10.03 Total with vat = 12.00 > but if I have two items at 10.03 the result is : Total vat = 3.93 - > Total without vat = 20.06 Total with vat = 23.99 > but I need it to be : Total vat = 3.94 - Total without vat = 20.06 > Total with vat = 24.00 > So from what I can see, sprintf only seems to work for printing and > the actual result is kept in memory, is this correct ? if so what > function should I use instead? > > Thanks in advance :) > > Richard |
|
|||
|
Sorry, this morning I have gone through everything again, and the
simplified example was wrong, but corrected it gives the right answer, however although I'm sure I've done the same with the main script I can not get the correct answer. I need to round each article seperatly so that the Vat inc prince remains the same. So a 10.03 without vat always makes 12.00 with vat. My test files works as it should : <?php $total = 0; $ht = 10.03; $vat = 19.6; $total += sprintf("%0.2f",$ht*($vat/100+1)); print("Total = ".sprintf("%0.2f",$total)); $total += sprintf("%0.2f",$ht*($vat/100+1)); print(" - Total 2 = ".sprintf("%0.2f",$total)); ?> Result : Total : 12 - Total 2 : 24 However the file I'm working on does not :( The script I'm working on makes use of the fpdf php project which automaticaly creates PDF files. Here is the extract of code : while ( list($code_tva, $articleHT) = each( $px ) ) { $tva = $tab_tva[$code_tva]; // is 19.6 % $this->SetXY(15, $y); //sets the coordinates of cell to be created in PDF file for each item ) $this->Cell( 21.5,4, sprintf("%0.2f", $articleHT),'', '','C' ); // inserts the item //=====================>>>>> $totalHT is TOTAL without VAT and $articleHT is a table which contains the price of each item without tax>>> $totalHT += $articleHT; //adds all items without vat //=====================>>>>> $totalTTC is TOTAL with VAT >>> $totalTTC += sprintf("%0.2f", ($articleHT * ( 1 + $tva/100 ))); // adds the rounded (item * 1.196) (including vat) //=====================>>>>> $totalTVA is TOTAL of VAT >>> $tmp_tva = sprintf("%0.2f",$articleHT * $tva/100); //amount of VAT of current item $a_tva[ $code_tva ] = $tmp_tva; $totalTVA += $tmp_tva; //adds current item's vat to total vat $this->SetXY(10, $y); $this->Cell( 5,4, $code_tva, 0,0,"C"); //prints vat option $this->SetXY(58, $y); $this->Cell( 21.5,4, sprintf("%0.2f",$tmp_tva),'', '' ,'C'); //prints the current item's vat amount $this->SetXY(79.5, $y); $this->Cell( 21.5,4, sprintf("%0.2f",$tva) ,'', '', 'C'); //prints the vat percentage for item $y+=4; } $this->SetXY(114,266.4); $this->Cell(15,4, sprintf("%0.2f", $totalHT), '', '', 'R' ); //prints the total amount excluding vat $this->SetXY(114,271.4); $this->Cell(15,4, sprintf("%0.2f", $totalTVA), '', '', 'R' ); //prints total amount including vat This is how I see it : If I have two different items ($articleHT) at 10.03 this line ($tva = 19.6 and $articleHT = 10.03) : $totalTTC += sprintf("%0.2f", ($articleHT * ( 1 + $tva/100 ))); Should add 12.00 to $totalTTC However it seems to add 11.99588 to $totalTTC instead ... In my test files it does exactly this, any idea why it would not do this in the real file ? Thanks again :) lists-php a écrit : > your issue is with rounding, and whether vat is applied (rounded) > per-item or on the invoice total. > > your sprintf output is simply truncating and rounding on display. you > aren't storing the rounded (up) value. > > increase the decimal positions to 4 or 6 and you'll see things better. > > Total = 11.995880 - Total 2 = 23.991760 > > the vat on 10.03 is 1.96588, which when you only display 2 positions > on display rounds up to 1.97. > > if you stored the rounded value ,on a per-item basis, you'd get what > you're after. > > now, the question is whether vat is applied per item or on the > invoice total. > > the difference becomes more obvious with say 3 items, at 10.03. on a > (rounded) per-item basis the vat total would be 5.91. on an invoice > total it would be 5.90 (rounded up from 5.89784). > > > - Rick > > > ------------ Original Message ------------ > >> Date: Saturday, March 22, 2008 10:35:12 PM +0100 >> From: Richard <php_list@ghz.fr> >> To: PHP lists <php-general@lists.php.net> >> Cc: >> Subject: Re: [php] sprintf problem... (with simplified code ) >> >> Here is a simplifie version of my code : >> >> <?php >> $total = 0; >> $ht = 10.03; >> $vat = 19.6; >> $total += $ht*($vat/100+1); >> print("Total = ".sprintf("%0.2f", $total)); >> $total += $ht*($vat/100+1); >> print(" - Total 2 = ".sprintf("%0.2f", $total)); >> ?> >> >> I get 12.00 and 23.99 ... what should I do to get 12.00 and 24.00 ? >> >> >> Richard a écrit : >> >>> Hello, I'm trying to write a invoice script but I have encountered >>> a slight problem. >>> Each product needs to be listed without tax, and at the end of the >>> file I need to show the VAT. In France VAT is 19.6% >>> So €10.03 without vat = €12.00 with vat. >>> So I do this : >>> >>> $totalwithoutvat = 0; >>> $totalwithoutvat = 0; >>> $totalvat =0; >>> while ( $itemwithoutvat) = each( $px ) ) >>> { >>> $totalwithoutvat += $itemwithoutvat; >>> $totalwithoutvat += sprintf("%0.2f", $itemwithoutvat * ( 1 + >>> 19.6/100 )); $totalvat += sprintf("%0.2f",$itemwithoutvat * >>> 19.6/100); } >>> print ("Total Vat =".sprintf("%0.2f",$totalvat)." - Total without >>> vat = ".sprintf("%0.2f",$totalwithoutvat)." - Total with vat = >>> ".sprintf("%0.2f",$totalwithvat)); >>> >>> But I'm not sure I am using sprintf correctly, maybe I should use >>> a different function because : >>> When I have one item at 10.03, the result is : Total Vat = 1.97 - >>> Total without vat = 10.03 Total with vat = 12.00 >>> but if I have two items at 10.03 the result is : Total vat = 3.93 >>> - Total without vat = 20.06 Total with vat = 23.99 >>> but I need it to be : Total vat = 3.94 - Total without vat = 20.06 >>> Total with vat = 24.00 >>> So from what I can see, sprintf only seems to work for printing >>> and the actual result is kept in memory, is this correct ? if so >>> what function should I use instead? >>> >>> Thanks in advance :) >>> >>> Richard >>> >> -- >> PHP General Mailing List (http://www.php.net/) >> To unsubscribe, visit: http://www.php.net/unsub.php >> > > ---------- End Original Message ---------- > > > |
|
|||
|
On Sat, Mar 22, 2008 at 3:37 PM, Richard <php_list@ghz.fr> wrote:
[snip=code!] > When I have one item at 10.03, the result is : Total Vat = 1.97 - Total > without vat = 10.03 Total with vat = 12.00 > but if I have two items at 10.03 the result is : Total vat = 3.93 - > Total without vat = 20.06 Total with vat = 23.99 > but I need it to be : Total vat = 3.94 - Total without vat = 20.06 Total > with vat = 24.00 Check your math, Richard. You're using sprintf() with the float correctly, you're just missing how it's rounding. (10.03 * 19.6) / 100 = 1.96588 (rounded to 1.97) ((10.03 * 19.6) / 100) * 2 = 3.93176 (rounded to 3.93) If you want it to come out to an even number with the VAT added, simply round the amount first, then multiply it. -- </Daniel P. Brown> Forensic Services, Senior Unix Engineer 1+ (570-) 362-0283 |