-
Trying to understand precision in Pd
-
@alexandros For modf or ceil?
-
@jameslo for ceil. I only tried the patch of the screenshot in the first post.
-
@alexandros Hmm, that's not good. The ceiling of 255 is definitely not zero and that's preventing you from seeing the thing I wanted to draw attention to. Here's another version for you to try: weird poop 2.pd

-
When performing division of rational numbers, the result will be exact if the denominator factors out such that all factors are a power of a factor of the numeric base. We're used to decimal, so those factors are 2 and 5. 20 = 2•2•5 so it's ok; 27 = 3•3•3 so we know this will be a repeating fraction (since 3 is not a factor of 10).
Floating point numbers in computers are base 2, so, for non-repeating division, the denominator must be a power of 2.
First you have [/ 1] -- 1 = 2^0 so, ok.
Then you have [/ 64] -- 64 = 2^6 so, ok.
When you introduce division by 44.1, then the denominator includes two 3s and two 7s (plus 2^-1 and 5^-1). These aren't powers of 2, so the fraction will be infinite, and rounding it off to the available precision is an approximation. Multiplying again doesn't restore the precision.
Like, 2/3 = 0.66666...7. Let's pick an arbitrary precision, say, 4 digits. 2/3 = 0.6667 (or, the floating point way, 6.667•10^(-1)). Now you multiply this back by 3 and you get 2.0001 -- there's your "higher than." This must also get rounded off, but at least it shows that inaccuracy when scaled up can eventually become visible.
The assumption that floating point math is exact is basically a good way to set yourself up for confusion or disappointment. (That is, this isn't Pd's fault -- it's IEEE 754.)
hjh
-
@jameslo The patch you provided indeed shows the bug. When clicking 44.1 the number on the bottom is 0. When clicking on 1 or 48, it's 1. But @ddw_music gave a very good explanation of why this is happening.
-
@ddw_music said:
The assumption that floating point math is exact is basically a good way to set yourself up for confusion or disappointment. (That is, this isn't Pd's fault -- it's IEEE 754.)
But what prevents Pd from displaying the inexact result, e.g. in the number box above [expr]? If the goal of patching is to make things more friendly for non-programmers, how is it helpful to hide it?
-
@jameslo said:
But what prevents Pd from displaying the inexact result, e.g. in the number box above [expr]? If the goal of patching is to make things more friendly for non-programmers, how is it helpful to hide it?
In fact, when a user types in 0.1 and it displays 0.100001 (I forget how many zeros for single-precision), this is more disturbing to non-programmers.
... because that's exactly what you get when you don't round off the last bit or two for string conversion: a whole lot of 0.n000001 or 0.n999999. SC tried this for awhile, but had to revert to a slightly lower precision for float-to-string because users really hated the more accurate display.
Python can demonstrate with double precision floats -- https://en.wikipedia.org/wiki/Double-precision_floating-point_format says "The 53-bit significand precision gives from 15 to 17 significant decimal digits precision (2−53 ≈ 1.11 × 10−16)" so let's try both:
$ python3 >>> for x in range(1, 10): x = x * 0.1; print(f"{x:.15f}") ... 0.100000000000000 0.200000000000000 0.300000000000000 0.400000000000000 0.500000000000000 0.600000000000000 0.700000000000000 0.800000000000000 0.900000000000000 >>> for x in range(1, 10): x = x * 0.1; print(f"{x:.17f}") ... 0.10000000000000001 0.20000000000000001 0.30000000000000004 0.40000000000000002 0.50000000000000000 0.60000000000000009 0.70000000000000007 0.80000000000000004 0.90000000000000002Increasing the string representation to include more digits makes it necessary to render into the UI the noise inherent in the least significant bit(s). This isn't appealing to everyone.
Since Pd uses single precision, 6 digits is the low end (and exactly the precision Pd displays). If Pd expanded these strings to 8 digits, you would see trailing digits for fractions that seem like they should be simple.
I think it's pretty common practice with floats to calculate with more precision than you're going to display, and round off for UI strings.
hjh
-
@ddw_music Thanks again. If you wanted to see that truncated noisy digit (say, to debug a patch), how would you go about displaying it? The goal is to avoid the situation above where two floats have the same display but don't equal each other. Would [makefilename $.7g] suffice? Or would it have to be .8 or .9 as some argue in this discussion https://fortran-lang.discourse.group/t/how-many-significant-decimal-digits-for-real-single-precision/2287 And for all cases 7 8 or 9, it would mean that there could be different displays of floats that actually equal each other, correct?
-
Suggest a title for this post>> "trying to understand precision in pd"(the current title is starting to annoy me :P)
-
@dreamer Finally! My intention was to solicit a whole bunch of funny titles and to make the thread playful, but I've obviously failed
Yours wins unless someone posts something funny.
