LAE

Welcome to the LAE community!  Please feel free to start a discussion in the discussion tab or join in a conversation.

Discussions

Members

Resources

Events

 View Only
  • 1.  Decimal rounding nearest

    Employee
    Posted 03-11-2011 10:44

    Note: This was originally posted by an inactive account. Content was preserved by moving under an admin account.

    Originally posted by: zon


    Hi,

    I've a doubt.
    I write the follwoing script for round test porpose.
    *********************************
    TESTE = 0.123/60
    TESTE1 = (TESTE*135)+0.123
    TESTE2 = TESTE1.round(-4)

    emit TESTE, TESTE1, TESTE2
    *********************************
    The result was:
    TESTE = 0.00205
    TESTE1 = 0.39975
    TESTE2 = 0.3997

    Is wrong right? TESTE2 should be 0.3998!
    Can you check please?

    Best Regards,
    ZON


  • 2.  RE: Decimal rounding nearest

    Employee
    Posted 03-11-2011 11:57

    Note: This was originally posted by an inactive account. Content was preserved by moving under an admin account.

    Originally posted by: timonk

    Zon,

    You have stumbled upon a rather amusing case of how the system is representing numbers internally.

    Take a look at the Python terminal output below:

    Python 2.4.4 (#71, Oct 18 2006, 08:34:43) [MSC v.1310 32 bit (Intel)] on win32
    Type "help", "copyright", "credits" or "license" for more information.
    >>> 0.39776
    0.39776
    >>> 0.39775
    0.39774999999999999

    Internally, 0.39776 is actually just that. So when you do a round() operation on it, you get 0.3978. However, the internal binary for 0.39775 is actually valued at 0.39774999... So when you do the round() on it, the result appears be off by one.

    If you had happened to pick 0.29775, or 0.19775, or 0.49775, you would have been fine:
    >>> 0.19775
    0.19775000000000001
    >>> 0.29775
    0.29775000000000001
    >>> 0.49775
    0.49775000000000003
    >>>

    Regards
    Timon Koufopoulos
    MDA Support.


  • 3.  RE: Decimal rounding nearest

    Employee
    Posted 03-16-2011 08:05

    Note: This was originally posted by an inactive account. Content was preserved by moving under an admin account.

    Originally posted by: zon

    Hi Timom,

    Thanks for the reply.
    But, why the system does that? Why 0,39775 is not just 0,39775 as 0,39776?
    Is actually wrong, right?

    How can I workaround this?

    Best Regards,
    ZON


  • 4.  RE: Decimal rounding nearest

    Employee
    Posted 03-16-2011 08:16

    Note: This was originally posted by an inactive account. Content was preserved by moving under an admin account.

    Originally posted by: timonk

    ZON,

    I would recommend you take a look in the BRAINScript Help (Help--> BRAINScript Help). Under the General Language Sections, there is a subject: "Floating Point Arithmetic".

    Here is an excerpt:

    "BRAINScript provides the double value type to represent floating-point numbers i.e., numbers with a decimal point. The double type is double precision (64 bits). The BRAINScript implements the IEEE standard IEEE 754 of floating-point arithmetic. Sometimes floating-point operations produce confusing results. These problmes are not due to limitations of BRAINScript, but are common to all fixed-width representations of real numbers."

    There is also an example here of a similar issue to what you are seeing, complete with BRAINScript and a proposed solution. I recommend you have a look there.

    Regards
    Timon


  • 5.  RE: Decimal rounding nearest

    Employee
    Posted 03-16-2011 08:41

    Note: This was originally posted by an inactive account. Content was preserved by moving under an admin account.

    Originally posted by: stonysmith

    By "the system".. it's meant that ANY computer based upon binary logic will have this trouble. It's referred to as "rounding error".

    Just like 1/3 is 0.33333333333..... (never ends)
    In binary, 1/10 is effectively .099999999999... (never ends)

    I would suggest reading the section "Accuracy Problems" on this article... http://en.wikipedia.org/wiki/Floating_point

    =====
    As to how to fix it.. That depends in part on how accurate you want/need your results to be. One method is to multiply by 100000 and work only with integers. Just before your output, divide by 100000. But, that may not be the best answer for your specific case.

    TESTE = 0.123*100000/60
    TESTE1 = (TESTE*135)+0.123*100000
    TESTE2 = TESTE1.round(1)/100000

    emit TESTE, TESTE1, TESTE2

    TESTE TESTE1 TESTE2
    205.0 39975.0 0.3998


  • 6.  RE: Decimal rounding nearest

    Employee
    Posted 03-17-2011 12:21

    Note: This was originally posted by an inactive account. Content was preserved by moving under an admin account.

    Originally posted by: zon

    I tried to do the multiply and then divide.

    TESTE = 1230/60
    TESTE1 = (TESTE*135)+1230
    TESTE2 = TESTE1.round(-4)
    TESTE3 = TESTE2/10000
    TESTE4 = TESTE3.round(-4)

    emit TESTE, TESTE1, TESTE2, TESTE3, TESTE4
    Results:
    TESTE TESTE1 TESTE2 TESTE3 TESTE4
    20.5 3997.5 3997.5 0.39975 0.3997

    Didn't work. Am I doing something wrong?

    Best Regards,
    ZON


  • 7.  RE: Decimal rounding nearest

    Employee
    Posted 03-18-2011 07:21

    Note: This was originally posted by an inactive account. Content was preserved by moving under an admin account.

    Originally posted by: timonk

    Use the exact same code.

    TESTE = 0.123*100000/60
    TESTE1 = (TESTE*135)+0.123*100000

    -Timon


  • 8.  RE: Decimal rounding nearest

    Employee
    Posted 03-18-2011 08:13

    Note: This was originally posted by an inactive account. Content was preserved by moving under an admin account.

    Originally posted by: rboccuzzi

    TESTE = 0.123*100000/60
    TESTE1 = (TESTE*135)+0.123*100000
    TESTE2 = TESTE1.round(1)
    TESTE3 = TESTE2/100000

    emit TESTE, TESTE1, TESTE2, TESTE3

    This should do what you are trying to do...you need to make sure you are doing a large enough * up front (*100000), to let you do a rounding in the integer portion (round using positive number, round(1)), then reverse with the / by the same number. But to be clear, you are using floating point math, and as the above cited articles mention, your results may still be represented slightly different from what you expect. This is standard on all floating point implementations using the IEEE standard.

    Cheers
    Rich