Skip to content

[RFC/Coffee Break] What about a new type NormedFloat? #147

Closed
@kimikage

Description

@kimikage

⚠️CAUTION:warning:: This is not a practical "request" or "proposal". Please read the conversation in PR #143 first.

I'm sure Normed{<:Signed} solves the N0f8 "overflow" problem, but I doubt that it is the best solution. So, I proposed a new strange type NormedFloat as a spoiling candidate or a touchstone.

NormedFloat is a kind of joke. So, don't think this too seriously. ☕

However, I think that the concepts and techniques related to NormedFloat might be helpful for other developments.

NormedFloat can be defined as:

using FixedPointNumbers

struct DummyInt{T} <: Integer
    i::T
end

struct NormedFloat{T<:AbstractFloat,f} <: FixedPoint{DummyInt{T},f}
    i::T
    NormedFloat{T,f}(i::AbstractFloat, _) where {T, f} = new{T, f}(i)
end

Base.reinterpret(::Type{NormedFloat{T,f}}, x::T) where {T, f} = NormedFloat{T,f}(x, 0)

const NF16f8 = NormedFloat{Float16,8};
const NF32f8 = NormedFloat{Float32,8};
const NF64f8 = NormedFloat{Float64,8};

<: FixedPoint{DummyInt{T},f} is just a workaround to use ColorVectorSpace.jl without modifications. As the name suggests, NormedFloat is not a FixedPoint numbers.

And, the signed Normed can be defined as:

struct SignedNormed{T<:Signed, f} <: FixedPoint{T, f}
    i::T
    SignedNormed{T,f}(i::Signed, _) where {T, f} = new{T, f}(i) 
end

Base.reinterpret(::Type{SignedNormed{T,f}}, x::T) where {T, f} = SignedNormed{T,f}(x, 0)

const S7f8  = SignedNormed{Int16,8};
const S23f8 = SignedNormed{Int32,8};
const S55f8 = SignedNormed{Int64,8};

I don't use Normed{<:Signed} here to make it easier to experiment on local REPL. If you already have Normed{<:Signed}, you can use it.

Just for display (not optimized):

FixedPointNumbers.typechar(::Type{<:NormedFloat}) = 'X'
FixedPointNumbers.signbits(::Type{<:NormedFloat}) = 1

Base.Float32(x::NormedFloat{T, 8}) where {T} = Float32(x.i) / 255.0f0
Base.Float64(x::NormedFloat{T, 8}) where {T} = Float64(x.i) / 255.0

FixedPointNumbers.typechar(::Type{<:SignedNormed}) = 'S'
FixedPointNumbers.signbits(::Type{<:SignedNormed}) = 1

Base.Float32(x::SignedNormed{T, 8}) where {T} = x.i / 255.0f0
Base.Float64(x::SignedNormed{T, 8}) where {T} = x.i / 255.0

Now, the following are the examples of numbers:

julia> reinterpret.(NF16f8, Float16[255, 1, 0, -1, -255])
5-element Array{X7f8,1} with eltype NormedFloat{Float16,8}:
  1.0X7f8
  0.004X7f8
  0.0X7f8
 -0.004X7f8
 -1.0X7f8

julia> reinterpret.(S7f8, Int16[255, 1, 0, -1, -255])
5-element Array{S7f8,1} with eltype SignedNormed{Int16,8}:
  1.0S7f8
  0.004S7f8
  0.0S7f8
 -0.004S7f8
 -1.0S7f8

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions