fbpx
Welcome, Guest
Username: Password: Remember me
Welcome to the XSharp forum!

Tell us and our members who you are, what you like and why you became a member of this site.
We welcome all new members and hope to see you around a lot!
  • Page:
  • 1
  • 2

TOPIC: If someone can explain it to me?

If someone can explain it to me? 22 Mar 2019 08:47 #7886

  • softdevo@tiscali.it's Avatar


  • Topic Author


  • Posts: 102
  • Look at the attached image: the same code in another application works perfectly, but here .... I just don't understand.
    Danilo
    Attachments:

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

    If someone can explain it to me? 22 Mar 2019 09:13 #7888

  • SHirsch's Avatar

  • SHirsch


  • Posts: 164
  • Hi Danilo,

    try using System.Decimal instead of System.Double.

    see: www.xsharp.info/forum/public-vo-vn/744-f...eal8-or-decimal#7418

    Regards,
    Stefan

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

    If someone can explain it to me? 22 Mar 2019 09:13 #7889

  • FFF's Avatar

  • FFF


  • Posts: 949
  • Sorry, Danilo,
    pls post bigger shots, this one is impossible to read.

    Karl
    Regards
    Karl (X# 2.4a; Xide 1.25; W8.1/64 German)

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

    If someone can explain it to me? 22 Mar 2019 10:24 #7892

  • wriedmann's Avatar

  • wriedmann


  • Posts: 2276
  • Hi Danilo,
    this is how real8 and floats work, and it is that way also in VO.
    Look at your SetFloatDelta() setting in both applications.
    Wolfgang
    Wolfgang Riedmann
    Meran, South Tyrol, Italy

    www.riedmann.it - docs.xsharp.it

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

    If someone can explain it to me? 22 Mar 2019 12:39 #7895

  • Terry's Avatar

  • Terry


  • Posts: 178
  • Danilo
    The reason for this boils down to rounding errors.

    Computations in a digital computer are exact using a number base of 2.
    Our understanding is based on a base of 10.

    Any conversion will be slightly inaccurate.

    To ensure total and absolute consistency in this process every calculation made must be rounded in the same way (up or down). Any compiler will do this in a consistent way.

    The downside of this is that the rounding process takes time, and if we require total accuracy, must be done as part of each calculation. When there are thousands of such conversions/calculations to be done this mounts up.

    As long as we are dealing with very small rounding errors we need not worry because they will never build up to such an extent as to have any noticeable effect on what we are trying to calculate.

    For example, calculating an on-screen pixel position to 2 places of decimals would achieve little.

    Floats are designed to calculate numerical results over a huge range, whilst not requiring the additional time-consuming overhead of base numbering scheme conversion.

    Therefore, you should never use Floats in any situation where absolute comparisons/values may be required.
    They do save time of course, when compared to decimal. It’s a case of “horses for courses”.

    Terry
    PS Having just read Wolfgang's reply I'm just guessing that SetFloatDelta() gives an accuracy limitation on Floats, allowing the compiler to do things to whatever accuracy is required.
    So rather than saying never use Floats, I guess it should be "do not use floats unless SetFloatData() is set.
    That is just a guess.

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

    Last edit: by Terry. Reason: Just Read Wolfgangs Reply

    If someone can explain it to me? 22 Mar 2019 16:45 #7907

  • softdevo@tiscali.it's Avatar


  • Topic Author


  • Posts: 102
  • Thanks to all, but I don't understand why with any other value it gives a correct result and only 8.70 gives error, then multiplying by 100 should not generate any rounding.
    Another thing I don't understand is why the same code in any other application works.
    I will try your suggestions, but I'm not satisfied, because every calculation is therefore in danger.
    Danilo

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

    If someone can explain it to me? 22 Mar 2019 17:33 #7908

  • Chris's Avatar

  • Chris


  • Posts: 1938
  • Hi Danilo,

    Some decimal numbers can be represented better than others. For example, the decimal value 0.625 can be perfectly represented in binary accurately as 0.101, while 0.626 can only be represented in approximation.

    The important question is, do you get a problem in your app while running it, or is it just the value you see in the debugger that you do not like? Because normally, when you actually print values to show to the user, you use some kind of rounding, which will eliminate that precision lost.
    XSharp Development Team
    chris(at)xsharp.eu

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

    If someone can explain it to me? 22 Mar 2019 18:02 #7911

  • Terry's Avatar

  • Terry


  • Posts: 178
  • Hi Danilo

    Unfortunately, as Karl said, I could not read your post properly.

    I made an assumption that it was probably due to rounding errors. I should not have done this - there may be other factors at play here.

    We need to see the full code properly.

    Sorry if I've managed to steer this discussion in the wrong direction.

    Terry

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

    If someone can explain it to me? 22 Mar 2019 18:19 #7913

  • Chris's Avatar

  • Chris


  • Posts: 1938
  • No worries Terry, I think both your and Karl's points were valid as well.
    XSharp Development Team
    chris(at)xsharp.eu

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

    If someone can explain it to me? 23 Mar 2019 09:52 #7928

  • Terry's Avatar

  • Terry


  • Posts: 178
  • Thanks Chris. It will be interesting to see what the problem turns out to be.

    Terry

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

    If someone can explain it to me? 23 Mar 2019 18:56 #7940

  • softdevo@tiscali.it's Avatar


  • Topic Author


  • Posts: 102
  • For those who have not read the image correctly, here is the simplification of the code under discussion:
    (As I said, the same code in another application gives the right result: 870)
    LOCAL cOre AS STRING
    LOCAL nNUORE AS System.Double
    LOCAL nTOMIC AS System.Double

    cOre := SELF:Gior:Text // "8,70"
    nNUORE := Val(cOre) // 8.70
    nTOMIC := (System.Double)(nNUORE*100,0) // 869.99999999999989 ERROR!!!!!!!!!!!!!!

    Danilo

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

    If someone can explain it to me? 23 Mar 2019 18:59 #7941

  • softdevo@tiscali.it's Avatar


  • Topic Author


  • Posts: 102
  • excuse me

    LOCAL cOre AS STRING
    LOCAL nNUORE AS System.Double
    LOCAL nTOMIC AS System.Double

    cOre := SELF:Gior:Text // "8,70"
    nNUORE := Val(cOre) // 8.70
    nTOMIC := (System.Double)(nNUORE*100) // 869.99999999999989

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

    If someone can explain it to me? 23 Mar 2019 19:03 #7943

  • wriedmann's Avatar

  • wriedmann


  • Posts: 2276
  • Ciao Danilo,

    if you put that value to a database field with 2 decimals, or display it using a picture, it is rounded to a correct value.

    I have these issues in VO all the time, and therefore I'm using Round() a lot, other than setting SetFloatDelta() to 0.0001.
    In .NET fortunately we have the "decimals" datatype, and AFAIK it is the datatype the X# runtime uses internally for decimal numbers.
    Wolfgang
    Wolfgang Riedmann
    Meran, South Tyrol, Italy

    www.riedmann.it - docs.xsharp.it

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

    If someone can explain it to me? 23 Mar 2019 19:09 #7944

  • softdevo@tiscali.it's Avatar


  • Topic Author


  • Posts: 102
  • Thanks Wolfgang, since the number is always a whole I solved this

    nTOMIC := (System.Double)Round(nNUORE*100,0) //(System.Double)(nNUORE*100) //

    But the problem remains …
    Danilo

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

    If someone can explain it to me? 23 Mar 2019 19:17 #7945

  • wriedmann's Avatar

  • wriedmann


  • Posts: 2276
  • Hi Danilo,
    the problem is not a problem of VO or X#, but a problem in the Microsoft Floating Point Library, or better in the representation of float or double. The float or real8 datatype was never planned for exact calculations, unfortunately.
    Use System.Decimal whenever possible.
    Wolfgang
    Wolfgang Riedmann
    Meran, South Tyrol, Italy

    www.riedmann.it - docs.xsharp.it

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

    If someone can explain it to me? 23 Mar 2019 19:31 #7946

  • Chris's Avatar

  • Chris


  • Posts: 1938
  • Danilo, please try this code in VO, or any other language:
    FUNCTION Start() AS INT
    LOCAL f1 AS REAL8
    LOCAL f2 AS REAL8
    
    SetFloatDelta(0)
    
    f1 := 0.015
    f1 := f1 + f1 + f1
    f1 *= 10.0
    
    f2 := 0.45
    ? f1==f2 , f1<f2 , f1>f2
    	WAIT 
    RETURN 0 

    Similarly in c#:
    public class Program
    {
    	static void Main()
    	{
    		double f1;
    		double f2;
    		
    		f1 = 0.015;
    		f1 = f1 + f1 + f1;
    		f1 *= 10.0;
    		
    		f2 = 0.45;
    		System.Console.WriteLine(f1==f2);
    		System.Console.WriteLine(f1<f2);
    		System.Console.WriteLine(f1>f2);
    	}
    }

    In both samples, you would expect f1 == f2 == 0.45, but both samples return FALSE for == and TRUE for <. This is because none of those values can be represented in binary accurately, there is some precision loss, and the more arithmetic you do with decimal numbers, the more precision is lost.

    When you store 0.015 in the f1 var, the actual value stored is something like 0.0149999999791 or similar, because there is no way to represent 0.015 in binary notation that the REAL8, REAL4, FLOAT etc types use. Yes, when you see the value in the debugger or print it with a function, you will usually see 0.015, but this is because there is a runtime function used to print the value, and this is smart, knowing about the precision lost and converts 0.0149999999791 to 0.015 before displaying it. But after a number of calculations with float numbers, you end up with accumulated precision lost in each calculation, so the end result is slightly wrong, and this is why you see this strange value in the debugger sometimes and sometimes not.

    For this reason, there is the Decimal type in .Net, which does not store values in binary format internally, but uses a decimal representation. This makes it much slower, but also has zero precision lost, 0.015 will always be 0.015 with this type.
    XSharp Development Team
    chris(at)xsharp.eu

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

    If someone can explain it to me? 23 Mar 2019 19:40 #7948

  • Chris's Avatar

  • Chris


  • Posts: 1938
  • Hi Wolfgang,

    wriedmann wrote: In .NET fortunately we have the "decimals" datatype, and AFAIK it is the datatype the X# runtime uses internally for decimal numbers.


    X# is working exactly as in VO:

    REAL8 and FLOAT use 8 bytes for representing the stored value, in binary format. REAL8 is a synonym for the .Net type System.Double, FLOAT is a special class which again uses a System.Double and also includes formatting info as in VO.

    REAL4 uses 4 bytes, in binary format again, it is a synonym for System.Single.

    When you want to use the Decimal type, you need to specify it explicitly.
    XSharp Development Team
    chris(at)xsharp.eu

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

    If someone can explain it to me? 24 Mar 2019 09:10 #7956

  • softdevo@tiscali.it's Avatar


  • Topic Author


  • Posts: 102
  • Ok guys, thanks to everyone, everything is clear.
    Now I ask if I use System.Decimal instead of System.Double in my calculation class for attendance management that makes thousands of operations on decimal numbers, will the slowness of the decimal be appreciable or irrelevant?
    Danilo

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

    If someone can explain it to me? 24 Mar 2019 10:56 #7958

  • lumberjack's Avatar

  • lumberjack


  • Posts: 683
  • Danilo,

    wrote: Ok guys, thanks to everyone, everything is clear.
    Now I ask if I use System.Decimal instead of System.Double in my calculation class for attendance management that makes thousands of operations on decimal numbers, will the slowness of the decimal be appreciable or irrelevant?

    It all depends, will try to explain with a bad coding example:
    LOCAL x, y as <SomeFloatType>
    x := 1.2 * (2.0 / 3.0) <rest of calculation>
    WHILE ctr < 1000000 .AND. x <> 0.0
        IF (1.2 * (2.0 / 3.0) <rest of calculation>) < 345.34555
            y += 1.2 * (2.0 / 3.0) <rest of  calc>
            x := 1.2 * (2.0 / 3.0) <rest of change x positively>
        ELSE
            y -= 1.2 / (2.0 / 3.0) <whatever>
            x := 1.2 / (2.0 / 3.0) <rest of change x negatively>
        ENDIF
        ctr++
    ENDDO
    Think we get the idea, we heavily making use of floating point calculations and we end up with (2.0 / 3.0) that cannot be represented exactly, we cannot get past that, but we can minimize the impact:
    LOCAL x, y as <SomeFloatType>
    LOCAL xneg, xpos AS <FloatType>
    xneg := 1.2 / (2.0 / 3.0)
    xpos := 1.2 * (2.0 / 3.0)
    x := xpos <rest of calculation>
    WHILE ctr < 1000000 .AND. x <> 0.0
        IF (x <rest of calculation>) < 345.34555
            y += xpos <rest of  calc>
            x := xpos <rest of change x positively>
        ELSE
            y -= xneg <whatever>
            x := xneg <rest of change x negatively>
        ENDIF
        ctr++
    ENDDO
    So yes it will have an impact, but you can minimize that impact that reduce the number of floating point arithmetic calculations. This is an extreme example but the impact will be reduced aka. speed up the process.

    In a single non-looped actual implementation it should not distract the user experience. Try where possible to eliminate floating point bottlenecks.

    Hope that helps,
    ______________________
    Johan Nel
    George, South Africa

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

    If someone can explain it to me? 24 Mar 2019 12:47 #7959

  • Chris's Avatar

  • Chris


  • Posts: 1938
  • wrote: Ok guys, thanks to everyone, everything is clear.
    Now I ask if I use System.Decimal instead of System.Double in my calculation class for attendance management that makes thousands of operations on decimal numbers, will the slowness of the decimal be appreciable or irrelevant?
    Danilo


    Most probably the speed difference will be irrelevant, because usually in our apps it's other things that slow down performance (disk access, GUI updates etc) and not numeric calculations. Of course I would not use the Decimal type if I wanted to calculate fractals, but for regular calculations, let's say 1,000 or 10,000 numeric calculations per command the difference will be zero. But of course it's always better if you give it a try and see in practice what difference it makes, if any.
    XSharp Development Team
    chris(at)xsharp.eu

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

    • Page:
    • 1
    • 2