- Home /
float.Parse no longer working
I had a working project with the following lines of code
public InputField mass;
float val = float.Parse(mass.text);
Pretty straighforward, an user puts an ammount of mass and it gets parsed from text to float, this was working perfecitly fine days ago, I was even able to export the project several times, no issues whatsover.
Today I returned to make some changes, before doing so I test it out and get this error.
FormatException: Invalid format. System.Double.Parse (System.String s, NumberStyles style, IFormatProvider provider) (at /Users/builduser/buildslave/mono/build/mcs/class/corlib/System/Double.cs:209) System.Single.Parse (System.String s) (at /Users/builduser/buildslave/mono/build/mcs/class/corlib/System/Single.cs:183) ControlMasa.Update () (at Assets/Scripts/ControlMasa.cs:47)
I have no idea why it suddendly stopped working, not as if I had updated the version of Unity or anything, one day it was working and the next it wasn't.
What's the problem, what can I do?
$$anonymous$$eaning that text was not float.
Float. Parse normally have (out floatVariables) in case of Parse fail
Answer by Bunny83 · May 18, 2018 at 09:24 AM
What exactly have you typed in? Note that the float format the way you parse it depends on the local culture settings of your OS. So for example if you are in germany or france the decimal point is a comma, not a dot. To parse (and also use ToString) with an invariant culture you would need to use:
using System.Globalization;
// [ ... ]
float f = 3.1415f;
string s = f.ToString(CultureInfo.InvariantCulture)); // "3.1415"
string numString = "3.1415";
float num = float.Parse(numString, CultureInfo.InvariantCulture));
If you want to use a specific culture you would have to use
CultureInfo.CreateSpecificCulture("en-GB")
// or
CultureInfo.CreateSpecificCulture("de-DE")
// or ...
inplace of the CultureInfo.InvariantCulture
. If you don't specify a culture the system settings are used. Even i'm german and my settings are set to getman, i've manually set the decimal point to the dot in my system settings as I'm used to use the dot. Though if you want your code / game work internationally you have to decide if you want to use the users local culture or if you want to force an invariant culture. It's generally adviced if you store something to a file or format data that is exchanged with others you should use the invariant culture so reading and writeing works exactly the same everywhere. User input usually should be culture dependent so users can enter numbers the way they are used to.
Though i agree with the others that you usually should use TryParse in almost all cases. I would only use Parse if i know where the text comes from. So never for user input.
float num = float.Parse(numString, CultureInfo.InvariantCulture));
This worked for me as I am also in Germany and I am reading float values from my X$$anonymous$$L file. 2 days ago, it was working fine but since last night I was getting below warning.
Due to floating-point precision limitations, it is recommended to bring the world coordinates of the GameObject within a smaller range.
Hence, I have added CultureInfo.InvariantCulture in my float.parse() and it worked perfectly. I don't know this is the correct solution but it works. Thanks a lot Bunny83.
Well, if the string didn't contain any decimal point in the past it would have worked without any issues. Even when there is one decimal place you would get a value that's 10 times larger since the decimal point would be ignored as group symbol. Though when you have more digits behind the decimal point the number would get too large and Unity complains about it when you assign it as a gameobject's position.
For example if you had a value like 12.32
when the .
is interpreted as group character the parsed number would be 1232. It's still the wrong number but it would still work. Though if the number would be 12.328547
the number would be read as 12328547
which is too large as a position and you get a warning from Unity.
The cultural differences can be annoying ^^. The parsing methods have been designed with business application development in $$anonymous$$d where you usually want to use the local culture. However for any pure machine to machine communication you always want to use the invariant culture. A lot people also forget about this when doing the opposite: converting a float to a string which also used the local culture by default.
<lineStartPosition>
<x>0.06606403</x>
<y>0.2662269</y>
<z>0.7022002</z>
</lineStartPosition>
<lineEndPosition>
<x>0.0316592269</x>
<y>-0.07216026</y>
<z>0.663845539</z>
</lineEndPosition>
Hey @Bunny83, I figured it out why it was working 2 days back and now why It is not working. The thing is on Thursday, I changed my laptop's Regional Format setting to Germany and it caused the issue. So now when you started explaining the issue with regional formatting, I realized that maybe it is because of system's Regional Format setting. So I changed it back to US and it started working for me again without CultureInfo.InvariantCulture.
Thanks a lot for such valuable input. Just to show, above values I was trying to parse w/o CultureInfo.InvariantCulture.
Answer by KaspianR · May 18, 2018 at 07:16 AM
I think what you entered was not a real float. It might just have contained a space or a letter. A solution to this problem might be:
public InputField mass;
float val;
if(float.TryParse(mass.text, out val))
{
//Here you can put code that will only run if the text is a valid number
}
else{
Debug.Log("Text is not a valid number");
//You can replace this with whatever code you want to run if the text is not a number, perhaps show some text telling the player that they have insert a incorrect string
}
Good luck!
Your answer
Follow this Question
Related Questions
Unity doesn't Play 2 Answers
Float.Parse() Question (Quickie) 1 Answer
invalid format exception when parsing float 2 Answers
Converting a .CSV string array to a float array 1 Answer
How to use System.Globalization.NumberFormatInfo for non US games? 2 Answers