[Vaporware/RFC] Width-Qualified FixedPointNumbers

First of all, I apologize to you all for the clickbait.

FixedPointNumbers.jl v0.8.5 is being prepared for release. Edit: CANCELED
That is 77% of what I want to announce.

Let’s talk about the other 33%.

WidthQualifiedFixedPointNumbers.jl is a package that does not actually work. Also, I do not plan to develop it for the time being.
This is one of a series of things I was writing around 2021 (cf. [PRE/RFC/ANN] Color-related packages (YUVColorTypes, CMYKColorTypes, ColorProfiles, HDRColorTypes, HDRImages)).

Currently, FixedPointNumbers.Normed s (e.g., N0f8), the “variant”, are widely used to represent colors such as RGB.
On the other hand, FixedPointNumbers.Fixed, which is fixed-point numbers in the typical sense, is also of engineering importance.
However, Fixed is ”actually” limited to bit widths of 8, 16, 32, 64, and 128.
In DSP or FPGA development, it is desirable to be able to statically specify an arbitrary bit width.

I have confirmed that Fixed almost works with Int24 from BitIntegers.jl by customizing FixedPointNumbers.bitwidth.
However, the current Julia does not support to create a type like Int7.

An approach to the solution would be to have the bit width information on the FixedPoint type side, rather than on the raw integer type.
Since the proposed form is not compatible with the existing Fixed, I thought of having a separate package to keep the hygiene of FixedPointNumbers.jl, in 2021.
That is the WidthQualifiedFixedPointNumbers.jl.
The name comes from the intention that it should be separate from the existing FixedPointNumbers.jl and the intention to include the letter “Q”. In fact, the name was too long and Discourse rejected the topic title.

The following is an example of the behavior that illustrates the design concept.

julia> using WidthQualifiedFixedPointNumbers

julia> sq7 = SQFixed8{3,7}(1.25) # a signed fixed-point number scaled by 2^3 with bit width of 7
SQFixed8{3,7}(1.25)

julia> bitstring(sq7) # 1.25 (dec) = 1.010 (bin)
"0001010"

julia> sq7 isa FixedPoint{Int8,3} # The raw type is `Int8`.
true

julia> uq11 = UQFixed{-1,11}(6) # an unsigned fixed-point number scaled by 2^(-1) with bit width 11
UQFixed{-1,11}(6.0)

julia> bitstring(uq11) # 6 = 3 / 2^(-1)
"00000000011"

julia> uq11 isa FixedPoint{UInt,-1} # The raw type is `UInt`.
true

julia> sq16 = SQFixed16{8}(127.0) # You may omit specifying the bit width.
SQFixed16{8}(127.0)

julia> bitstring(sq16) # The bit width is 16 as the raw type is `Int16`.
"0111111100000000"

Perhaps with the so-called C23 being published in this year, we may be able to expect progress on arbitrary bitwidth integer support for julia.

Julia users tend to be meticulous people, so you probably don’t have my story in your head because you’re worried about the -10%.
That is the amount absorbed by the :grapes:channel, so the order of the world is maintained.
If you are interested in the overflow you should become a maintainer of FixedPointNumbers.jl!

1 Like

You could certainly define an 8-bit type whose arithmetic emulates 7-bit integers. And a specialized array type implementing packed storage of odd-size integers.

I did not say it was the only approach. We could certainly define an 8-bit type whose arithmetic emulates 7-bit fixed-point numbers.

Your point is technically correct, but there is an important oversight.
I do not want to officially support types like Int7 in the FixedPointNumbers.jl.
Such a type may work on its own, but it becomes difficult to be consistent with promotion rules, etc.

This is off-topic (i.e., a Normed topic, not a Fixed topic), but 16-bit RGB values with 5-bit R, 6-bit G, and 5-bit B components are used in the real world.
I do not want to officially support types like RGB565 in the ColorTypes.jl.