2

I already searched for my problem but I wasn't successfully and that's the reason I'm here.

All I want to do is reading a string like "3.14" and convert it to double. Enough said... here is my code:

using System;

namespace GlazerCalcApplication
{
    class MainClass
    {
        public static void Main (string[] args)
        {
            string heightString;
            double height;

            heightString = Console.ReadLine();
            height = Convert.ToDouble(heightString);
            Console.WriteLine(height);
        }
    }
}

Output:

3.14
314

Press any key to continue...

Why is my double value not 3.14?

Instead of Convert.ToDouble() I also tried it with double.Parse() but I received the same behaviour. Reading strings like 3,14 is no problem. Maybe I should also mention that I use MonoDevelop and a linux OS. Thanks in advance.

2
  • What is your CurrentCulture? Commented Apr 19, 2014 at 20:53
  • finally I found it out de-DE :D Commented Apr 19, 2014 at 21:17

4 Answers 4

3

Try specifying the culture as Invariant:

height = Convert.ToDouble(heightString,CultureInfo.InvariantCulture);

It seems the decimal seperator of your culture is comma instead of dot therefore dot is truncated after conversion.

Sign up to request clarification or add additional context in comments.

Comments

3

Convert.ToDouble(string) uses Double.Parse(string, CultureInfo.CurrentCulture) method explicitly.

Here how it's implemented;

public static double ToDouble(String value) {
    if (value == null)
        return 0;
    return Double.Parse(value, CultureInfo.CurrentCulture);
}

It is likely your CurrentCulture's NumberFormatInfo.NumberDecimalSeparator property is not . (dot). That's why you can't parse a string with . as a date seperator.

Example in LINQPad;

CultureInfo c = new CultureInfo("de-DE");
c.NumberFormat.NumberDecimalSeparator.Dump(); // Prints ,

As a solution, you can create a new reference of your CurrentCulture and assing it's NumberDecimalSeparator property to . like;

double height;
CultureInfo c = new CultureInfo("de-DE");
c.NumberFormat.NumberDecimalSeparator = ".";
height = Convert.ToDouble("3.14", c);

2 Comments

The .Dump() method is some custom extension method of yours or a part of the standard library?
Okay thanks for this information. As I'm coming from C I would never think of using a ',' as separator.
2

Judging by the result I take it you are in a culture zone where comma is the normal decimal separator. Also, I take it that you want both dot and comma to be used for decimal separation. If not, the below is not the proper solution.

The fastest solution for using both would be

height = Convert.ToDouble(heightString.Replace('.', ',');

This would mean that both dots and comma's are used as comma and thus parsed as a decimal separator.

If you only want to use a dot as separator, you can use invariantculture or a specific numberformatinfo. Invariant culture is already shown in the other posts. numberformat info example:

    var nfi = new NumberFormatInfo { NumberDecimalSeparator = "." };
    height = double.Parse(heightString,nfi);

For completeness, the example below shows both using numberformatinfo for setting the dot as decimal separator, as well as replacing comma with dots, so both characters are used for decimals

    var nfi = new NumberFormatInfo { NumberDecimalSeparator = "." };
    height = double.Parse(heightString.Replace(',', '.'),nfi);

4 Comments

+0: while most of the question have good details, I can't agree with replacing separators with ,: "1.500" is not the same as "one and a half" for many countries...
@AlexeiLevenkov The answer was based on that 3,14 worked, and manual input is used. Living in the Netherlands, we often want precisely that: both characters to be used as decimal separator, because our official separator is the comma, but input is often done with the dot (numeric keypad)
But you did not specify culture if you wanted , to be parsed always as decimal separator... I know couple people that don't live in Netherlands :)...
@AlexeiLevenkov True, I'm not sure of the Orpo's intent. Altered the post to indicate what I expected what he was after. However I must say that for manual input I've done exactly that a few times. Simply because the manually entered amounts never contained group separators, only decimal separators, but yes, that's specifying a specific group of users and the request specifically was that both were considered as decimal separators. (Wow, don't think I've ever written the word separator this much one place :D )
1

Different .Net cultures (countries) have different decimal separators.

If you expect input values to be in some specific format - either use some particular culture or InvariantCulture. Also consider using double.Parse as it geve more flexibility on parsing the values than generic Convert.ToDouble.

    var d = double.Parse(heightString, CultureInfo.InvariantCulture);

If you expect user to enter value in local format - your code is fine, but either your expectation of "local format" is wrong, or "current culture" set incorrectly.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.