locked
Why do i loose the decimal when parsing a string to decimal. ? RRS feed

  • Question

  • User1253338400 posted

    Hi ,

    i have the foillowing string "117.50" and I try to convert to a decimal and get 11750.

    I am doing the following 

    string s= "117.50"

    Convert.Todecimal(s);

    result is 11750 

    expected 117.50

    thanks

    Monday, February 16, 2015 11:07 PM

Answers

  • User-434868552 posted

    @robby32

    i suggest you use the Decimal.TryParse Method (String, NumberStyles, IFormatProvider, Decimal)

    You need to be specific, depending on your globalization settings.

    Study this code:

    System.Globalization.NumberStyles style;
    System.Globalization.CultureInfo culture;
    // Croation
    Boolean goodA;
    Boolean goodB;
    String amountA = "117,50";  // pretend this is input from a Croatian
    String amountB =  "17,50";  // pretend this is input from a Croatian
    Decimal amountAparsed;
    Decimal amountBparsed;
    Decimal result;
    style   = System.Globalization.NumberStyles.AllowDecimalPoint;
    culture = System.Globalization.CultureInfo.CreateSpecificCulture("hr-HR");
    goodA = Decimal.TryParse(amountA, style, culture, out amountAparsed);
    goodB = Decimal.TryParse(amountB, style, culture, out amountBparsed);
    if(goodA && goodB) 
    {
        result = amountAparsed - amountBparsed;
        Console.WriteLine("{0} - {1} = {2}", amountAparsed, amountBparsed, result); 
        Console.WriteLine("{0} - {1} = {2}", amountAparsed.ToString(culture), amountBparsed.ToString(culture), result.ToString(culture)); 
    }

    output:

    117.50 - 17.50 = 100.00
    117,50 - 17,50 = 100,00

    Study this MSDN article:
    https://msdn.microsoft.com/en-us/library/ew0seb73(v=vs.110).asptx "Decimal.TryParse Method (String, NumberStyles, IFormatProvider, Decimal)" 

    You will likely find this useful:  http://www.csharp-examples.net/culture-names/ 

    edit:

    Note:  internally, numbers and dates are stored the same, regardless of culture; you only need to give thought to the relevance of culture to your application with regards to parsing input and formatting output.

    N.B.:  the Boolean result of a .TryParse must be true, otherwise, do not dare to use the out value.

    end edit. 

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Tuesday, February 17, 2015 2:31 AM

All replies

  • User-1716253493 posted

    Try replace dot with comma before convert

    Monday, February 16, 2015 11:52 PM
  • User-434868552 posted

    @robby32    Suwandi's suggestion is likely to work for you ...

    this implies that your system settings are likely wrong since you expect a period to be your decimal point.

    For that reason it appears that you've accidentally set the comma as your decimal point.

    https://msdn.microsoft.com/en-us/goglobal/bb688127.aspx "Globalization Step-by-Step: Number Formatting"

    Tuesday, February 17, 2015 12:04 AM
  • User1253338400 posted

    Yep the comma is there because i have set my locale to Croatian for testing. 

    Now when i do calculation , i convert to decimal and get the number back . so for example my result is 11750-1750 = 10000

    now this is $100.00 dollars but in Croatian format it should be 100,00(is that correct ? )  but instead I get  "10.000,00" when i apply the following 

    var temAmpount =  10000;

    tempOtherAmount.ToString("N" + Decimals.ToString());   ------->  gives "10.000,00" instead of 100.00 for Croatian format

    thanks

    Tuesday, February 17, 2015 12:10 AM
  • User-824199218 posted

    You have set temAmpount to ten thousand (an integer).

    Then you get the string representation of tempOtherAmount and get ten thousand (with two decimal places).

    Is there a relationship between temAmpount and tempOtherAmount? Is one supposed to be one hundredth of the other?  Can you show your calculations?

    Tuesday, February 17, 2015 12:41 AM
  • User-1716253493 posted

    Can you show complete codes?

    Below code, i guess wrong

    tempOtherAmount.ToString("N" + Decimals.ToString());

    Do you mean?

    (tempOtherAmount + Decimals).ToString("N");

    Tuesday, February 17, 2015 1:25 AM
  • User-434868552 posted

    @robby32

    i suggest you use the Decimal.TryParse Method (String, NumberStyles, IFormatProvider, Decimal)

    You need to be specific, depending on your globalization settings.

    Study this code:

    System.Globalization.NumberStyles style;
    System.Globalization.CultureInfo culture;
    // Croation
    Boolean goodA;
    Boolean goodB;
    String amountA = "117,50";  // pretend this is input from a Croatian
    String amountB =  "17,50";  // pretend this is input from a Croatian
    Decimal amountAparsed;
    Decimal amountBparsed;
    Decimal result;
    style   = System.Globalization.NumberStyles.AllowDecimalPoint;
    culture = System.Globalization.CultureInfo.CreateSpecificCulture("hr-HR");
    goodA = Decimal.TryParse(amountA, style, culture, out amountAparsed);
    goodB = Decimal.TryParse(amountB, style, culture, out amountBparsed);
    if(goodA && goodB) 
    {
        result = amountAparsed - amountBparsed;
        Console.WriteLine("{0} - {1} = {2}", amountAparsed, amountBparsed, result); 
        Console.WriteLine("{0} - {1} = {2}", amountAparsed.ToString(culture), amountBparsed.ToString(culture), result.ToString(culture)); 
    }

    output:

    117.50 - 17.50 = 100.00
    117,50 - 17,50 = 100,00

    Study this MSDN article:
    https://msdn.microsoft.com/en-us/library/ew0seb73(v=vs.110).asptx "Decimal.TryParse Method (String, NumberStyles, IFormatProvider, Decimal)" 

    You will likely find this useful:  http://www.csharp-examples.net/culture-names/ 

    edit:

    Note:  internally, numbers and dates are stored the same, regardless of culture; you only need to give thought to the relevance of culture to your application with regards to parsing input and formatting output.

    N.B.:  the Boolean result of a .TryParse must be true, otherwise, do not dare to use the out value.

    end edit. 

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Tuesday, February 17, 2015 2:31 AM
  • User1253338400 posted

    sorry tempothermount is meant to be tempamount , a typo

    Tuesday, February 17, 2015 3:38 AM
  • User1253338400 posted

    Hi,

    if lets says decimals is 2 , that i want to represent the number of decimal places, so i dont think that would be correct ,

    Tuesday, February 17, 2015 3:42 AM
  • User-1716253493 posted
            decimal d = 2;
            Response.Write(d.ToString("0:0.00"));

    Tuesday, February 17, 2015 3:53 AM
  • User1253338400 posted

    Thanks I studied the links put by 

    gerrylowry

    they helped .

    cheers

    Tuesday, February 17, 2015 4:09 AM
  • User-434868552 posted

    @robby32

    Please clarify.   Are you saying

    (a) you want to restrict the input to 2 decimal places?

    (b) you want 2 decimal places in the output?

    (c) both (a) and (b)?

    Also, if your input is from a Croatian locale, do you intend to output in the format of that locale?

    it might help if you tell us the salient points about your project with respect to this thread's O.P.

    robby32, you will discover that carefully studying this https://msdn.microsoft.com/en-us/library/system.decimal(v=vs.110).aspx will help your understanding.

    always study the remarks in MSDN articles to glean important information.  For example, from the above link you learn:

    The Decimal value type represents decimal numbers ranging from

    positive 79,228,162,514,264,337,593,543,950,335 to

    negative 79,228,162,514,264,337,593,543,950,335.

    The Decimal value type is appropriate for financial calculations that require large numbers of significant integral and fractional digits and no round-off errors.

    The Decimal type does not eliminate the need for rounding. Rather, it minimizes errors due to rounding.

    robby32, GIGO (Garbage in, Garbage out) ... if you want good data, you must edit your input.  if globalization is supported by your application, then you must edit your input with regards to the locale.

    Please read:  http://weblogs.asp.net/gerrylowry/clarity-is-important-both-in-question-and-in-answer ... if your questions are not clearly and precisely stated, your peers here at forums.asp.net will experience substantial difficulty in giving you clear answers.

    Tuesday, February 17, 2015 4:21 AM
  • User1253338400 posted

    Hi,

    thanks so much for your help , i have read the link you provided

    https://msdn.microsoft.com/en-us/library/system.decimal(v=vs.110).aspx 

    it was helpful.

    Yes i want to 2 decimal places in the output . So if they give 5 decimal places , it will be rounded to 2.

    I realise your point 

    " GIGO (Garbage in, Garbage out) ... if you want good data, you must edit your input.  if globalization is supported by your application, then you must edit your input with regards to the locale."

    Thanks

    Tuesday, February 17, 2015 5:11 AM
  • User-434868552 posted

    @robby32

    The .NET Framework has methods for rounding, and for controlling how one rounds. 

    Note in the links given that in some cases i've used .NET 4 because some of the .NET 4.5 links appear to be broken.

    also, Google is your best friend ... i suggest you learn more about rounding, including mid-point rounding so that you can choose what is best for any given situation.

    the default is "to Even" but imho it's best to be explicit for other person's who have to maintain your code.

    System.Globalization.NumberStyles style;
    System.Globalization.CultureInfo culture;
    // Croation
    Boolean goodA;
    Boolean goodB;
    String amountA = "117,54567";  // pretend this is input from a Croatian
    String amountB =  "17,54499";  // pretend this is input from a Croatian
    Decimal amountAparsed;
    Decimal amountBparsed;
    Decimal result;
    style   = System.Globalization.NumberStyles.AllowDecimalPoint;
    culture = System.Globalization.CultureInfo.CreateSpecificCulture("hr-HR");
    goodA = Decimal.TryParse(amountA, style, culture, out amountAparsed);
    goodB = Decimal.TryParse(amountB, style, culture, out amountBparsed);
    if(goodA && goodB) 
    {
        result = amountAparsed - amountBparsed;
        Console.WriteLine(" no rounding {0} - {1} = {2}", amountAparsed, amountBparsed, result); 
        Console.WriteLine(" no rounding {0} - {1} = {2}", amountAparsed.ToString(culture), amountBparsed.ToString(culture), result.ToString(culture)); 
    	Decimal amountArounded = Math.Round(amountAparsed, 2, MidpointRounding.AwayFromZero);
    	Decimal amountBrounded = Math.Round(amountBparsed, 2, MidpointRounding.AwayFromZero);
        result = amountArounded - amountBrounded; // note that result is NOT rounded
        Console.WriteLine("    away from zero {0} - {1} = {2}", amountArounded, amountBrounded, result); 
        Console.WriteLine("    away from zero {0} - {1} = {2}", amountArounded.ToString(culture), amountBrounded.ToString(culture), result.ToString(culture)); 
    	amountArounded = Math.Round(amountAparsed, 2, MidpointRounding.ToEven);
    	amountBrounded = Math.Round(amountBparsed, 2, MidpointRounding.ToEven);
        result = amountArounded - amountBrounded; // note that result is NOT rounded
        Console.WriteLine("           to even {0} - {1} = {2}", amountArounded, amountBrounded, result); 
        Console.WriteLine("           to even {0} - {1} = {2}", amountArounded.ToString(culture), amountBrounded.ToString(culture), result.ToString(culture)); 
    	amountArounded = Math.Round(amountAparsed, 2);
    	amountBrounded = Math.Round(amountBparsed, 2);
        result = amountArounded - amountBrounded; // note that result is NOT rounded
        Console.WriteLine("default is to even {0} - {1} = {2}", amountArounded, amountBrounded, result); 
        Console.WriteLine("default is to even {0} - {1} = {2}", amountArounded.ToString(culture), amountBrounded.ToString(culture), result.ToString(culture)); 
    }

    output:

     no rounding 117.54567 - 17.54499 = 100.00068
     no rounding 117,54567 - 17,54499 = 100,00068
        away from zero 117.55 - 17.54 = 100.01
        away from zero 117,55 - 17,54 = 100,01
               to even 117.55 - 17.54 = 100.01
               to even 117,55 - 17,54 = 100,01
    default is to even 117.55 - 17.54 = 100.01
    default is to even 117,55 - 17,54 = 100,01

    links:
    .NET 4.5 https://msdn.microsoft.com/en-us/library/System.Math.Round(v=vs.110).aspx 

    .NET 4   https://msdn.microsoft.com/en-us/library/3s2d3xkk(v=vs.100).aspx "Math.Round Method (Decimal, Int32)"

    .NET 4  https://msdn.microsoft.com/en-us/library/ms131275(v=vs.100).aspx  "Math.Round Method (Decimal, Int32, MidpointRounding)"

    Note:  in addition to reading the Remarks, it's also often useful to read any Community Additions on the MSDN documentation pages.

    likewise, do study the code examples on the MSDN pages whenever they are present.

    Tuesday, February 17, 2015 11:42 AM
  • User1253338400 posted

    Hi ,

    thank you so much , it has been extremely helpful and I wil definitely bookmark these links ....much appreciated

    Tuesday, February 17, 2015 4:24 PM