6 Replies Latest reply on Nov 19, 2010 9:20 AM by Flex harUI

    String vs Number (scientific notation) problem

    forsythes

      Hello all,

       

      This has been driving me nuts now for what feels like forever. In order to illustrate my problem, I've paired down my code as much as possible to only the necessary parts. Please, if anyone can help, I would be very grateful. (I won't be able to graduate without finishing this nightmare project, and it's the only part I'm stuck on. It's central to the function of the whole program.)

       

      Thank you!

       

      The program (this part of it anyway):

      The program should import the contents of an xml file and place them in a datagrid. The data grid contains two columns: Accesion and EValue.

       

      The problem:

      EValue seems to be automatically converted to a Number... and the WRONG number at that! It is CRUTIAL that this value is imported either as the correct number or as a string. Also, it's only wrong sometimes. (See 1G2I vs. NP_126160.)

       

      Problem Table: EValue in Flex should be the same as EValue in XML

       

      AccessionEValue in FlexEValue in XML
      NP_5794483.999999999999999e-92

      4e-92

      NP_1435483.999999999999988e-84

      4e-84

      1G2I1.999999999999997e-81

      2e-81

      NP_1261601e-80

      1e-80

      YP_0029594358e-80

      8e-80

      ZP_048895922.999999999999994e-79

      3e-79

      ZP_048777842.999999999999998e-77

      3e-77

      YP_1836974.999999999999999e-76

      5e-76

      YP_00023076702.999999999999994e-75

      3e-75

       

       

      Main.mxml

       

      <?xml version="1.0" encoding="utf-8"?>

      <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"

         xmlns:s="library://ns.adobe.com/flex/spark"

         xmlns:mx="library://ns.adobe.com/flex/mx"

         xmlns:views="views.*"

         width="1400" height="900"

         preinitialize="hitsResponder.token = service.send()">

       

       

      <fx:Declarations>

      <s:HTTPService id="service"

         url="data/TestCase.xml"

         showBusyCursor="true" />

      <s:CallResponder id="hitsResponder"

      result="service_resultHandler(event)"

      fault="service_faultHandler(event)"/>

       

      </fx:Declarations>

       

      <fx:Script>

      <![CDATA[

       

      /* Imports */

      import mx.utils.ArrayUtil;

      import mx.collections.ArrayCollection;

      import mx.rpc.events.FaultEvent;

      import mx.rpc.events.ResultEvent;

      import mx.controls.Alert;

       

       

      /* Variables */

      [Bindable]

      protected var scores:ArrayCollection;

       

       

      /* Handlers */

      protected function service_faultHandler(event:FaultEvent):void

      {

      Alert.show(event.fault.faultString, event.fault.faultCode);

      }

      protected function service_resultHandler(event:ResultEvent):void

      {

      scores = event.result.hits.hit; //push hits into array collection

      }

       

      ]]>

      </fx:Script>

       

       

      <s:Panel id="dataPanel" title="Results" width="400" height="470">

      <s:layout>

      <s:VerticalLayout paddingBottom="10" paddingLeft="10" paddingRight="10" paddingTop="10" />

      </s:layout>

       

      <!-- Results grid -->

      <views:TestGrid dataProvider="{scores}"/>

      <!---->

      </s:Panel>

       

       

       

      </s:Application>

       

       

      views:TestGrid.mxml

       

      <?xml version="1.0" encoding="utf-8"?>

      <mx:DataGrid

      xmlns:fx="http://ns.adobe.com/mxml/2009"

      xmlns:s="library://ns.adobe.com/flex/spark"

      xmlns:mx="library://ns.adobe.com/flex/mx"

      width="100%" height="100%">

       

      <mx:columns>

      <mx:DataGridColumn dataField="accession" headerText="Accession" sortable="true"/>

      <mx:DataGridColumn dataField="eValue" headerText="EValue" sortable="true" visible="true"/>

      </mx:columns>

       

      </mx:DataGrid>

       

       

       

      TestCase.xml

       

      <hits>

      <hit>

      <accession>NP_579448</accession>

      <eValue>4e-92</eValue>

      </hit>

      <hit>

      <accession>NP_143548</accession>

      <eValue>4e-84</eValue>

      </hit>

      <hit>

      <accession>1G2I</accession>

      <eValue>2e-81</eValue>

      </hit>

      <hit>

      <accession>NP_126160</accession>

      <eValue>1e-80</eValue>

      </hit>

      <hit>

      <accession>YP_002959435</accession>

      <eValue>8e-80</eValue>

      </hit>

      <hit>

      <accession>ZP_04880592</accession>

      <eValue>3e-79</eValue>

      </hit>

      <hit>

      <accession>ZP_04877784</accession>

      <eValue>3e-77</eValue>

      </hit>

      <hit>

      <accession>YP_183697</accession>

      <eValue>5e-76</eValue>

      </hit>

      <hit>

      <accession>YP_002307670</accession>

      <eValue>3e-75</eValue>

      </hit>

      </hits>

        • 1. Re: String vs Number (scientific notation) problem
          forsythes Level 1

          How do I make sure the EValues are assigned correct values and types in the array?

          • 2. Re: String vs Number (scientific notation) problem
            SashaKeith Adobe Employee

            Maybe try using a combination of NumberFormatter and parsing the strings yourself? NumberFormatter should take care of the rounding issues.

            • 3. Re: String vs Number (scientific notation) problem
              forsythes Level 1

              Well, I used this to at least get it to display properly, but it's a string and therefore won't sort properly as a number. When I convert to number, it doesnt' display right.

               

              protected function service_resultHandler(event:ResultEvent):void
                          {
                              scores = event.result.hits.hit; //push hits into array collection
                             
                              for(var scoresCount:int=0;scoresCount<scores.length;scoresCount++)
                              {
                                  var thisItem:String = scores.getItemAt(scoresCount).eValue;
                                  var thisItemArr:Array = thisItem.split("e");
                                  var thisNumber:String = Math.round(thisItemArr[0]).toString();
                                  var thisMagnitude:String = thisItemArr[1];
                                  var replacement:String = thisNumber+"e"+thisMagnitude;
                                  scores.itemUpdated(scores[scoresCount].eValue = replacement);
                              }

              ...

              }

               

              I'm wondering if I should make EValue an object with the displayed value and numerical value as separate properties?

               

              Is it a bug that Flex brings scientific notation in from an XML file as a Number and then only converts SOME of them improperly? Or am I doing soemthing wrong?

               

              Is there a better way to do it?

              • 4. Re: String vs Number (scientific notation) problem
                SashaKeith Adobe Employee

                This sounds like a bug in the conversion from String to Number. It may be a known bug but you can file one if you like.

                 

                In the meanwhile, I can suggest a workaround. In your HTTPService, set the resultFormat to "xml". This will prevent the automatic parsing of String to Number. Display your Datagrid with the String values. Then while sorting, use a custom compare function.

                • 5. Re: String vs Number (scientific notation) problem
                  forsythes Level 1

                  Thank you, that's pretty much the conclusion that I've come to. I'm looking into the custom sort now. I'll post again once I get it working so that others who run into this problem have a solution as well. Thanks again!

                  • 6. Re: String vs Number (scientific notation) problem
                    Flex harUI Adobe Employee

                    String to Number follows IEEE conventions.  Not all numbers are

                    representable in floating point.  You can search past threads on floating

                    point to learn more.

                     

                    If you need exact representations, you will have to maintain the values as

                    strings and implement a custom sortCompareFunction.