mirror of
https://github.com/wader/fq.git
synced 2024-10-27 04:09:37 +03:00
bits: Add from_f32le, to_f32le, ...
TODO: - show somehow generalize to/from encodings? - move code to somwewhere else?
This commit is contained in:
parent
496849daa5
commit
e9226226d3
@ -2,14 +2,21 @@ package bits
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"embed"
|
"embed"
|
||||||
|
"encoding/binary"
|
||||||
|
"fmt"
|
||||||
|
"math"
|
||||||
|
|
||||||
"github.com/wader/fq/format"
|
"github.com/wader/fq/format"
|
||||||
|
"github.com/wader/fq/internal/gojqx"
|
||||||
|
"github.com/wader/fq/internal/mathx"
|
||||||
|
"github.com/wader/fq/pkg/bitio"
|
||||||
"github.com/wader/fq/pkg/decode"
|
"github.com/wader/fq/pkg/decode"
|
||||||
"github.com/wader/fq/pkg/interp"
|
"github.com/wader/fq/pkg/interp"
|
||||||
"github.com/wader/fq/pkg/scalar"
|
"github.com/wader/fq/pkg/scalar"
|
||||||
)
|
)
|
||||||
|
|
||||||
//go:embed bits.md
|
//go:embed bits.md
|
||||||
|
//go:embed bits.jq
|
||||||
//go:embed bytes.md
|
//go:embed bytes.md
|
||||||
var bitsFS embed.FS
|
var bitsFS embed.FS
|
||||||
|
|
||||||
@ -39,5 +46,74 @@ func init() {
|
|||||||
DecodeFn: decodeBits(8),
|
DecodeFn: decodeBits(8),
|
||||||
SkipDecodeFunction: true, // skip add bytes and frombytes function
|
SkipDecodeFunction: true, // skip add bytes and frombytes function
|
||||||
})
|
})
|
||||||
|
interp.RegisterFunc2("_from_float", func(_ *interp.Interp, c any, nBits int, isLE bool) any {
|
||||||
|
switch nBits {
|
||||||
|
case 16, 32, 64:
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("unsupported bit size %d, must be 16, 32 or 64", nBits)
|
||||||
|
}
|
||||||
|
|
||||||
|
br, err := interp.ToBitReader(c)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
var b [8]byte
|
||||||
|
bs := b[:][0 : nBits/8]
|
||||||
|
_, err = br.ReadBits(bs[:], int64(nBits))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if isLE {
|
||||||
|
decode.ReverseBytes(bs[:])
|
||||||
|
}
|
||||||
|
|
||||||
|
switch nBits {
|
||||||
|
case 64:
|
||||||
|
return math.Float64frombits(binary.BigEndian.Uint64(bs[:]))
|
||||||
|
case 32:
|
||||||
|
return float64(math.Float32frombits(binary.BigEndian.Uint32(bs[:])))
|
||||||
|
case 16:
|
||||||
|
return float64(mathx.Float16(binary.BigEndian.Uint16(bs[:])).Float32())
|
||||||
|
default:
|
||||||
|
panic("unreachable")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
interp.RegisterFunc2("_to_float", func(_ *interp.Interp, c any, nBits int, isLE bool) any {
|
||||||
|
switch nBits {
|
||||||
|
case 16, 32, 64:
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("unsupported bit size %d, must be 16, 32 or 64", nBits)
|
||||||
|
}
|
||||||
|
|
||||||
|
v, ok := gojqx.Cast[float64](c)
|
||||||
|
if !ok {
|
||||||
|
return gojqx.FuncTypeError{Name: "_to_float", V: v}
|
||||||
|
}
|
||||||
|
|
||||||
|
var b [8]byte
|
||||||
|
bs := b[:][0 : nBits/8]
|
||||||
|
switch nBits {
|
||||||
|
case 64:
|
||||||
|
binary.BigEndian.PutUint64(bs, math.Float64bits(v))
|
||||||
|
case 32:
|
||||||
|
binary.BigEndian.PutUint32(bs, math.Float32bits(float32(v)))
|
||||||
|
case 16:
|
||||||
|
binary.BigEndian.PutUint16(bs, uint16(mathx.NewFloat16(float32(v))))
|
||||||
|
default:
|
||||||
|
panic("unreachable")
|
||||||
|
}
|
||||||
|
if isLE {
|
||||||
|
decode.ReverseBytes(bs[:])
|
||||||
|
}
|
||||||
|
|
||||||
|
br, err := interp.NewBinaryFromBitReader(bitio.NewBitReader(bs, -1), 8, 0)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return br
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
interp.RegisterFS(bitsFS)
|
interp.RegisterFS(bitsFS)
|
||||||
}
|
}
|
||||||
|
12
format/bits/bits.jq
Normal file
12
format/bits/bits.jq
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
def from_f16be: _from_float(16; false);
|
||||||
|
def from_f32be: _from_float(32; false);
|
||||||
|
def from_f64be: _from_float(64; false);
|
||||||
|
def from_f16le: _from_float(16; true);
|
||||||
|
def from_f32le: _from_float(32; true);
|
||||||
|
def from_f64le: _from_float(64; true);
|
||||||
|
def to_f16le: _to_float(16; true);
|
||||||
|
def to_f32le: _to_float(32; true);
|
||||||
|
def to_f64le: _to_float(64; true);
|
||||||
|
def to_f16be: _to_float(16; false);
|
||||||
|
def to_f32be: _to_float(32; false);
|
||||||
|
def to_f64be: _to_float(64; false);
|
Loading…
Reference in New Issue
Block a user