Welcome, Guest
Username: Password: Remember me
Visual Objects

Please use this forum to post questions about Visual Objects and Vulcan.NET

TOPIC:

Float, Real8, or Decimal? 02 Jul 2018 12:15 #5258

  • ArneOrtlinghaus
  • ArneOrtlinghaus's Avatar
  • Topic Author


  • Posts: 339
  • Hello,

    I would like to hear your opinion. In VO we normally used float for all floating numbers.
    Our experience was that sometimes it was nice to have an automatic formatting according to assumed decimals, and
    sometimes it provoked undesired rounding errors. Having the standard system/GUIclasses it was also often the best way to interact with usuals.

    In our own transporter to X# we inserted a conversion to Real8 for all float variables because there were suggestions in the past to do this for performance reasons and thinking to get rid of old VO variable types.

    Now we have doubts about doing this. On one hand we have much old code where we did not pay attention at formatting using ntrim or Str without decimal parameters. Also usuals seem to be related to float very much. On the other hand there were proposals to use the type "decimal" to have a higher precision.

    Please Log in or Create an account to join the conversation.

    Float, Real8, or Decimal? 02 Jul 2018 12:40 #5260

    • ic2
    • ic2's Avatar


  • Posts: 1604
  • Hello Arne,

    On comp.lang there's a discussion starting with "Very interesting: XSharp development roadmap" starting 2-5-2018. Within the thread the so called decimal datatype was discussed; Chris added some code where rounding differences were absent using this datatype.

    Otherwise, this discussion can be found in comp.lang multiple times since 2000 with different winners. I've chosen FLOAT everywhere based on one of those discussions. I "tricked" the rounding error sufficiently with NTRIM but if I would start replacing code converted from VO to X# this decimal type is of course a better solution.

    Dick

    Please Log in or Create an account to join the conversation.

    Float, Real8, or Decimal? 02 Jul 2018 13:33 #5264

    • wriedmann
    • wriedmann's Avatar


  • Posts: 3297
  • Hi Arne,

    the decimal datatype for me is motivation enough to move to X#, and both Robert and Chris have confirmed that the X# runtime internally uses the decimal datatype for usuals, so goodbye rounding problems.

    After migrating my VO applications, I will change all occurrences of floats to decimals.

    So my answer to your question should be clear <g>.

    Wolfgang
    Wolfgang Riedmann
    Meran, South Tyrol, Italy

    www.riedmann.it - docs.xsharp.it

    Please Log in or Create an account to join the conversation.

    Float, Real8, or Decimal? 02 Jul 2018 14:23 #5272

    • Karl-Heinz
    • Karl-Heinz's Avatar


  • Posts: 774
  • Hi Arne,

    the only reason why the VO-Datatypes REAL4 ( single) and REAL8 ( double ) exist is to have the possiblity to talk with foreign hosted systems ( typically C / Winapi Dlls ) There´s absolutly no reason to use them with plain VO code. So, when switching to X#, i would keep at the beginning the floats and switch step by step to decimals. In german words: "Nicht zuviele Baustellen gleichzeitig eröffnen" ;-). To workaround the known float rounding problems i´m using since ages this function.

    FUNCTION Runde ( fVal AS FLOAT , iDeci AS INT ) AS FLOAT PASCAL

    RETURN Round (fVal + ( 1 / 10 ^ 10 ), iDeci )

    regards
    Karl-Heinz

    Please Log in or Create an account to join the conversation.

    Float, Real8, or Decimal? 02 Jul 2018 15:26 #5280

    • Meinhard
    • Meinhard's Avatar


  • Posts: 76
  • Karl-Heinz,

    > There´s absolutly no reason to use them with plain VO code.

    oh, there is! In VO floats are dynamic objects and therefor subject to be garbage collected.

    Regards
    Meinhard

    Please Log in or Create an account to join the conversation.

    Float, Real8, or Decimal? 02 Jul 2018 15:40 #5282

    • robert
    • robert's Avatar


  • Posts: 3442
  • Meinhard,

    You are right. They are dynamic. And in older versions of VO there was a compiler problem with Floats that could cause corruption and 5333s.

    However having said that: I have seen many examples where people followed the advise given on newsgroups and forums and changed all their floats to real8s. And then they were calling late bound function or method calls passing these real8 values as parameter. And guess what: these real8 values are then converted to floats because USUAL does not support Real8.

    My point is: you and I we know what we are doing. Many people don't know these details and blindly follow advises even in situations where it is useless and end up doing things the wrong way.
    I have learned to be careful with advises like "thy shall not use floats because floats are evil".
    So I tend to follow Karl-Heinz his advise in many cases.

    Robert
    XSharp Development Team
    The Netherlands

    Please Log in or Create an account to join the conversation.

    Float, Real8, or Decimal? 02 Jul 2018 16:54 #5285

    • ic2
    • ic2's Avatar


  • Posts: 1604
  • Hello Robert,

    Many people don't know these details and blindly follow advises even in situations where it is useless and end up doing things the wrong way.


    Not even blindly. Much of the discussion contained good arguments. If I search my "Agent" for comp.lang...

    9-9-2000 Use Real
    11-12-2000 Use Float
    9-1-2001 Use Float.

    And so on. In the latter discussion I added that using floats was CA recommended. And this is the reply from a certain Robert v.d. Hulst ;) - on a reply of Geoff - I'd say: enjoy!



    > Perhaps if you attended a VO conference somewhere you could catch up on
    > these issues. Frew (whose 'proper' name is Angswillie) was quite specific
    > about the use of the REALs as being compatibility data types and you even
    > seem to agree with this point. But I need to correct the record you seem
    > hell-bent on breaking every 5 mins, REAL4 and REAL8 are converted to a FLOAT
    > internally and hence they are actually LESS effecient than floats. Given
    > that you might save a few precious bytes per variable in static memory,
    > reals still cause dynamic memory usage so you are saving nothing.

    I agree with you: all the intermediate results of Floating Point calculations
    are handled as Float variables. That is exactly what FRU (thai is his real
    name) said at the Vo conference.
    And if you are using variables of type Real4/Real8 the compiler converts the
    intermediate results back into Real4/8 after the calculation is finished.
    For Real8 the conversion is painless, since it only involves removing the
    formatting information of a float (a float is not more than a real8 with
    formatting information stored in dynamic memory) but for a Real4 the
    conversion will mean losing some accuracy.




    Dick

    Please Log in or Create an account to join the conversation.

    Float, Real8, or Decimal? 02 Jul 2018 18:15 #5291

    • Chris
    • Chris's Avatar


  • Posts: 3835
  • Hmm, I think we need to use some specific code samples to make sure we are talking about the same thing. It's been a very long time I checked what VO does internally, but are you guys saying that in this sample there's internal conversion to FLOAT for every calculation in VO?:

    LOCAL r1,r2 AS REAL8
    r1 := 1.2
    r2 := r1 * 2 // not 2.0
    r1 := r2 + r1
    r2 := r1 * r2

    From what I remember, only the first line involves a FLOAT, because "1.2" in VO is a FLOAT literal, so it needs to be "converted" to REAL8, in order to be assigned to a REAL8 local. But form then on, all the shown arithmetic is done purely with REAL8s and no FLOATs are involved anymore. Am I wrong?

    Personally I got rid of many 5333s in VO by doing exactly that, replacing data types in intense calculations from FLOAT to REAL8.

    Note to everybody: In X# and also in Vulcan, there's definitely no conversion to FLOAT at all for this code. Actually you can avoid even the one conversion from literal FLOAT to REAL8 in the first line, by disabling the compiler option "FLOAT decimal literals"

    Some other remarks:

    - In X# and vulcan, FLOAT is not a garbage collected type anymore, so it's not that "bad" at times as in VO. Still, REAL8 and REAL4 are faster, because there's no overhead involved when using them (FLOAT is a custom data type)

    - In X# (not in vulcan), the USUAL type indeed supports the Decimal type, so if you put a Decimal value in a USUAL, then you get a Decimal out as well (in vulcan you get a FLOAT out). But that does not mean that USUALs _ALWAYS_ use the Decimal data type to store floating point numbers, if you assign a float or real8 value to a usual, then it will be stored as a FLOAT.

    For example when reading numerics from DBF fields, the value will be stored in the USUAL return type of certain RDD functions like FieldGet() as a FLOAT, which is needed for VO compatibility, as only the FLOAT type includes formatting information.

    -Regarding which is best to use, it all depends on the specific needs, so if you rely heavily on the formatting feature of FLOAT and do not intend to modify the code, then it's possible best to keep using FLOATs. A few things to have in mind (for x#):

    -REAL8 is the fastest, Decimal is the slowest, FLOAT performance is in between. AS previously stated, this speed difference can be important, or it can be completely irrelevant, depending on the usage scenario. Usually in our apps performance is limited due to disk access (loading values from DBF files) and not on numeric calculations after loading them, so in such cases the speed of the datatype used has very little if any impact.
    -Decimal does not suffer from precision lost, the others do.
    -In X#, all three types are value types (structures, stored in the stack), so none of them involve GC activity when using them.
    -In vulcan, the sizes of REAL8, FLOAT, Decimal in bytes are 8,16,16. In X# (with the X# runtime), those numbers are 8,12,16
    XSharp Development Team
    chris(at)xsharp.eu

    Please Log in or Create an account to join the conversation.

    Last edit: by Chris.

    Float, Real8, or Decimal? 02 Jul 2018 19:41 #5295

    • robert
    • robert's Avatar


  • Posts: 3442
  • Chris wrote: but are you guys saying that in this sample there's internal conversion to FLOAT for every calculation in VO?:

    LOCAL r1,r2 AS REAL8
    r1 := 1.2
    r2 := r1 * 2 // not 2.0
    r1 := r2 + r1
    r2 := r1 * r2

    From what I remember, only the first line involves a FLOAT, because "1.2" in VO is a FLOAT literal, so it needs to be "converted" to REAL8, in order to be assigned to a REAL8 local. But form then on, all the shown arithmetic is done purely with REAL8s and no FLOATs are involved anymore. Am I wrong?


    You are right that only the first line of code (in VO) involved a FLOAT. If you use REAL8 inside a function or method then it will be more efficient than FLOAT.
    The problem is that I have also seen code that does this:
    LOCAL r8 as REAL8
    LOCAL cValue AS STRING
    r8 := SomeCalculationThatReturnsAReal8()
    cValue := Ntrim(r8) //  <- this will create a FLOAT on the fly

    Or code like this
    CLASS FOO
       EXPORT MyValue as REAL8
    
    Function Test
    local oFoo AS OBJECT // or as USUAL
    local cValue as STRING
    local r8 as real8
    oFoo := Foo{}
    oFoo:MyValue := 10.0     // A FLOAT will be packaged in a USUAL and then IVarPut is called and after that the FLOAT  is  assigned to the REAL8
    r8 := oFoo:MyValue // IVarGet() is called. This reads the Real8 and stores it as float in a usual. THen afterwards the float is assigned to the r8 

    In general: REAL8 in combination with untyped and/or late bound code is worse than FLOAT because every read/write will create a temporary FLOAT inside a USUAL.

    Robert
    XSharp Development Team
    The Netherlands

    Please Log in or Create an account to join the conversation.

    Last edit: by robert.

    Float, Real8, or Decimal? 02 Jul 2018 19:51 #5298

    • ic2
    • ic2's Avatar


  • Posts: 1604
  • Hello Chris, Robert,

    Thanks for explanations.

    Personally I got rid of many 5333s in VO by doing exactly that, replacing data types in intense calculations from FLOAT to REAL8.


    Haha, that's quite remarkable. I had the same when I did the reverse many years ago.....

    Dick

    Please Log in or Create an account to join the conversation.

    Float, Real8, or Decimal? 02 Jul 2018 19:56 #5300

    • wriedmann
    • wriedmann's Avatar


  • Posts: 3297
  • Hi Chris,

    if I remember correctly, you had used not the latest VO version, and Robert wrote that he had discovered flaws in the runtime that could cause 5333s when using floats.

    Wolfgang

    P.S. anyway, this is a very interesting thread. I will bookmark it in both my pearls page and the X# Documentation Project
    Wolfgang Riedmann
    Meran, South Tyrol, Italy

    www.riedmann.it - docs.xsharp.it

    Please Log in or Create an account to join the conversation.

    Float, Real8, or Decimal? 02 Jul 2018 20:05 #5301

    • robert
    • robert's Avatar


  • Posts: 3442
  • The problem that I found had to do with calling methods or functions where one of the arguments was defined as USUAL or FLOAT. When the value passed in was the result of some kind of calculation then the (dynamic) value was calculated and allocated in dynamic memory and its address was pushed on the stack but not under the control of the GC. If any of the expressions for other parameters would trigger the GC to run then this reference on the stack was not updated.
    The solution that I created calculates each parameter first and stores the results in temporary variables (which were of course registered with the GC) and after all parameters were known then their values or addresses were pushed on the stack and the function/method would be called.
    This solved most of the FLOAT related errors (but this could happen with strings as well).

    Robert
    XSharp Development Team
    The Netherlands

    Please Log in or Create an account to join the conversation.

    Float, Real8, or Decimal? 03 Jul 2018 09:34 #5310

    • ArneOrtlinghaus
    • ArneOrtlinghaus's Avatar
    • Topic Author


  • Posts: 339
  • I feel proud having created such a nice long discussion... B)

    In VO we had the experience that mixing of types created many problems. Although most of the program worked with float, we tried to use real8 in some places and we had to change many real8 definitions back to float. I believe it was the combination together with usuals in the basic classes.

    I have now made some performance tests in X# with the X# runtime, also mixing with usuals. I would summarize it as follows:
    Although Real8 is the winner, using decimal performs still better than float and usual and has the precision advantages. Usual and float have nearly the same performance. So if trying to replace floats in old programs it can be a good idea to use decimals and not real8.
    For using decimals I had to change the literals in the code which can create much work:
    Error XS0664 Literal of type double cannot be implicitly converted to type 'decimal'; use an 'M' suffix to create a literal of this type Consolefloat2 C:\Daten\vulcan\test\Consolefloat\Consolefloat2\Program.prg 39

    Arne

    Please Log in or Create an account to join the conversation.

    Float, Real8, or Decimal? 03 Jul 2018 09:44 #5312

    • wriedmann
    • wriedmann's Avatar


  • Posts: 3297
  • Hi Arne, hi Robert,

    it would be a good thing to have automatic conversions from float or real8 values to decimal.

    Wolfgang
    Wolfgang Riedmann
    Meran, South Tyrol, Italy

    www.riedmann.it - docs.xsharp.it

    Please Log in or Create an account to join the conversation.

    Float, Real8, or Decimal? 03 Jul 2018 09:55 #5313

    • robert
    • robert's Avatar


  • Posts: 3442
  • Wolfgang,
    There is already an implicit conversion from decimal to float and back. You can see it in the file
    github.com/X-Sharp/XSharpPublic/blob/fea...p.VO/Types/Float.prg
    static operator implicit(value as System.Decimal) as Float
    				return Float{ (real8) value, RuntimeState.Decimals}
    
    static operator implicit(fl  as Float) as System.Decimal
    				return (System.Decimal) fl:_value

    For doubles we can't add these implicit operators (they are defined in the framework). We would have to change the compiler to silently do this. I will see if that can be done without breaking things.

    Robert
    XSharp Development Team
    The Netherlands

    Please Log in or Create an account to join the conversation.

    Float, Real8, or Decimal? 03 Jul 2018 10:02 #5314

    • lumberjack
    • lumberjack's Avatar


  • Posts: 720
  • Hi Arne,

    ArneOrtlinghaus wrote: I feel proud having created such a nice long discussion... B)

    Well, maybe we should convince Geoff Schaller to get involve in X#... Then every forum post will be a vvvvveeeeerrrryyyyy lllllloooooonnnnngggggggggg discussion.... :lol: :lol: :lol: :lol: :lol: :lol: :lol:

    I actually miss having a go at him these days. Dick too nice for such things...
    ______________________
    Johan Nel
    Boshof, South Africa

    Please Log in or Create an account to join the conversation.

    Last edit: by lumberjack.

    Float, Real8, or Decimal? 03 Jul 2018 10:03 #5315

    • wriedmann
    • wriedmann's Avatar


  • Posts: 3297
  • Hi Robert,

    thank you very much!

    Maybe it would be enough to make this work only for literals - if that is easier.

    I'm thinking to change my variables from float to decimal in my VO applications after the migration is complete.

    Wolfgang
    Wolfgang Riedmann
    Meran, South Tyrol, Italy

    www.riedmann.it - docs.xsharp.it

    Please Log in or Create an account to join the conversation.

    Float, Real8, or Decimal? 03 Jul 2018 11:13 #5316

    • ic2
    • ic2's Avatar


  • Posts: 1604
  • Hello Johan,

    I actually miss having a go at him these days. Dick too nice for such things...


    Thank you for that although some people may disagree :lol: .
    One of these days I think I am going to call to see if he's interested....


    DIck

    Please Log in or Create an account to join the conversation.

    Float, Real8, or Decimal? 10 Jan 2019 06:50 #7114

    • garrymacin
    • garrymacin's Avatar



    Decimals have much higher precision and are usually used within financial applications that require a high degree of accuracy. Decimals are much slower (up to 20X times in some tests) than a double/float . Decimals and Floats/Doubles cannot be compared without a cast whereas Floats and Doubles can. Decimals also allow the encoding or trailing zeros.

    Please Log in or Create an account to join the conversation.

    Float, Real8, or Decimal? 18 Feb 2019 12:33 #7374

    • ArneOrtlinghaus
    • ArneOrtlinghaus's Avatar
    • Topic Author


  • Posts: 339
  • I am back with testing what is best for our programs:
    Stay with floats or convert to another type, that's the question...

    Currently it seems for me that the X#-Runtime fits best to real8 and it is less riskier to convert everything to real8 than to stay with the float.
    I had now an issue using the function Seconds() together with float variables in x#.
    Seconds return a real8 in X#, whereas it returns a usual in VO.
    In my program I have something like:

    local fsecstart := Seconds() as float
    local fdiff as float

    ... do something
    fdiff := Seconds()-fsecstart
    // in the following condition the difference of the new seconds()
    // minus the previous seconds() call converted to float was unexpectedly smaller than 0
    // The reason seem to be the mixing of float and real8
    // In the VO-program this was treated correctly, but also in the X#-Program converting everything to real8
    if fdiff < 0
    fdiff += 86400 // for midnight change
    endif

    - When looking at the function Val it seems to returns a real8 in case of decimals.
    - Usuals seem to treat floats and real8 equally: The value assigned to seem to be returned without conversion.
    What may be the main differences is the use of the NTRIM function (unfortunately used often), that may return more undesired decimals using Real8. But already in VO we had some timeconsuming issues where the expected number of decimals in float was not what was really in the variable.

    Arne

    Please Log in or Create an account to join the conversation.