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 (
|
||||
"embed"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"math"
|
||||
|
||||
"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/interp"
|
||||
"github.com/wader/fq/pkg/scalar"
|
||||
)
|
||||
|
||||
//go:embed bits.md
|
||||
//go:embed bits.jq
|
||||
//go:embed bytes.md
|
||||
var bitsFS embed.FS
|
||||
|
||||
@ -39,5 +46,74 @@ func init() {
|
||||
DecodeFn: decodeBits(8),
|
||||
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)
|
||||
}
|
||||
|
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