36 std::memcpy(&
b, &
x, 4);
37 const uint32_t sign = (
b >> 16) & 0x8000u;
38 const int32_t e = int32_t((
b >> 23) & 0xFFu) - 127 + 15;
39 uint32_t
m =
b & 0x7FFFFFu;
40 if (e >= 0x1F)
return uint16_t(sign | 0x7C00u);
42 if (e < -10)
return uint16_t(sign);
44 const uint32_t shift = uint32_t(14 - e);
45 uint32_t half =
m >> shift;
46 const uint32_t rem =
m & ((1u << shift) - 1u);
47 if (rem > (1u << (shift - 1)) || (rem == (1u << (shift - 1)) && (half & 1u))) ++half;
48 return uint16_t(sign | half);
50 uint32_t half = (uint32_t(e) << 10) | (
m >> 13);
51 const uint32_t rem =
m & 0x1FFFu;
52 if (rem > 0x1000u || (rem == 0x1000u && (half & 1u))) ++half;
53 return uint16_t(sign | half);
110inline uint32_t
floatToEfm(
float x,
int expBits,
int manBits,
int bias) {
115 static std::vector<EfmEntry> *cache =
nullptr;
116 static int cacheExp = 0, cacheMan = 0, cacheBias = 0;
117 if (!cache || cacheExp != expBits || cacheMan != manBits || cacheBias != bias) {
119 cache =
new std::vector<EfmEntry>();
120 const int expCount = 1 << expBits;
121 const int manCount = 1 << manBits;
122 for (uint32_t e = 0; e < uint32_t(expCount); ++e) {
123 for (uint32_t
m = 0;
m < uint32_t(manCount); ++
m) {
125 ? std::ldexp(
float(
m), 1 - bias - manBits)
126 : std::ldexp(1.0f +
float(
m) /
float(manCount),
int(e) - bias);
127 cache->push_back({
v, (e << manBits) |
m});
130 std::sort(cache->begin(), cache->end(),
131 [](
const EfmEntry &
a,
const EfmEntry &
b) { return a.value < b.value; });
136 if (std::isnan(
x) || std::isinf(
x)) {
137 const uint32_t maxExp = (1u << expBits) - 2u;
138 const uint32_t maxBits = (maxExp << manBits) | ((1u << manBits) - 1u);
139 const uint32_t signBit = 1u << (expBits + manBits);
140 return x < 0 ? (signBit | maxBits) : maxBits;
142 const float ax = std::fabs(
x);
143 size_t lo = 0, hi = cache->size();
144 while (lo + 1 < hi) {
145 const size_t mid = (lo + hi) / 2;
146 if ((*cache)[mid].value <= ax) lo = mid;
150 if (lo + 1 < cache->size() &&
151 std::fabs((*cache)[lo + 1].
value - ax) < std::fabs((*cache)[lo].
value - ax))
153 const uint32_t bits = (*cache)[best].bits;
154 const uint32_t signBit = 1u << (expBits + manBits);
155 return x < 0 ? (signBit | bits) : bits;
231 const int groups = (count +
p.group - 1) /
p.group;
232 p.scales.resize(
static_cast<size_t>(groups));
233 for (
int g = 0; g < groups; ++g) {
235 const int begin = g *
p.group;
236 const int end = std::min(count, begin +
p.group);
237 for (
int i = begin; i < end; ++i) maxAbs = std::max(maxAbs, std::fabs(src[static_cast<size_t>(i)]));
238 float scale = maxAbs / float(maxQ);
240 p.scales[
static_cast<size_t>(g)] =
scale;
241 for (
int i = begin; i < end; ++i) {
242 const float norm = src[
static_cast<size_t>(i)] /
scale;
249 uint8_t &
byte =
p.bytes[
static_cast<size_t>(i) / 2];
250 if (i & 1)
byte = uint8_t((
byte & 0x0Fu) | uint8_t(nib << 4));
251 else byte = uint8_t((
byte & 0xF0u) | nib);
254 int qv = int(std::floor(norm + 0.5f));
255 const int qBound = int(maxQ);
256 qv = std::max(-qBound - 1, std::min(qBound, qv));
258 p.bytes[
static_cast<size_t>(i)] = uint8_t(int8_t(qv));
260 const int nib = qv & 0xFu;
261 uint8_t &
byte =
p.bytes[
static_cast<size_t>(i) / 2];
262 if (i & 1)
byte = uint8_t((
byte & 0x0Fu) | uint8_t(nib << 4));
263 else byte = uint8_t((
byte & 0xF0u) | uint8_t(nib));
269 for (
int i = 0; i < count; ++i) {
270 const float v = src[
static_cast<size_t>(i)];
274 std::memcpy(
p.bytes.data() +
size_t(i) * 2, &
h, 2);
280 uint8_t &
byte =
p.bytes[
static_cast<size_t>(i) / 2];
281 if (i & 1)
byte = uint8_t((
byte & 0x0Fu) | uint8_t(nib << 4));
282 else byte = uint8_t((
byte & 0xF0u) | nib);