I don't think this behavior could be considered desirable by anyone:
julia> fld1(-0.533669923120631, 3.430469)
-1.0
julia> fld1(prevfloat(-0.533669923120631), 3.430469)
0.0
julia> fld1(nextfloat(-0.533669923120631), 3.430469)
0.0
(confirmed on 1.12.5 and 1.14.0-DEV.2662)
it seems like the right thing to do here is to make fld1 an alias of cld, and deprecate its use. I don't know why we have a separate fld1 and cld anyways, since they are logically equivalent for integer inputs:
julia> @code_typed fld1(20,3)
CodeInfo(
1 ─ %1 = intrinsic Base.checked_sdiv_int(x, y)::Int64
│ %2 = intrinsic Base.xor_int(x, y)::Int64
│ %3 = intrinsic Base.slt_int(%2, 0)::Bool
│ %4 = intrinsic Base.not_int(%3)::Bool
│ %5 = intrinsic Base.mul_int(%1, y)::Int64
│ %6 = builtin (%5 === x)::Bool
│ %7 = intrinsic Base.not_int(%6)::Bool
│ %8 = intrinsic Base.and_int(%4, %7)::Bool
│ %9 = intrinsic Core.zext_int(Core.Int64, %8)::Int64
│ %10 = intrinsic Core.and_int(%9, 1)::Int64
│ %11 = intrinsic Base.add_int(%1, %10)::Int64
└── return %11
) => Int64
julia> @code_typed cld(20,3)
CodeInfo(
1 ─ %1 = intrinsic Base.checked_sdiv_int(a, b)::Int64
│ %2 = intrinsic Base.slt_int(0, a)::Bool
│ %3 = intrinsic Base.slt_int(0, b)::Bool
│ %4 = builtin (%2 === %3)::Bool
│ %5 = intrinsic Base.mul_int(%1, b)::Int64
│ %6 = builtin (%5 === a)::Bool
│ %7 = intrinsic Base.not_int(%6)::Bool
│ %8 = intrinsic Base.and_int(%4, %7)::Bool
│ %9 = intrinsic Core.zext_int(Core.Int64, %8)::Int64
│ %10 = intrinsic Core.and_int(%9, 1)::Int64
│ %11 = intrinsic Base.add_int(%1, %10)::Int64
└── return %11
) => Int64
((0<=a) == (0<=b) and (a⊻b) >= 0 are equivalent statements; and fld1 and cld are trivially equivalent when a or b is zero)
it would also be nice if we could make fldmod1 an alias for cldmod1 and deprecate the fldmod1 name as well.
admire the flickeryness:
julia> using GLMakie
julia> fig = Figure()
julia> ax = Axis(fig[1, 1], xticks = (1:4, ["div", "cld", "fld", "fld1"]), title = "op(a, b)")
Axis with 0 plots:
julia> sl = SliderGrid(fig[2, 1],
(range = [-logrange(100,.001,100); logrange(.001,100,100)], label = "a", format = "{:.15f}"),
(range = [-logrange(100,.001,100); logrange(.001,100,100)], label = "b", format = "{:.15f}")
)
SliderGrid()
julia> bars = lift([s.value for s in sl.sliders]...) do a, b
[div(a,b), cld(a,b), fld(a,b), fld1(a,b)]
end
Observable([1.0, 1.0, 1.0, 1.0])
julia> plt = barplot!(ax, bars)
BarPlot{Tuple{Vector{Point{2, Float64}}}}
julia> on(bars) do b
ylims!(ax, minimum(b)-1, maximum(b)+1)
end
ObserverFunction defined at REPL[73]:2 operating on Observable([1.0, 1.0, 1.0, 1.0])
julia> while events(fig).window_open[]
a = sl.sliders[1].selected_index[]
if a==200
a=0
b=sl.sliders[2].selected_index[]
if b==200 b=0 end
set_close_to!(sl.sliders[2], sl.sliders[2].range[][b+1])
end
set_close_to!(sl.sliders[1], sl.sliders[1].range[][a+1])
sleep(1/60)
end
I don't think this behavior could be considered desirable by anyone:
(confirmed on 1.12.5 and 1.14.0-DEV.2662)
it seems like the right thing to do here is to make
fld1an alias ofcld, and deprecate its use. I don't know why we have a separatefld1andcldanyways, since they are logically equivalent for integer inputs:(
(0<=a) == (0<=b)and(a⊻b) >= 0are equivalent statements; andfld1andcldare trivially equivalent when a or b is zero)it would also be nice if we could make
fldmod1an alias forcldmod1and deprecate thefldmod1name as well.admire the flickeryness: