top | item 40853875

(no title)

moonchild | 1 year ago

> float

hm ...

  >>> def percent(progress, total):
  ...     return round(99 * progress / total + 0.5)
  ...
  >>> x = 9007199254740990.0
  >>> x - 1 < x
  True
  >>> percent(x - 1, x)
  100

discuss

order

tavianator|1 year ago

You're cheating by using floating-point arguments; they should be integers:

    >>> x = 9007199254740990
    >>> percent(x - 1, x)
    99
But then again,

    >>> percent(10 * x - 1, 10 * x)
    100
If your procedure has 2^53 steps, feel free to ignore my rounding recommendations, since I'll never see it get anywhere near 100% :)

Also if your username is named after the band, good taste :)

moonchild|1 year ago

> they should be integers

i am not cheating; you are cheating by trying to do integer arithmetic instead of float arithmetic. in particular: 99 * progress is a (potentially big) integer; then the quotient, from my understanding of python, is equal to the mathematical quantity rn(99 * progress / total), which is not trivial to compute. (although cpython does tend to do a particularly bad job of this sort of thing.) (compare with c or with my version of the python, where it would be rn(rn(99 * progress) / rn(total)), rounding twice, which is very easy to compute. i'm not saying the c semantics is better, mind.) when you scale up by 10x, the numerator is <1/2 'ulp' away from the denominator, and so the quotient rounds up to 99 exactly; there is still double rounding (would have been triple rounding in c and my python), because we got rn(rn(99 * progress / total) + 0.5) where what we wanted was rn(99 * progress / total + 0.5) (which is mathematically always the correct result)

i agree it is not common to have so many steps. but if i were providing a routine that was intended to be robust where others were not, i would try to be comprehensive. and i would not try to do int math with floats unless i could show it to be robust (i have sketched such a stunt! https://gist.github.com/moon-chilled/60bd2ba687dc197d93a9d22...). the integer routine is simpler and more honest anyway, and it is obvious that it works uniformly for the entire range

note also that, with x floating, the python expressions 10 * x and 10 * x - 1 are equivalent, meaning the error is on input to the percent function. (if we set progress to 10 * x - 8, the immediately preceding fp number, we do get 99, but there is no deep reason for this, and it differs for different values of 10.)

> if your username is named after the band, good taste :)

my username comes from a book: the neverending story. i am more using the german version of the name these days but i do not feel like making a new account on this godforesaken website