Advertisement
If you have a new account but are having problems posting or verifying your account, please email us on hello@boards.ie for help. Thanks :)
Hello all! Please ensure that you are posting a new thread or question in the appropriate forum. The Feedback forum is overwhelmed with questions that are having to be moved elsewhere. If you need help to verify your account contact hello@boards.ie

C#, declaring a decimal and forcing only 2 digit calculation...

Options
  • 18-05-2011 2:09am
    #1
    Closed Accounts Posts: 3,912 ✭✭✭


    Hi folks,

    I'm having a problem with a bit of code that I've written. The problem being that I have a few label controls on an aspx page and I basically pull data from my DB and use a DropDownList that is populated with a selection of discount values. This all works fine, I have it updating on my DropDownSelectedIndexChanged and my labels all update as planned, except for one tiny discrepancy that I've found...

    What seems to be the problem is in this line of code:

    decimal InvoiceTotal = (CustPrice + OutputVATAmount);

    Every now and again, the values returned will be such that the addition above is calculating on the basis of 3 decimal precision points being used after the decimal place above. So the amounts are a cent off when they should be exact and I'm fairly sure that the cause of the issue is that the three decimal variables above need to be forced into the format X.XX before the calculation above is done. Maybe I've answered my own question with that last sentence but sure for pig iron, if anyone has any suggestions I'd be most grateful to hear them...!

    Thanks again for any help with this...

    EDIT: All my labels are properly formatted I think using

    InvoiceTotal.ToString("c");

    or

    InvoiceTotal.ToString("f2");

    But I'm still getting a tiny error on some calculations depending on the values involved, the error is always only 1 cent out...


Comments

  • Registered Users Posts: 14,336 ✭✭✭✭jimmycrackcorm


    Hi folks,

    I'm having a problem with a bit of code that I've written. The problem being that I have a few label controls on an aspx page and I basically pull data from my DB and use a DropDownList that is populated with a selection of discount values. This all works fine, I have it updating on my DropDownSelectedIndexChanged and my labels all update as planned, except for one tiny discrepancy that I've found...

    What seems to be the problem is in this line of code:

    decimal InvoiceTotal = (CustPrice + OutputVATAmount);

    Every now and again, the values returned will be such that the addition above is calculating on the basis of 3 decimal precision points being used after the decimal place above. So the amounts are a cent off when they should be exact and I'm fairly sure that the cause of the issue is that the three decimal variables above need to be forced into the format X.XX before the calculation above is done. Maybe I've answered my own question with that last sentence but sure for pig iron, if anyone has any suggestions I'd be most grateful to hear them...!

    Thanks again for any help with this...

    EDIT: All my labels are properly formatted I think using

    InvoiceTotal.ToString("c");

    or

    InvoiceTotal.ToString("f2");

    But I'm still getting a tiny error on some calculations depending on the values involved, the error is always only 1 cent out...

    Format currency strings with 2 decimal places: http://www.csharp-examples.net/string-format-double/


  • Closed Accounts Posts: 3,912 ✭✭✭HellFireClub


    Format currency strings with 2 decimal places: http://www.csharp-examples.net/string-format-double/

    Hi Jimmy, thanks for that... The problem is that all my input labels & strings are properly formatted as above, the issue arises when this particular calculation gets done, sometimes the output of it is not added as a price formatted amount, as in:

    It will add:

    12.44
    12.41
    24.84

    Obviously the sum above is incorrect for currency addition, as the sum returned should be 24.85. Then if the numbers involved are different, it will add correctly... :confused::confused::confused:


  • Registered Users Posts: 4,766 ✭✭✭cython


    Can you post any more complete code please? For example, your assignment and/or calculation of the numbers that you are adding together? The reason that I ask is that I am not sure that you are handling rounding correctly. As you seem to be aware, numbers stored as decimals are not automatically going to be to two places of decimal. To expand on your example figures above, the below 3 digit numbers could be the values actually in use.

    12.436 (rounds to 12.44)
    12.406 (rounds to 12.41)
    24.842 (rounds to 24.84, but sum of rounds earlier is 24.85, i.e. your problem)

    So far, the program is doing exactly what you would expect from a computer, though the result is undesirable. My advice would be that if you are only going to be working in 2 decimal places at all times, then would rounding to 2 places before the calculation be acceptable? So that
    decimal InvoiceTotal = (CustPrice + OutputVATAmount);
    
    would become
    decimal InvoiceTotal = (decimal.Round(CustPrice, 2) + decimal.Round(OutputVATAmount, 2));
    

    Having said that, I'm not the most familiar with the decimal type in C#, so this may not be the solution you seek. I only point it out as an issue that I have seen and demonstrated arising with floats and doubles in the past.


  • Closed Accounts Posts: 3,912 ✭✭✭HellFireClub


    cython wrote: »
    Can you post any more complete code please? For example, your assignment and/or calculation of the numbers that you are adding together? The reason that I ask is that I am not sure that you are handling rounding correctly. As you seem to be aware, numbers stored as decimals are not automatically going to be to two places of decimal. To expand on your example figures above, the below 3 digit numbers could be the values actually in use.

    12.436 (rounds to 12.44)
    12.406 (rounds to 12.41)
    24.842 (rounds to 24.84, but sum of rounds earlier is 24.85, i.e. your problem)

    So far, the program is doing exactly what you would expect from a computer, though the result is undesirable. My advice would be that if you are only going to be working in 2 decimal places at all times, then would rounding to 2 places before the calculation be acceptable? So that
    decimal InvoiceTotal = (CustPrice + OutputVATAmount);
    
    would become
    decimal InvoiceTotal = (decimal.Round(CustPrice, 2) + decimal.Round(OutputVATAmount, 2));
    
    Having said that, I'm not the most familiar with the decimal type in C#, so this may not be the solution you seek. I only point it out as an issue that I have seen and demonstrated arising with floats and doubles in the past.

    You've hit the nail on the head there with that advice cython, thanks a million for that, it's resolved the problem for me...


  • Registered Users Posts: 4,766 ✭✭✭cython


    You've hit the nail on the head there with that advice cython, thanks a million for that, it's resolved the problem for me...

    No problem. It's the sort of issue that if you don't know the background of the number storage mechanisms and the limits of precision, and haven't seen it before, it can be a real head-scratcher, but if you've seen it once, you'll recognise it very quickly if you see it again :)


  • Advertisement
  • Registered Users Posts: 2,781 ✭✭✭amen


    While you have fixed the values for you calculation you may also have a similar problem in your database.

    you should verify that the decimals fields in the database are defined so that they only store 2 decimal points.


  • Closed Accounts Posts: 3,912 ✭✭✭HellFireClub


    amen wrote: »
    While you have fixed the values for you calculation you may also have a similar problem in your database.

    you should verify that the decimals fields in the database are defined so that they only store 2 decimal points.

    That's the thing, the DB inserts were all bang on, because they are passed in through properly formatted strings. The problem only arose when some of the data was pulled from the DB and put through the operations above.

    Got it fully resolved now, thanks again to cython for giving me the fix...


Advertisement