# Correctness bugs

**URL:** <https://discourse.julialang.org/t/correctness-bugs/122855>\
**Category:** Offtopic\
**Tags:** gripes, griping\
**Created:** [November 20, 2024, 3:19pm UTC](https://discourse.julialang.org/t/correctness-bugs/122855 "2024-11-20T15:19:19Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![Anil\_Kumar1](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/anil_kumar1/32/212857_2.png) [@Anil\_Kumar1](https://discourse.julialang.org/u/Anil_Kumar1)\
**Post date:** [November 20, 2024, 3:19pm UTC](https://discourse.julialang.org/t/correctness-bugs/122855/1 "2024-11-20T15:19:19Z")

</div>

[https://yuri.is/not-julia/](https://yuri.is/not-julia/)

I saw this on Bluesky today.

" In my experience, Julia and its packages have the highest rate of serious correctness bugs of any programming system I’ve used, and I started programming with Visual Basic 6 in the mid-2000s.

It might be useful to give some concrete examples.

Here are some correctness issues I filed:

- [Sampling a probability density produces an incorrect result](https://github.com/JuliaStats/Distributions.jl/issues/1241)
- [Sampling an array can produce biased results](https://github.com/JuliaStats/StatsBase.jl/issues/642)
- [The product function can produce incorrect results for 8-bit, 16-bit, and 32-bit integers](https://github.com/JuliaLang/julia/issues/39183)
- [Fitting a histogram to a Float64 array can produce incorrect results](https://github.com/JuliaStats/StatsBase.jl/issues/616)
- [Base functions sum!, prod!, any!, and all! may silently return incorrect results](https://github.com/JuliaLang/julia/issues/39385)"

---

<div class="post-metadata">

**Author:** ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)\
**Post date:** [November 20, 2024, 3:29pm UTC](https://discourse.julialang.org/t/correctness-bugs/122855/2 "2024-11-20T15:29:57Z")

</div>

It seems all of them are closed (presumably fixed) except the last one. Good job Julia community!

---

<div class="post-metadata">

**Author:** ![barucden](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/barucden/32/26154_2.png) [@barucden](https://discourse.julialang.org/u/barucden)\
**Post date:** [November 20, 2024, 3:30pm UTC](https://discourse.julialang.org/t/correctness-bugs/122855/3 "2024-11-20T15:30:27Z")

</div>

> [@Discussion on "Why I no longer recommend Julia" by Yuri Vishnevsky](https://discourse.julialang.org/t/discussion-on-why-i-no-longer-recommend-julia-by-yuri-vishnevsky/81151):
>
> Hey folks! There was a pretty good critical article written about Julia recently called [“Why I no longer recommend Julia” by Yuri Vishnevsky](https://yuri.is/not-julia/) There is an ongoing discussion about the article that has largely been constructive on Slack. Hoping to capture some of these thoughts here to provide actionable points for the community. Feel free to comment or continue streams of thought here about the article and what actions could be done next. Thanks and remember: this is meant to be a cordial and…

Please, not again 😿

---

<div class="post-metadata">

**Author:** ![JuhaNuutila](https://avatars.discourse-cdn.com/v4/letter/j/f4b2a3/32.png) [@JuhaNuutila](https://discourse.julialang.org/u/JuhaNuutila)\
**Post date:** [November 20, 2024, 9:15pm UTC](https://discourse.julialang.org/t/correctness-bugs/122855/4 "2024-11-20T21:15:46Z")

</div>

It’s fascinating how people circulate the same posts and arguments for years.

Find any Linux-related discussion on the Internet and observe how many people are complaining about bugs or configuration problems that were fixed over 10 years ago. It only shows that they haven’t actually used the thing to see the progress.

---

<div class="post-metadata">

**Author:** ![greatpet](https://avatars.discourse-cdn.com/v4/letter/g/e495f1/32.png) [@greatpet](https://discourse.julialang.org/u/greatpet)\
**Post date:** [November 20, 2024, 10:22pm UTC](https://discourse.julialang.org/t/correctness-bugs/122855/5 "2024-11-20T22:22:49Z")

</div>

It has been discussed many times, though re-reading the blog reminds me that Elon Musk used to post more sensible stuff on Twitter.

---

<div class="post-metadata">

**Author:** ![tomaklutfu](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tomaklutfu/32/2411_2.png) [@tomaklutfu](https://discourse.julialang.org/u/tomaklutfu)\
**Post date:** [November 21, 2024, 10:36am UTC](https://discourse.julialang.org/t/correctness-bugs/122855/6 "2024-11-21T10:36:34Z")

</div>

I went ahead and looked at the blog post for opened issue links and vast majority of them finished/closed. A couple stays open pending some finish up work and a couple is pending for design decision(I think). A couple is real issue. Great work Julia community!

---

<div class="post-metadata">

**Author:** ![Benny](https://avatars.discourse-cdn.com/v4/letter/b/49beb7/32.png) [@Benny](https://discourse.julialang.org/u/Benny)\
**Post date:** [November 21, 2024, 1:22pm UTC](https://discourse.julialang.org/t/correctness-bugs/122855/7 "2024-11-21T13:22:18Z")

</div>

Let’s not be too hard on someone for missing an old discussion.  
Also put quotes in quote blocks (leading `>` for formatting)

> like this  
> and this

so people don’t mistake the blog’s text for your own. The " starting and ending a quote are easily missed, and the custom for quoting multiple paragraphs is to write a leading " for each paragraph.

---

<div class="post-metadata">

**Author:** ![Palli](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/palli/32/3380_2.png) [@Palli](https://discourse.julialang.org/u/Palli)\
**Post date:** [November 23, 2024, 5:38pm UTC](https://discourse.julialang.org/t/correctness-bugs/122855/8 "2024-11-23T17:38:38Z")

</div>

> [@kristoffer.carlsson](#):
>
> It seems all of them are closed (presumably fixed) except the last one. Good job Julia community!

Right (though that last one a bit of a tough one), also he reported more, e.g.:

> <https://github.com/JuliaLang/julia/issues/49450#issuecomment-1517581984>
>
> Julia has a \[\`div\`\](https://docs.julialang.org/en/v1/base/math/#Base.div) functi…on that is used to implement \[floor division\](https://docs.julialang.org/en/v1/base/math/#Base.fld) (\`fld\`) and \[ceil division\](https://docs.julialang.org/en/v1/base/math/#Base.cld) (\`cld\`). I think I’ve found a bug that causes all of these division functions to return incorrect results.
> 
> Floor division is documented to return the largest integer less than or equal to \`x / y\`. It should never return a number that is \*greater\* than \`x / y\`.
> 
> But it does:
> 
> \`\`\`julia
> julia\> 514 / Float16(0.75)
> Float16(685.5)
> 
> julia\> div(514, Float16(0.75)) # should round down, but rounds up instead
> Float16(686.0)
> 
> julia\> fld(514, Float16(0.75)) # likewise
> Float16(686.0)
> 
> julia\> fld(514, Float16(0.75)) ≤ 514 / Float16(0.75)
> false
> \`\`\`
> 
> Similarly, ceil division should never return a number that is \*smaller\* than regular division, but it does:
> 
> \`\`\`julia
> julia\> 515 / Float16(0.75)
> Float16(686.5)
> 
> julia\> cld(515, Float16(0.75)) # should round up, but rounds down instead
> Float16(686.0)
> 
> julia\> cld(515, Float16(0.75)) ≥ 515 / Float16(0.75)
> false
> \`\`\`
> 
> This behavior is not limited to 16-bit floats. Here’s a case where \`fld\` produces an incorrect result for \`Float32\` inputs:
> 
> \`\`\`julia
> julia\> 4\_194\_307 / Float32(0.75) # = 5592409.5
> 5.5924095f6
> 
> julia\> fld(4\_194\_307, Float32(0.75)) # = 5592410, incorrectly rounded up
> 5.59241f6
> 
> julia\> fld(4\_194\_307, Float32(0.75)) ≤ 4\_194\_307 / Float32(0.75)
> false
> \`\`\`
> 
> And here’s the same for \`cld\`:
> 
> \`\`\`julia
> julia\> 4\_194\_308 / Float32(0.75) # = 5592410.5
> 
> julia\> cld(4\_194\_308, Float32(0.75)) # = 5592410, incorrectly rounded down
> 5.59241f6
> 
> julia\> cld(4\_194\_308, Float32(0.75)) ≥ 4\_194\_308 / Float32(0.75)
> false
> \`\`\`
> 
> The equivalent operations in Python produce the correct results:
> 
> \`\`\`python
> \# For 16-bit floats:
> \>\>\> np.float16(514) / np.float16(0.75) # regular division
> 685.5
> \>\>\> np.float16(514) // np.float16(0.75) # floor division
> 685.0
> 
> \# For 32-bit floats:
> \>\>\> np.float32(4\_194\_307) / np.float32(0.75) # regular division
> 5592409.5
> \>\>\> np.float32(4\_194\_307) // np.float32(0.75) # floor division
> 5592409.0
> \`\`\`
> 
> Examples of this incorrect behavior are not hard to find – for most floats, you can find a divisor that will make either \`fld\` or \`cld\` return the wrong answer.
> 
> Here are some examples for \`Float16\` where either \`fld\` or \`cld\` is incorrect:
> 
> \- \`cld(1, Float16(0.000999)) \< 1 / Float16(0.000999)\`
> \- \`cld(2, Float16(0.001999)) \< 2 / Float16(0.001999)\`
> \- \`cld(3, Float16(0.002934)) \< 3 / Float16(0.002934)\`
> \- \`cld(4, Float16(0.003998)) \< 4 / Float16(0.003998)\`
> \- \`fld(5, Float16(0.004925)) \> 5 / Float16(0.004925)\`
> 
> And here are some for \`Float32\`:
> 
> \- \`fld(5, Float32(6.556511e-7)) \> 5 / Float32(6.556511e-7)\`
> \- \`fld(10, Float32(1.3113022e-6)) \> 10 / Float32(1.3113022e-6)\`
> \- \`fld(11, Float32(1.4305115e-6)) \> 11 / Float32(1.4305115e-6)\`
> \- \`cld(16, Float32(2.8014183e-6)) \< 16 / Float32(2.8014183e-6)\`
> \- \`cld(17, Float32(2.2053719e-6)) \< 17 / Float32(2.2053719e-6)\`
> 
> For simplicity I’ve presented examples where the first argument is an integer; this bug also occurs for non-integral inputs.
> 
> A divisor producing the wrong result can be found for over 51% of all possible 16-bit floats. I have not evaluated how widespread this is for \`Float32\`, but the results above suggest that it is similarly easy to find failures there too.
> 
> I’ve tracked the invocations down to \[this definition\](https://github.com/JuliaLang/julia/blob/72aec423c2ab9f80c249d63fdd68b35833cfd7ed/base/div.jl#L370) of \`div\`, which has existed at least as far back as \[Julia 1.6\](https://github.com/JuliaLang/julia/blob/f9720dc2ebd6cd9e3086365f281e62506444ef37/base/div.jl#L279):
> 
> \`\`\`julia
> div(x::T, y::T, r::RoundingMode) where {T\<:AbstractFloat} =
> convert(T, round((x - rem(x, y, r)) / y))
> \`\`\`

Most recent update in August.

> [@Checked vs unchecked, e.g. (floored) divison](https://discourse.julialang.org/t/checked-vs-unchecked-e-g-floored-divison/122899/2):
>
> The advantage of mapping ÷ to fld is that then % needs to be mod, which is not so uncommon to use with a negative first argument. Both rem and mod give you a useful cyclic behavior for positive numbers. If you go past zero mod keeps being cyclic, whereas rem makes a sign shift and goes over to a cycle with negative numbers. I’m sure there’s some context where rem is useful with negative first argument, but I’m yet to find it. In my experience mod is always the operator you want and if you carel…

> I’m not generally enthusiastic about Python but this is something they got right, and Julia (and many other languages) sadly didn’t.

Julia does (or well tries) to do same as C and C++. It’s not clear to me Python’s way is better, either definition works, assuming people know which is used.

Also a (minor? i.e. not correctness, only stackoverflow) bug was fixed in OrderedCollections.jl, and the PR fix, approved in Feb 2021, got forgotten for 4 years, and I reported it some months before that with [Bug in OrderedDict (unlike in LittleDict, and Dict) · Issue #65 · JuliaCollections/OrderedCollections.jl · GitHub](https://github.com/JuliaCollections/OrderedCollections.jl/issues/65)

---

<div class="post-metadata">

**Author:** ![StefanKarpinski](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stefankarpinski/32/24_2.png) [@StefanKarpinski](https://discourse.julialang.org/u/StefanKarpinski)\
**Post date:** [November 29, 2024, 2:34am UTC](https://discourse.julialang.org/t/correctness-bugs/122855/9 "2024-11-29T02:34:21Z")

</div>

Most of them were already fixed when the post was published.
