fbpx
Welcome, Guest
Username: Password: Remember me
  • Page:
  • 1

TOPIC:

Small incompatibility with mod operator/function 22 Feb 2021 10:01 #17524

  • ArneOrtlinghaus's Avatar

  • ArneOrtlinghaus

  • Topic Author


  • Posts: 252
  • One of our beta test customers discovered a small incompatibility for the mod function. Mod is not only defined for integers, but should be valid also for float numbers.
    f := mod(2.6, 0.5) -> VO: 0.1 X#: Exception
    f := mod(2.6, 2) -> VO: 0.6 X#: 0
    It makes really sense using floats in the mod function, if you have to distribute articles quantities into packages:
    - over all quantity of 2.6 liters to be shipped.
    - Packages of 0.5 liters
    -> 5 packages of 0.5 liters can be sent plus a remainder of 0.1 liters.
    Arne

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

    Last edit: by ArneOrtlinghaus.

    Small incompatibility with mod operator/function 22 Feb 2021 10:05 #17525

  • Chris's Avatar

  • Chris


  • Posts: 2346
  • Hi Arne,

    Mod() is indeed defined also for floating point operations. I tried your samples and they seem to work fine, but maybe it is a combination of compiler options that causes the problem. Can you please post a full sample project reproducing this problem, so we can have a look into it and fix it?
    XSharp Development Team
    chris(at)xsharp.eu

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

    Small incompatibility with mod operator/function 22 Feb 2021 10:12 #17526

  • ArneOrtlinghaus's Avatar

  • ArneOrtlinghaus

  • Topic Author


  • Posts: 252
  • Hi Chris,
    thank you for answering so quickly. I have sent you an example via email. Probably it depends on compiler settings and variable types used.

    Arne

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

    Small incompatibility with mod operator/function 22 Feb 2021 10:55 #17527

  • ArneOrtlinghaus's Avatar

  • ArneOrtlinghaus

  • Topic Author


  • Posts: 252
  • Chris has already found the reason: Usage of usuals as arguments. As a workaround I can help the compiler with casting types: f := Mod(FLOAT(u), fn) with u as usual, fn as float. Having floats or ints as arguments everything works correctly.

    Arne

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

    Small incompatibility with mod operator/function 22 Feb 2021 11:33 #17529

  • Chris's Avatar

  • Chris


  • Posts: 2346
  • Hi Arne,

    Unfortunately it's even more complicated than that, see github.com/X-Sharp/XSharpPublic/issues/571 for some more cases.

    The problem is that we tried to make the Mod() function more efficient than in VO, by providing overloads for different parameter types, but this means that now it's up to the compiler to decide at compile time how to handle the expression, without knowing in advance what the params will represent at runtime.

    We could remove the overloads and provide a single Mod() function with USUALs as in VO and make it 100% VO compatible, but this would require a full rebuild of all 3rd party libraries, which is probably better to avoid for now, since the next build will already contain several changes.

    Is the workaround with the FLOAT() conversion sufficient enough for you for now?
    XSharp Development Team
    chris(at)xsharp.eu

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

    Small incompatibility with mod operator/function 22 Feb 2021 11:42 #17530

  • ArneOrtlinghaus's Avatar

  • ArneOrtlinghaus

  • Topic Author


  • Posts: 252
  • Hi Chris,

    I think that the workaround is ok for us. I will try it the next days. There shouldn't be many occurrences like this in our code. In any case it seems to be an ugly solution that has been used here.

    Arne

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

    Small incompatibility with mod operator/function 24 Feb 2021 16:40 #17556

  • ArneOrtlinghaus's Avatar

  • ArneOrtlinghaus

  • Topic Author


  • Posts: 252
  • I am now changing our occurrences with float or usual parameters.
    It is interesting how many effects someone can find out in long running programs.
    The result for mod(2, 0.2) is not 0 as someone could imagine. It is 0.2!
    But this result in X# is equal in C#, VO, Python.
    mod(20.0, 2.0) gives 0 in all these programs.

    Arne

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

    Small incompatibility with mod operator/function 24 Feb 2021 16:46 #17557

  • ArneOrtlinghaus's Avatar

  • ArneOrtlinghaus

  • Topic Author


  • Posts: 252
  • Please Log in or Create an account to join the conversation.

    Small incompatibility with mod operator/function 24 Feb 2021 19:28 #17558

  • robert's Avatar

  • robert


  • Posts: 2074
  • Arne,
    It is even worse than that in VO:
    The VO runtime uses inline assembler and the Numeric coprocessor for calculations.
    What happens is this:
    - The input for the Mod() function are 2 64 bit floating point numbers (REAL8)
    - In the inline assembler these 2 numbers are loaded in the floating point registers in the coprocessor. These registers are not 64 bits but 80 bits, so a conversion takes place (this is done with the FLD QWORD PTR instruction)
    - The modulo operation is performed on 2 80 bits numbers and the result is a new 80 bits number
    - The result is converted back from 80 bits to 64 bits (this is done with the FSTP QWORD PTR instruction)

    So there are "rounding errors" on 3 spots:
    - Input 2 * 64 -> 80 bits
    - Calculation -> modulo on fractional numbers is never 100% accurate
    - Output 80 -> 64 bits

    This makes you wonder how our apps were running....

    Robert
    XSharp Development Team
    The Netherlands

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

    Small incompatibility with mod operator/function 25 Feb 2021 08:04 #17562

  • ArneOrtlinghaus's Avatar

  • ArneOrtlinghaus

  • Topic Author


  • Posts: 252
  • This is interesting. In my tests I saw that VO sometimes has a higher precision than Dotnet with double/real8, about 3 decimals. This should be due to the use of the 80 bit FPU.

    I believe that it needs always quite a lot of work to make business applications work correctly with floating point values . This especially if a database is in between with its own rounding behaviors. Probably converting to the Dotnet type DECIMAL will help in some cases. (decimal)2.0 % (decimal)0.2 gives 0.0.

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

    Small incompatibility with mod operator/function 25 Feb 2021 08:16 #17563

  • wriedmann's Avatar

  • wriedmann


  • Posts: 2520
  • Hi Arne,
    please let me add my 0.2 cents: I expect that a lot of rounding errors will be gone only moving from float to decimal.... decimal may be slower than "classic" numeric datatypes, but that is irrelevant.
    This will be the most important thing in a .NET migration (my first programming job was using Cobol<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.

    Small incompatibility with mod operator/function 25 Feb 2021 08:38 #17564

  • ArneOrtlinghaus's Avatar

  • ArneOrtlinghaus

  • Topic Author


  • Posts: 252
  • Hi Wolfgang,
    yes, I see it like you. But: ... everything must work with decimal.
    - There mustn't be any function in between that uses double (self written or basic X# function)
    - Every use of a database/file/control input/output in between must be verified separately, because here mechanisms are used outside of the decimal calculation.

    What should remain are the roundings that are prescribed by business rules, for example tax roundings or currency exchange roundings.

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

    Small incompatibility with mod operator/function 25 Feb 2021 09:11 #17565

  • wriedmann's Avatar

  • wriedmann


  • Posts: 2520
  • Hi Arne,
    I agree with you.
    IMHO there should be an option in the RDD that every numeric field get with decimals should return a decimal instead of a float.
    If I remember correctly, Robert had written sometimes ago that the runtime would see untyped numeric datatypes with decimals as "decimal" datatype and not more as float.
    Wolfgang
    Wolfgang Riedmann
    Meran, South Tyrol, Italy

    www.riedmann.it - docs.xsharp.it

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

    • Page:
    • 1