Bug 138527 - Add a more correct way to compare floating point numbers and use it
Summary: Add a more correct way to compare floating point numbers and use it
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: Web Template Framework (show other bugs)
Version: 528+ (Nightly build)
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: Chris Dumez
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2014-11-07 16:37 PST by Chris Dumez
Modified: 2014-11-09 21:51 PST (History)
8 users (show)

See Also:


Attachments
Patch (12.93 KB, patch)
2014-11-07 16:58 PST, Chris Dumez
no flags Details | Formatted Diff | Diff
Patch (13.39 KB, patch)
2014-11-08 16:54 PST, Chris Dumez
no flags Details | Formatted Diff | Diff
Patch (13.87 KB, patch)
2014-11-08 23:39 PST, Chris Dumez
no flags Details | Formatted Diff | Diff
Patch (17.65 KB, patch)
2014-11-09 13:54 PST, Chris Dumez
no flags Details | Formatted Diff | Diff
Patch (19.68 KB, patch)
2014-11-09 15:36 PST, Chris Dumez
no flags Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Chris Dumez 2014-11-07 16:37:10 PST
We should add a more correct way to compare floating point numbers and use it in the code base. We currently use std::abs(a-b) <= std::numeric_limits<T>::epsilon() in several places. However, this is not correct for arbitrary floating point values, and will fail for values that are not close to zero.
Comment 1 Chris Dumez 2014-11-07 16:58:57 PST
Created attachment 241220 [details]
Patch
Comment 2 WebKit Commit Bot 2014-11-07 17:00:41 PST
Attachment 241220 [details] did not pass style-queue:


ERROR: Source/WebKit/mac/WebView/WebHTMLView.mm:2416:  An else statement can be removed when the prior "if" concludes with a return, break, continue or goto statement.  [readability/control_flow] [4]
Total errors found: 1 in 11 files


If any of these errors are false positives, please file a bug against check-webkit-style.
Comment 3 Chris Dumez 2014-11-08 16:54:30 PST
Created attachment 241242 [details]
Patch
Comment 4 WebKit Commit Bot 2014-11-08 16:56:40 PST
Attachment 241242 [details] did not pass style-queue:


ERROR: Source/WebKit/mac/WebView/WebHTMLView.mm:2416:  An else statement can be removed when the prior "if" concludes with a return, break, continue or goto statement.  [readability/control_flow] [4]
Total errors found: 1 in 11 files


If any of these errors are false positives, please file a bug against check-webkit-style.
Comment 5 Daniel Bates 2014-11-08 22:57:58 PST
Comment on attachment 241242 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=241242&action=review

I did not review this patch for correctness. I noticed a minor nit with the citation style and had a question as to the origin of the quotation "very close with tolerance e".

> Source/WTF/ChangeLog:19
> +        which defines a "very close with tolerance e" relationship between u

Do you know what page this quotes comes from? I was unable to find this quotation when searching through the 1981 printing of The Art of Computer Programming, Volume 2 (*) or section 4.2.2 "Accuracy of Floating Point Arithmetic" of the 1998 printing. The only reference I found of this quotation is on <http://www.boost.org/doc/libs/1_34_0/libs/test/doc/components/test_tools/floating_point_comparison.html>. This web page doesn't cite the particular page(s)/section(s) referenced from The Art of Computer Programming, Volume 2 :( You may also want to consider citing the boost.org web page in this ChangeLog entry.

(*) A PDF of the 1981 printing of t <http://www.itpa.lt/~acus/Knygos/Donald.E.Knuth%20-%20The%20Art%20of%20Computer%20Programming%20I-III,%20Concrete%20Mathematics,%20The%20Tex%20Book/Addison.Wesley.Donald.E.Knuth.The.Art.of.Computer.Programming.Volume.2.pdf>

> Source/WTF/wtf/MathExtras.h:409
> +// Floating point numbers comparison.
> +// From Knuth D.E. The art of computer programming (vol II):
> +// | u - v | / |u| <= e and | u - v | / |v| <= e
> +// defines a "very close with tolerance e" relationship between u and v

You may also want to consider citing the boost.org web page, <http://www.boost.org/doc/libs/1_34_0/libs/test/doc/components/test_tools/floating_point_comparison.html>, in this comment.

Assuming you are referencing section 4.2.2 "Accuracy of Floating Point Arithmetic" of the The Art of Computer Programming then the MLA-citation would be of the form:

Knuth, D. E. "Accuracy of Floating Point Arithmetic." The Art of Computer Programming. 3rd ed. Vol. 2. Boston: Addison-Wesley, 1998. 229-45.
Comment 6 Chris Dumez 2014-11-08 23:24:08 PST
Comment on attachment 241242 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=241242&action=review

>> Source/WTF/ChangeLog:19
>> +        which defines a "very close with tolerance e" relationship between u
> 
> Do you know what page this quotes comes from? I was unable to find this quotation when searching through the 1981 printing of The Art of Computer Programming, Volume 2 (*) or section 4.2.2 "Accuracy of Floating Point Arithmetic" of the 1998 printing. The only reference I found of this quotation is on <http://www.boost.org/doc/libs/1_34_0/libs/test/doc/components/test_tools/floating_point_comparison.html>. This web page doesn't cite the particular page(s)/section(s) referenced from The Art of Computer Programming, Volume 2 :( You may also want to consider citing the boost.org web page in this ChangeLog entry.
> 
> (*) A PDF of the 1981 printing of t <http://www.itpa.lt/~acus/Knygos/Donald.E.Knuth%20-%20The%20Art%20of%20Computer%20Programming%20I-III,%20Concrete%20Mathematics,%20The%20Tex%20Book/Addison.Wesley.Donald.E.Knuth.The.Art.of.Computer.Programming.Volume.2.pdf>

This is on page 218 - 219. Knuth actually uses the terms "essentially equal to" / "approximately equal to". I actually quoted the boost page, which referred to Knuth's book. My proposal would be to use "is essentially equal to" (rename to function to areEssentiallyEqual()) and keep quoting Knuth. What do you think? I will also include a link to the boost page as this is the one I referred to initially.

>> Source/WTF/wtf/MathExtras.h:409
>> +// defines a "very close with tolerance e" relationship between u and v
> 
> You may also want to consider citing the boost.org web page, <http://www.boost.org/doc/libs/1_34_0/libs/test/doc/components/test_tools/floating_point_comparison.html>, in this comment.
> 
> Assuming you are referencing section 4.2.2 "Accuracy of Floating Point Arithmetic" of the The Art of Computer Programming then the MLA-citation would be of the form:
> 
> Knuth, D. E. "Accuracy of Floating Point Arithmetic." The Art of Computer Programming. 3rd ed. Vol. 2. Boston: Addison-Wesley, 1998. 229-45.

Yes, section 4.2.2 indeed.
Comment 7 Chris Dumez 2014-11-08 23:39:57 PST
Created attachment 241250 [details]
Patch
Comment 8 Chris Dumez 2014-11-08 23:41:13 PST
Thanks for the review Daniel. I have updated the patch accordingly I believe.
Comment 9 WebKit Commit Bot 2014-11-08 23:41:59 PST
Attachment 241250 [details] did not pass style-queue:


ERROR: Source/WebKit/mac/WebView/WebHTMLView.mm:2416:  An else statement can be removed when the prior "if" concludes with a return, break, continue or goto statement.  [readability/control_flow] [4]
Total errors found: 1 in 11 files


If any of these errors are false positives, please file a bug against check-webkit-style.
Comment 10 Darin Adler 2014-11-09 10:02:30 PST
Comment on attachment 241250 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=241250&action=review

This change is OK, but I am really concerned with the fragile way we wrote the code to compare double scale factors in WebKit, compensating for the fact that they are treated as floats inside WebCore.

> Source/WTF/wtf/MathExtras.h:399
> +    if (v < 1  && u > v * std::numeric_limits<T>::max())

Extra space before the "&&" on this line.

> Source/WebKit2/UIProcess/API/Cocoa/WKWebView.mm:833
> +static inline bool withinEpsilon(float a, float b)

This function, with its current name and function, is too subtle. The most important thing this function does it convert its arguments to floats, as the comment explains above; it is needed because WebCore stores these values as float, not double. Given that, I think it needs a better name. It’s not just a general purpose "within epsilon" function, but rather one that’s specifically about the "float" type. More specifically, if someone were to overload this to work for doubles as well as floats, or convert it back to a template, that would likely break this, since we’d use a double epsilon rather than a float one.

> Source/WebKit2/UIProcess/CoordinatedGraphics/PageViewportController.cpp:325
> +    bool currentlyScaledToFit = WTF::areEssentiallyEqual(m_pageScaleFactor, m_minimumScaleToFit, 0.0001f);

In both the old code and the new, I wonder where the magic number 0.0001f comes from.

> Source/WebKit2/WebProcess/WebPage/ios/WebPageIOS.mm:2217
> +    return WTF::areEssentiallyEqual(a, b);

We have the same problem here as in WKWebView.mm, but here we don’t even have the comment explaining why converting to float is important. It would be really easy to break this code by overloading or changing the types.
Comment 11 Daniel Bates 2014-11-09 13:24:04 PST
(In reply to comment #6)
> [...]
> This is on page 218 - 219. Knuth actually uses the terms "essentially equal
> to" / "approximately equal to". I actually quoted the boost page, which
> referred to Knuth's book. My proposal would be to use "is essentially equal
> to" (rename to function to areEssentiallyEqual()) and keep quoting Knuth.
> What do you think? 

Sounds reasonable.

> I will also include a link to the boost page as this is
> the one I referred to initially.
> 

Good.
Comment 12 Chris Dumez 2014-11-09 13:48:22 PST
Comment on attachment 241250 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=241250&action=review

>> Source/WebKit2/UIProcess/CoordinatedGraphics/PageViewportController.cpp:325
>> +    bool currentlyScaledToFit = WTF::areEssentiallyEqual(m_pageScaleFactor, m_minimumScaleToFit, 0.0001f);
> 
> In both the old code and the new, I wonder where the magic number 0.0001f comes from.

This apparently used to be 0.001f a very long time ago, when this code was Qt-specific. It was updated to 0.0001f in https://bugs.webkit.org/attachment.cgi?id=177492&action=review to "fix flakiness" in scale related API tests. It is very likely we can use here the same code as on Mac and iOS instead of using this arbitrary precision. However, I am not sure I should be the one making this change as I don't have an easy to test the change.
Comment 13 Chris Dumez 2014-11-09 13:54:33 PST
Created attachment 241258 [details]
Patch
Comment 14 WebKit Commit Bot 2014-11-09 13:55:47 PST
Attachment 241258 [details] did not pass style-queue:


ERROR: Source/WebKit/mac/WebView/WebHTMLView.mm:2416:  An else statement can be removed when the prior "if" concludes with a return, break, continue or goto statement.  [readability/control_flow] [4]
Total errors found: 1 in 11 files


If any of these errors are false positives, please file a bug against check-webkit-style.
Comment 15 Chris Dumez 2014-11-09 13:55:58 PST
Comment on attachment 241258 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=241258&action=review

> Source/WebKit2/UIProcess/CoordinatedGraphics/PageViewportController.cpp:325
> +    // FIXME: Why this arbitrary precision? We likely want to omit the third argument so that

Gyuyoung, do you think this is something you could look into in a follow-up as the EFL port is exercising this code path?
Comment 16 Chris Dumez 2014-11-09 15:36:56 PST
Created attachment 241263 [details]
Patch
Comment 17 WebKit Commit Bot 2014-11-09 15:39:09 PST
Attachment 241263 [details] did not pass style-queue:


ERROR: Source/WebKit/mac/WebView/WebHTMLView.mm:2416:  An else statement can be removed when the prior "if" concludes with a return, break, continue or goto statement.  [readability/control_flow] [4]
Total errors found: 1 in 13 files


If any of these errors are false positives, please file a bug against check-webkit-style.
Comment 18 WebKit Commit Bot 2014-11-09 16:22:00 PST
Comment on attachment 241263 [details]
Patch

Clearing flags on attachment: 241263

Committed r175796: <http://trac.webkit.org/changeset/175796>
Comment 19 WebKit Commit Bot 2014-11-09 16:22:06 PST
All reviewed patches have been landed.  Closing bug.
Comment 20 David Kilzer (:ddkilzer) 2014-11-09 18:47:38 PST
"Essentually" is misspelled--should be "Essentially".
Comment 21 Chris Dumez 2014-11-09 18:48:56 PST
(In reply to comment #20)
> "Essentually" is misspelled--should be "Essentially".

Hmm :) Thankfully it is only in the Changelogs.
Comment 22 Chris Dumez 2014-11-09 18:54:32 PST
(In reply to comment #21)
> (In reply to comment #20)
> > "Essentually" is misspelled--should be "Essentially".
> 
> Hmm :) Thankfully it is only in the Changelogs.

Not sure what's the policy in this case. Should I land a patch to fix only the Changelogs?
Comment 23 Darin Adler 2014-11-09 21:45:24 PST
I like the function name, areEssentiallyEqualAsFloat, that you chose for the float workaround function. Unfortunately, it looks like it was spelled incorrectly as areEssentiallEqualAsFloat in WebPageIOS.mm.
Comment 24 Chris Dumez 2014-11-09 21:49:57 PST
(In reply to comment #23)
> I like the function name, areEssentiallyEqualAsFloat, that you chose for the
> float workaround function. Unfortunately, it looks like it was spelled
> incorrectly as areEssentiallEqualAsFloat in WebPageIOS.mm.

Thanks for catching that and sorry about that. I fixed to typo in <http://trac.webkit.org/changeset/175797>.
Comment 25 Darin Adler 2014-11-09 21:51:45 PST
(In reply to comment #22)
> Should I land a patch to fix only the Changelogs?

No.