Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use fld in _colon method in range.jl, rather than floating point division #48654

Merged
merged 1 commit into from
Feb 14, 2023

Conversation

garrison
Copy link
Sponsor Member

@garrison garrison commented Feb 12, 2023

This replaces calls to floor(Integer, a / b) with fld(a, b) in _colon(), resulting in simpler and more efficient generated code.

The convert(Integer, ...) is necessary, otherwise the following test fails:

julia/test/ranges.jl

Lines 1524 to 1527 in d8c2250

# issue #20382
let r = @inferred((:)(big(1.0),big(2.0),big(5.0)))
@test eltype(r) == BigFloat
end

with

  LoadError: MethodError: no method matching StepRangeLen(::BigFloat, ::BigFloat, ::BigFloat)
  
  Closest candidates are:
    StepRangeLen(::R, ::S, ::Integer) where {R, S}
     @ Base range.jl:507
    StepRangeLen(::R, ::S, ::Integer, ::Integer) where {R, S}
     @ Base range.jl:507

I was surprised at first that cld(::BigFloat, ::BigFloat) returns a BigFloat rather than a BigInt, but on second thought, I believe the current behavior is indeed appropriate, as there is nothing to say that BigInt and BigFloat are set to the same precision this is consistent with cld(::Float64, ::Float64) returning a Float64 (see the cld docstring). Hence the convert call in this PR to ensure the returned value is still an Integer.

@oscardssmith
Copy link
Member

tagging @StefanKarpinski on these (also #48653) because although these changes look good, I want to make sure he wasn't doing something sneaky.

@oscardssmith oscardssmith added performance Must go faster domain:ranges Everything AbstractRange labels Feb 12, 2023
@jishnub
Copy link
Contributor

jishnub commented Feb 12, 2023

I was surprised at first that cld(::BigFloat, ::BigFloat) returns a BigFloat rather than a BigInt

Looks like cld propagates Inf and NaN without complaining. Shouldn't it require that the result is an integer?

julia> cld(Inf, 2.0)
NaN

julia> cld(2.0, 0.0)
NaN

@garrison
Copy link
Sponsor Member Author

garrison commented Feb 12, 2023

Looks like cld propagates Inf and NaN without complaining. Shouldn't it require that the result is an integer?

Sorry, I have revised my original comment a bit, as it was misleading. It looks like cld(::Float64, ::Float64) is indeed meant to return a Float64, so I believe the current behavior is appropriate with regard to Inf and NaN.

My real surprise, now that I better understand this, is that the BigFloat test is the only one that failed (at least within the ranges tests -- I didn't check any others) before I added convert(Integer, ...).

@KristofferC KristofferC merged commit ff6a3cf into JuliaLang:master Feb 14, 2023
@garrison garrison deleted the fld-range-colon branch February 14, 2023 19:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
domain:ranges Everything AbstractRange performance Must go faster
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants