Problems with SKILL functions: fix, truncate, floor

Discussion in 'Cadence' started by Manuel Koch, Nov 7, 2004.

  1. Manuel Koch

    Manuel Koch Guest

    Hi all,
    I'm running into some problems with integer-skill functions.

    I do the following directly in the CIW, it also won't work when I use
    these functions in my pcells that I'm trying to get to work correctly:

    Set the variables:

    w=0.7
    x=0.8

    so (w+0.1)/x evaluates correctly to 1.0

    fix((w+0.1)/x) evaluates falsly to 0,
    wheras fix(1.0) gives correctly 1

    same problems with truncate and floor.
    What am I missing here?

    Manuel
     
    Manuel Koch, Nov 7, 2004
    #1
  2. Manuel Koch

    Jim Newton Guest

    everybody thinks they find problems with the SKILL
    integer functions.

    in the case where you think (w+0.1)/x evaluates to 1.0,
    i think you will actually find that
    (w+0.1)/x == 1.0 evaluates to nil.

    i.e., (w+0.1)/x prints as 1.0 but is acutally something
    like .9999999999999999999999


    don't be confused into thinking that just because
    a number prints as 1.0 that it is identically equal
    to 1.0

    -jim
     
    Jim Newton, Nov 7, 2004
    #2
  3. And to add to what Jim says - this is not unique to SKILL. Other
    languages (C for example) will do exactly the same thing.

    The confusion arises primarily because rounding errors occur because
    floating point numbers are represented with a binary mantissa in IEEE
    floating point formats. 0.1 (decimal) is an infinitely recurring
    binary fraction. So whilst you would be quite expecting to see
    rounding errors if you do manual decimal arithmetic, and represent
    1/3 as 0.33333 to a finite number of digits, you don't expect that the
    machine will have the same problem in its representation of 1/10.

    In any number base, you can only represent numbers which are sums of
    fractions of the factors of the base exactly. In decimal this means
    1/10, 1/5, 1/2 and combinations and powers of these. In binary that
    only means 1/2 (and so 1/4, 1/8, 1/16 etc). You cannot represent 1/10
    as a sum of powers of 1/2 exactly.

    So it's very easy to get rounding errors on numbers that would appear
    to be easy to calculate as a human, as Jim outlined.

    Regards,

    Adrew.
     
    Andrew Beckett, Nov 8, 2004
    #3
  4. Yep. Also, note that SKILL offers a function that C doesn't: round().
    We often use this when we need to get a polygon point onto a
    manufacturing grid.

    If you truly need floor, truncate, equality, etc., it's often necessary
    to fudge with an epsilon value. Unfortunately, there's no "silver
    bullet" -- each floating-point operation can potentially add some error,
    and the correct epsilon to use depends on the computation. Entire PhD
    theses have been devoted to this subject.

    A few Google searches on this topic for further reading. If your head
    doesn't hurt after reading these, you might consider a career in
    numerical analysis... :)

    J. Demmel, "Basic Issues in Floating Point Arithmetic and Error
    Analysis" (Berkeley CS267 lecture notes)
    http://http.cs.berkeley.edu/~demmel/cs267/lecture21/lecture21.html

    "Python Tutorial: B. Floating Point Arithmetic: Issues and Limitations"
    http://docs.python.org/tut/node15.html

    D. Goldberg, "What Every Computer Scientist Should Know About
    Floating-Point Arithmetic."
    http://docs.sun.com/source/806-3568/ncg_goldberg.html
     
    David Cuthbert, Nov 8, 2004
    #4
  5. Manuel Koch

    Jim Newton Guest

    actually COMMON LISP does offer lossless calculation in the
    form of rational numbers. i.e., internally represented as
    pairs of arbitrarily large integers (bignums). The calculations
    can be expensive and memory intensive but you can really do the
    equivalent of

    a = 1 / 3
    b = a * 3 ; returns 1 exactly

    (setf a (/ 1 3)
    b (* a 3))


    I'm not sure why SKILL does not implement bignums and rationals.

    -jim
     
    Jim Newton, Nov 9, 2004
    #5
  6. Manuel Koch

    fogh Guest

    I would like to remind us that 0.99999... == 1 should return true.
    without using series convergence, an easy way to see it is :
    x=0.99999...
    10x-x
    =9.9999... - 0.99999
    =9
    =9x
    and 9x=x has x=1 for solution.
     
    fogh, Nov 10, 2004
    #6
  7. Er, this is rubbish. That's only true if there is an infinite sequence of 9's in the fractional
    part, or you extend the number with another 9 when you multiply by 10.
    Otherwise, you'll end up with a rounding error, or zero-extension error. For example,
    imagine you were representing a number with 6 decimal significant digits:

    x=0.999999
    10x => 9.999990
    10x-x => 8.999991 (which may well get rounded down to 8.99999)
    and so it does not give 9 as the solution. Since 9x=8.999991 gives
    x being 0.999999 your argument falls over...

    Andrew.
     
    Andrew Beckett, Nov 10, 2004
    #7
  8. Probably because SKILL is based on a flavour of lisp which pre-dates Common Lisp,
    and nobody has ever asked for rational number support.

    Andrew.
     
    Andrew Beckett, Nov 10, 2004
    #8
  9. Manuel Koch

    Jim Newton Guest

    another intuitive way to see this is

    1/9 = .1111111111...
    2/9 = .2222222222...
    3/9 = .3333333333...
    4/9 = .4444444444...
    ....
    8/9 = .8888888888...
    9/9 = .9999999999...
    but of course 9/9 is just another way of writing 1

    -jim
     
    Jim Newton, Nov 11, 2004
    #9
  10. Manuel Koch

    gennari Guest

    There are various round() functions available with some C/C++ libraries. You
    can also implement your own round (though not as good as a built-in
    function):
    * If number is positive, add 0.5 and convert to an integer
    * If number is negative, subtract 0.5 and convert to an integer

    If you want to round to, say, tenths, then multiply the floating-point
    number by 10, round, and divide by 10 (using floating-point division).

    Frank
     
    gennari, Nov 12, 2004
    #10
Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.