frontpage.
newsnewestaskshowjobs

Made with ♥ by @iamnishanth

Open Source @Github

fp.

Open in hackernews

It's OK to compare floating-points for equality

https://lisyarus.github.io/blog/posts/its-ok-to-compare-floating-points-for-equality.html
29•coinfused•3d ago

Comments

mizmar•3d ago
There is another way to compare floats for rough equality that I haven't seen much explored anywhere: bit-cast to integer, strip few least significant bits and then compare for equality. This is agnostic to magnitude, unlike epsilon which has to be tuned for range of values you expect to get a meaningful result.
twic•1h ago
This doesn't work. For any number of significant bits, there are pairs of numbers one machine epsilon apart which will truncate to different values.
andyjohnson0•1h ago
> strip few least significant bits

I'm unconvinced. Doesnt this just replace the need to choose a suitable epsilon with the need to choose the right number of bits to strip? With the latter affording much fewer choices for degree of "roughness" than does the former.

SideQuark•58m ago
Completely worked out at least 20 years ago: https://www.lomont.org/papers/2005/CompareFloat.pdf
fn-mote•10m ago
Note for the skeptic: this cites Knuth, Volume II, writes out the IEEE edge cases, and optimizes.
StilesCrisis•24m ago
Rather than stripping bits, you can just compare if the bit-casted numbers are less than N apart (choose an appropriate N that works for your data; a good starting point is 4).

This breaks down across the positive/negative boundary, but honestly, that's probably a good property. -0.00001 is not all that similar to +0.00001 despite being close on the number line.

It also requires that the inputs are finite (no INF/NAN), unless you are okay saying that FLT_MAX is roughly equal to infinity.

4pkjai•1h ago
I do this to see if text in a PDF is exactly where it is in some other PDF. For my use case it works pretty well.
jph•53m ago
I have this floating-point problem at scale and will donate $100 to the author, or to anyone here, who can improve my code the most.

The Rust code in the assert_f64_eq macro is:

    if (a >= b && a - b < f64::EPSILON) || (a <= b && b - a < f64::EPSILON)
I'm the author of the Rust assertables crate. It provides floating-point assert macros much as described in the article.

https://github.com/SixArm/assertables-rust-crate/blob/main/s...

If there's a way to make it more precise and/or specific and/or faster, or create similar macros with better functionality and/or correctness, that's great.

See the same directory for corresponding assert_* macros for less than, greater than, etc.

lukax•43m ago
You generally want both relative and absolute tolerances. Relative handles scale, absolute handles values near zero (raw EPSILON isn’t a universal threshold per IEEE 754).

The usual pattern is abs(a - b) <= max(rel_tol * max(abs(a), abs(b)), abs_tol) to avoid both large-value and near-zero pitfalls.

lukax•36m ago
See the implementation of Python's math.isclose

https://github.com/python/cpython/blob/d61fcf834d197f0113a6a...

pclmulqdq•41m ago
Your assertion code here doesn't make a ton of sense. The epsilon of choice here is the distance between 1 and the next number up, and it's completely separated from the scale of the numbers in question. 1e-50 will compare equal to 2e-50, for example.

I would suggest that "equals" actually is for "exactly equals" as in (a == b). In many pieces of floating point code this is the correct thing to test. Then also add a function for "within range of" so your users can specify an epsilon of interest, using the formula (abs(a - b) < eps). You may also want to support multidimensional quantities by allowing the user to specify a distance metric. You probably also want a relative version of the comparison in addition to an absolute version.

Auto-computing epsilons for an equality check is really hard and depends on the usage, as well as the numerics of the code that is upstream and downstream of the comparison. I don't see how you would do it in an assertion library.

lifthrasiir•36m ago
Hyb error [1] might be what you want.

[1] https://arxiv.org/html/2403.07492v2

thomasmg•29m ago
Well it depends on the use case, but do you consider NaN to be equal to NaN? For an assert macro, I would expect so. Also, your code works differently for very large and very small numbers, eg. 1.0000001, 1.0000002 vs 1e-100, 1.0000002e-100.

For my own soft-floating point math library, I expect the value is off by a some percentage, not just off by epsilon. And so I have my own almostSame method [1] which accounts for that and is quite a bit more complex. Actually multiple such methods. But well, that's just my use own use case.

[1] https://github.com/thomasmueller/bau-lang/blob/main/src/test...

hmry•24m ago
Is there any constant more misused in compsci than ieee epsilon? :)

It's defined as the difference between 1.0 and the smallest number larger than 1.0. More usefully, it's the spacing between adjacent representable float numbers in the range 1.0 to 2.0.

Because floats get less precise at every integer power of two, it's impossible for two numbers greater than or equal to 2.0 to be epsilon apart. The spacing between 2.0 and the next larger number is 2*epsilon.

That means `abs(a - b) <= epsilon` is equivalent to `a == b` for any a or b greater than or equal to 2.0. And if you use `<` then the limit will be 1.0 instead.

Epsilon is the wrong tool for the job in 99.9% of cases.

fouronnes3•12m ago
You should use two tolerances: absolute and relative. See for example numpy.allclose()

https://numpy.org/doc/stable/reference/generated/numpy.allcl...

judofyr•1m ago
Ignoring the misuse of epsilon, I'd also say that you'd be helping your users more by not providing a general `assert_f64_eq` macro, but rather force the user to decide the error model. Add a required "precision" parameter as an enum with different modes:

    // Precise matching:
    assert_f64_eq!(a, 0.1, Steps(2))
    // same as: assert!(a == 0.1.next_down().next_down())

    // Number of digits (after period) that are matching:
    assert_f64_eq!(a, 0.1, Digits(5))

    // Relative error:
    assert_f64_eq!(a, 0.1, Rel(0.5))
AshamedCaptain•40m ago
One of the goals of comparing floating points with an epsilon is precisely so that you can apply these types of accuracy increasing (or decreasing) changes to the operations, and still get similar results.

Anything else is basically a nightmare to however has to maintain the code in the future.

Also, good luck with e.g. checking if points are aligned to a grid or the like without introducing a concept of epsilon _somewhere_.

demorro•34m ago
I guess I'm confused. I thought epsilon was the smallest possible value to account for accuracy drift across the range of a floating point representation, not just "1e-4".

Done some reading. Thanks to the article to waking me up to this fact at least. I didn't realize that the epsilon provided by languages tends to be the one that only works around 1.0, and if you want to use episilons globally (which the article would say is generally a bad idea) you need to be more dynamic as your ranges, and potential errors, increase.

rpdillon•24m ago
Yeah, I'm not sure how widespread the knowledge is that floating point trades precision for magnitude. Its obvious if you know the implementation, but I'm not sure most folks do.

Category Theory Illustrated – Orders

https://abuseofnotation.github.io/category-theory-illustrated/04_order/
114•boris_m•5h ago•32 comments

Michael Rabin Has Died

https://en.wikipedia.org/wiki/Michael_O._Rabin
137•tkhattra•2d ago•8 comments

Amiga Graphics

https://amiga.lychesis.net/
122•sph•5h ago•13 comments

Claude Design

https://www.anthropic.com/news/claude-design-anthropic-labs
1080•meetpateltech•21h ago•707 comments

It's OK to compare floating-points for equality

https://lisyarus.github.io/blog/posts/its-ok-to-compare-floating-points-for-equality.html
29•coinfused•3d ago•19 comments

Show HN: I made a calculator that works over disjoint sets of intervals

https://victorpoughon.github.io/interval-calculator/
191•fouronnes3•10h ago•37 comments

Measuring Claude 4.7's tokenizer costs

https://www.claudecodecamp.com/p/i-measured-claude-4-7-s-new-tokenizer-here-s-what-it-costs-you
624•aray07•20h ago•442 comments

Towards trust in Emacs

https://eshelyaron.com/posts/2026-04-15-towards-trust-in-emacs.html
132•eshelyaron•2d ago•18 comments

All 12 moonwalkers had "lunar hay fever" from dust smelling like gunpowder (2018)

https://www.esa.int/Science_Exploration/Human_and_Robotic_Exploration/The_toxic_side_of_the_Moon
354•cybermango•17h ago•204 comments

Spending 3 months coding by hand

https://miguelconner.substack.com/p/im-coding-by-hand
232•evakhoury•19h ago•238 comments

Rewriting Every Syscall in a Linux Binary at Load Time

https://amitlimaye1.substack.com/p/rewriting-every-syscall-in-a-linux
59•riteshnoronha16•4d ago•23 comments

It is incorrect to "normalize" // in HTTP URL paths

https://runxiyu.org/comp/doubleslash/
46•pabs3•6h ago•35 comments

Are the costs of AI agents also rising exponentially? (2025)

https://www.tobyord.com/writing/hourly-costs-for-ai-agents
229•louiereederson•2d ago•70 comments

Brunost: The Nynorsk Programming Language

https://lindbakk.com/blog/introducing-brunost
84•atomfinger•4d ago•32 comments

A simplified model of Fil-C

https://www.corsix.org/content/simplified-model-of-fil-c
179•aw1621107•14h ago•99 comments

The simple geometry behind any road

https://sandboxspirit.com/blog/simple-geometry-of-roads/
54•azhenley•2d ago•7 comments

Show HN: Smol machines – subsecond coldstart, portable virtual machines

https://github.com/smol-machines/smolvm
348•binsquare•18h ago•116 comments

Slop Cop

https://awnist.com/slop-cop
202•ericHosick•20h ago•119 comments

"cat readme.txt" is not safe if you use iTerm2

https://blog.calif.io/p/mad-bugs-even-cat-readmetxt-is-not
209•arkadiyt•17h ago•123 comments

Hyperscalers have already outspent most famous US megaprojects

https://twitter.com/finmoorhouse/status/2044933442236776794
210•nowflux•19h ago•172 comments

Show HN: PanicLock – Close your MacBook lid disable TouchID –> password unlock

https://github.com/paniclock/paniclock/
206•seanieb•19h ago•95 comments

Loonies for Loongsons

https://www.leadedsolder.com/2026/04/14/loongson-ls3a5000-debian-linux.html
13•zdw•3d ago•2 comments

Middle schooler finds coin from Troy in Berlin

https://www.thehistoryblog.com/archives/75848
242•speckx•21h ago•112 comments

NASA Force

https://nasaforce.gov/
281•LorenDB•20h ago•277 comments

Claude Code Opus 4.7 keeps checking on malware

19•decide1000•1h ago•12 comments

Landmark ancient-genome study shows surprise acceleration of human evolution

https://www.nature.com/articles/d41586-026-01204-5
87•unsuspecting•13h ago•83 comments

NIST gives up enriching most CVEs

https://risky.biz/risky-bulletin-nist-gives-up-enriching-most-cves/
208•mooreds•20h ago•51 comments

Show HN: Sfsym – Export Apple SF Symbols as Vector SVG/PDF/PNG

https://github.com/yapstudios/sfsym
13•olliewagner•8h ago•1 comments

Introducing: ShaderPad

https://rileyjshaw.com/blog/introducing-shaderpad/
103•evakhoury•2d ago•18 comments

Casus Belli Engineering

https://marcosmagueta.com/blog/casus-belli-engineering/
48•b-man•10h ago•14 comments