-
Trying to understand precision in Pd
-
@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. -
@jameslo said:
Would [makefilename $.7g] suffice? Or would it have to be .8 or .9 as some argue in this discussion?
%.7gisn't enough, but%.8gseems to catch it.
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?
Yes, but keep in mind: if you ask C to convert a binary floating-point number to a decimal string with more precision than exists in the original binary, the trailing digits are basically garbage. With
%.9gyou will definitely be able to see that two single precision floats are different, but don't rely on the specific value.For
[==], it's kinda better not to use it at all with fractional floats, unless you're sure the denominator will always be a power of two.[==]might be correct but might sometimes give you false negatives; the absdif approach lets you control the precision that's relevant for equivalence.
hjh
-
@ddw_music said:
%.7gisn't enough, but%.8gseems to catch it.That Fortran discussion I linked to presented the number 1.00000048 as an example of a 9 digit decimal that has a SPFP value that's not representable in 8 decimal digits, but it appears to me that 1.0000005 works fine. How would you prove that 8 digits is sufficient for all SPFP numbers?
-
@jameslo "The glyphosphate tales" (Roundup). "The Monsanto Tales" "The Bayer Tales"...
"Farming Times"......
"Cancer, my tractor and me"...
None good enough so I didn't post...... but maybe on the right track...
Maybe.."The Prisoner" (I am not a number I am a free man).....
If you need precision and 64-bit integer limits give you enough dynamic range then stick with that.
If you need a really massive dynamic range then you will have to put up with floating point imprecision.
I think.....
I suppose that then the question is how to predict the data shift (*/) necessary to fit in the integer range..?
David.
(when I studied Fortran74 I don't remember anyone talking about this problem). -
@whale-av Your titles made me laugh anyway. If it wasn't my thread I would've suggested "horseshoes, hand grenades, and single precision floating point." Or now, maybe "Who is number 0.1? You are number 255"
I was a software engineer for several life sciences and financial services companies and don't remember anything like 255 != 255, but we also had the luxury of more than one numeric datatype and a lot of formatting options.
