7 Replies Latest reply on Jan 18, 2018 9:22 PM by Rick Davin

    Why are my values not getting stored correctly


      I am trying to write values to PI but am not getting the results I expected.  When I write 51.200001.  PI stores 51.20000076.  I write 51.200002. PI Stores 51.20000076 (same as before).  When I write 51.200003, PI stores 51.20000458.


      Here is the C# code.  I am using the UpdateValue method.  The NewValue object is a C# decimal.  I have ran my program in debug and verifed the decimal value sent to PI.


      class PI


              static private PISDK.PISDK mSDK;

              static private PISDK.Server mServer;

              static private PISDK.PIPoints mPoints;



              public PI(String ServerName, String UserName, String PassWord="")


                  mSDK = new PISDK.PISDK();

                  mServer = mSDK.Servers[ServerName];

                  mPoints = mServer.PIPoints;







              public static PISDK.PIValue GetSnapshotValue(String TagName)


                  PISDK.PIValue mValue;

                  PISDK.PIPoint mPoint;            


                  mPoint = mPoints[TagName];

                  mValue = mPoint.Data.Snapshot;



                  return mValue;




              public static void UpdateValue(String TagName, String TimeStamp, Object NewValue )


                  mPoints[TagName].Data.UpdateValue(NewValue, TimeStamp);



        • Re: Why are my values not getting stored correctly

          Hi Steve,


          What's the point type of the PI Point you are writing to? For that level of precision I believe you'll need to be using a Float64.



          • Re: Why are my values not getting stored correctly

            Hi Steve,

            It sounds like you are running into rounding error based on how float32/float64 values are actually stored in memory.  I would recommend checking out KB1172OSI8 for more information and discussion of the issue.


            Edit: As Sebastien Raposo mentioned, adjusting the point type to Float64 if it is not already may help.


            - Adam

            1 of 1 people found this helpful
            • Re: Why are my values not getting stored correctly

              Hi Steve.


              In addition to the other's thoughts, is there any particular reason that you need so much precision? When I think of the decimal data type, I think of some kind of monetary or financial calculation, so I would be interested in why you need the precision of a decimal data type.


              As decimal is not a native data type for the PI Data Archive, I imagine that some kind of conversion is happening when the value is stored in PI. You could see something similar in C# by examining the value of something like

              double val = Convert.ToSingle(51.200001m);


              Lastly, I think it's worth mentioning here that you should absolutely consider using AF SDK over PI SDK in any kind of new project. PI SDK uses COM technology, which Microsoft has been moving away from for some time in favor of .NET, which is what the AF SDK is built with. With a PI Point that has a data type of float64 (which you can configure in SMT using the Point Builder plugin), here is what writing one of your values in AF SDK might look like:

              PIServer srv = new PIServers()["dataArchiveName"];
              double val = 51.200001;
              if (srv != null && PIPoint.TryFindPIPoint(srv, "sinusoid", out PIPoint pt)) {
                   pt.UpdateValue(new AFValue(val), AFUpdateOption.Replace);


              If you are interested in learning AF SDK we have lots of resources for getting started with it, just let us know.



              1 of 1 people found this helpful
              • Re: Why are my values not getting stored correctly
                Rick Davin

                Hi Steve,


                While you really should be using AF SDK over PI SDK, this is not an AF SDK versus PI SDK issue.  Rather its a conversion between Single (or Float) and Double (see this related link).


                If you write 51.200001, then that value is a double when calling your UpdateValue method.  The data archive checks that the receiving tag's point type is Float32, and therefore must convert from double to Single.  To get it to match, you could be sure you pass a Single to the UpdateValue method.  One way to do this:



                3 of 3 people found this helpful