Incorrect values when using float.Parse(string)

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • trevor

    Incorrect values when using float.Parse(string)

    Incorrect values when using float.Parse(str ing)

    I have discovered a problem with float.Parse(str ing) not getting values
    exactly correct in some circumstances(C SV file source) but in very
    similar circumstances(X ML file source) and with exactly the same value
    it gets it perfectly correct all the time.

    These are the results I got, XML is always correct, CSV are only
    incorrect for some of the values (above about 0.01) but always gives
    the same incorrect value.

    StringValue XMLfloat CSVfloat
    0.001380697 0.001380697 0.001380697 OK
    0.008801419 0.008801419 0.008801419 OK
    0.011789167 0.011789167 0.0117891673 Error
    1.115063567 1.115063567 1.11506355 Error
    2.233219287 2.233219287 2.23321939 Error

    As you can see in the (CSV file source) I have tried parsing to double
    then to float but the error still accurse when going into float.
    The two bits of code are in the same class just different methods.

    Are there any environmental parameters that can affect the way floats
    operate?

    XML file source
    private static float GetAttributeFlo at(XmlAttribute Collection
    _Attributes, AttributeName _AttributesName )
    {
    float _ValidFloat = 0.0F;
    foreach(XmlAttr ibute _Attribute in _Attributes)
    {
    if(Equals(_Attr ibute.Name,_Att ributesName))
    {
    try
    {
    _ValidFloat = float.Parse(_At tribute.Value);
    }
    catch(Exception )
    { }
    }
    }
    return _ValidFloat;
    }

    CSV file source
    int[] CurveADC = new int[EnergyCompTable Values];
    float[] CurveDose = new float[EnergyCompTable Values];
    for(int y=0;y < EnergyCompTable Values;y++)
    {
    // CurveADC[y] = int.Parse(CalDa ta[CalDataIndex++]);
    // float temp = 0.0F;
    // string datas = CalData[CalDataIndex++];
    // double temp2 = Convert.ToDoubl e(datas);
    // float temp3 = (float)temp2;
    // temp = float.Parse(dat as,new
    System.Globaliz ation.CultureIn fo("en-GB", true));
    // CurveDose[y] = temp;
    CurveDose[y] = float.Parse(Cal Data[CalDataIndex++]);
    }



    Background info:
    Basically I have got two files XML & CSV format which contain
    identically the same data. The data is converted into a binary image
    for uploading into hardware, which ever file is used identical binary
    images are required.

  • Marc Gravell

    #2
    Re: Incorrect values when using float.Parse(str ing)

    Well, float.Parse yelds as below (as the default .ToString()), as does the
    number itself (evaluated at the immediate window):

    ?float.Parse("1 .115063567")
    1.11506355
    ?1.115063567F
    1.11506355
    ?1.115063567F== float.Parse("1. 115063567")
    true

    Are you sure the problem isn't formatting? And note that floating points are
    *by definition* not exact.
    I can't recall the format specifier to get the full value, but I'm also not
    100% that it is actually there...

    Marc


    Comment

    • Carl Daniel [VC++ MVP]

      #3
      Re: Incorrect values when using float.Parse(str ing)

      trevor wrote:
      Incorrect values when using float.Parse(str ing)
      >
      I have discovered a problem with float.Parse(str ing) not getting
      values exactly correct in some circumstances(C SV file source) but in
      very similar circumstances(X ML file source) and with exactly the same
      value it gets it perfectly correct all the time.
      >
      These are the results I got, XML is always correct, CSV are only
      incorrect for some of the values (above about 0.01) but always gives
      the same incorrect value.
      >
      StringValue XMLfloat CSVfloat
      0.001380697 0.001380697 0.001380697 OK
      0.008801419 0.008801419 0.008801419 OK
      0.011789167 0.011789167 0.0117891673 Error
      1.115063567 1.115063567 1.11506355 Error
      2.233219287 2.233219287 2.23321939 Error
      You're expecting more from floating point math than it can provide. See



      In a nutshell, a float has about 8 significant digits. The two values
      you've shown above differ in the 9th significant digit. This may be due to
      a single bit difference in the float representation, or, more likely, is
      related to the specific sequence of widening and narrowing conversions that
      the two code paths exhibit - particularly on the output (conversion from
      float to string) side.

      Have you compared the binary representations of the Xml- and Csv-derived
      floats to see if they're really different? Despite the various oddities
      that are seen with floats, it would seem reasonable to expect that
      float.Parse(str ) will always return the same value for a given sequence of
      characters, although I can't see anything obvious in the .NET documentation
      that guarantees that.

      -cd




      Comment

      • Marc Gravell

        #4
        Re: Incorrect values when using float.Parse(str ing)

        I forgot to say... you are operating very close to the limit of floats...
        suggest you switch to doubles (or decimals if they fit your data; check the
        range).

        Might also want to read:

        Numerics.NET: Numerical components for the .NET framework. Develop financial, statistical, scientific and engineering applications in C# or Visual Basic.NET faster. Includes curve fitting, optimization, regression, ANOVA, vector and matrix classes with BLAS and LAPACK interface.

        or


        (Jon: your online "exact double" page still points to aspspider, which is a
        404... probably not critical though)

        Marc


        Comment

        • trevor

          #5
          Re: Incorrect values when using float.Parse(str ing)

          Im fixed to using floats due to hardware that the binary image ends up.

          Yes the binary image is different by as much as 2 or 3 bits, this is
          what led me to tracking it back to the float problem.

          I have even created a little method just for the float parsing, both
          CSV & XML processing call this but still produce the different results.

          Yes I would expect identical strings to give identical results
          regardless of the situation, it must use the same underlying code.

          Comment

          • Marc Gravell

            #6
            Re: Incorrect values when using float.Parse(str ing)

            To be honest, I don't think float.Parse is the culprit here. I can't believe
            it would return different things for the same string.

            Are you sure you are reading the CSV correctly? The code to fill CalData
            isn't shown, but I would be *very* interested to see what the ?strings?
            actually are inside this array. The floating point accuracy will prevent you
            getting the number you first thought of, but it should be possible to get
            the same number via either route. The following works just fine (although
            you do get minor variance from the input values):

            static void Main() {
            const string xml = @"
            <xml a=""0.011789167 ""
            b=""1.115063567 ""
            c=""2.233219287 ""/>";
            const string csv = "0.011789167,1. 115063567,2.233 219287";
            float[,] data = new float[3,2];
            XmlDocument doc = new XmlDocument();
            doc.LoadXml(xml );
            int index = 0;
            foreach(XmlAttr ibute xmlValue in doc.DocumentEle ment.Attributes ) {
            data[index++, 0] = float.Parse(xml Value.Value);
            }
            index = 0;
            foreach (string csvValue in csv.Split(',')) {
            data[index++, 1] = float.Parse(csv Value);
            }
            for (int i = 0; i < 3; i++) {
            float v1 = data[i, 0], v2 = data[i,1];
            Debug.WriteLine (string.Format( "{0} vs {1}: {2}",
            v1.ToString("E1 2"), v2.ToString("E1 2"), v1 == v2 ? "OK" : "Error"));
            }
            }


            Comment

            • Jon Skeet [C# MVP]

              #7
              Re: Incorrect values when using float.Parse(str ing)

              Marc Gravell <marc.gravell@g mail.comwrote:
              I forgot to say... you are operating very close to the limit of floats...
              suggest you switch to doubles (or decimals if they fit your data; check the
              range).
              >
              Might also want to read:
              >
              Numerics.NET: Numerical components for the .NET framework. Develop financial, statistical, scientific and engineering applications in C# or Visual Basic.NET faster. Includes curve fitting, optimization, regression, ANOVA, vector and matrix classes with BLAS and LAPACK interface.

              or

              >
              (Jon: your online "exact double" page still points to aspspider, which is a
              404... probably not critical though)
              Cheers - aspspider keeps losing my account, so I need to keep
              reuploading the content. Thanks for pointing it out :)

              --
              Jon Skeet - <skeet@pobox.co m>
              http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
              If replying to the group, please do not mail me too

              Comment

              Working...