question in title; fld1 seems much more similar to cld than fld:
julia> findall(!iszero, [fld1(a,b)-cld(a,b) for a=-10000:.1:10000, b=[-100:-1; 1:100]]) |> length
0
julia> findall(!iszero, [fld1(a,b)-fld(a,b) for a=-10000:.1:10000, b=[-100:-1; 1:100]]) |> length
39792664
it only seems to match fld when you’re specifically looking for floating pointy weirdness:
julia> fld1(3, 0.3)
10.0
julia> cld(3, 0.3)
11.0
julia> fld(3, 0.3)
10.0
actually, the code for integers appears to be identical, since (0<a) == (0<b) is the same as (a⊻b) >= 0 for non-zero a & b:
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
it seems like it would make more sense to call something that’s pretty much cld as cld1, not fld1. is there some theory reason it’s called fld1?