Skip to content

Commit 11cfb94

Browse files
committed
Clamp before downcasting in float to i8 conversions
Previously we were downcasting floats to the target type (e.g. int8_t), and then clamping to [-100, 100] range. This means that e.g. 129 would be cast to -127 and then converted to -100, in stead of becoming 100 The fix does clamping first, and then casts the resulting number (which is guaranteed to be in range [-100, 100], due to clamping) from source type to target int8_t. Given the clamping, this will never overflow.
1 parent c453582 commit 11cfb94

File tree

1 file changed

+4
-3
lines changed

1 file changed

+4
-3
lines changed

include/usearch/index_plugins.hpp

+4-3
Original file line numberDiff line numberDiff line change
@@ -960,12 +960,13 @@ class i8_converted_t {
960960
inline explicit operator std::int32_t() const noexcept { return int8_; }
961961
inline explicit operator std::int64_t() const noexcept { return int8_; }
962962

963+
/* clamp uses std::less comparator which does not have comparisons for f16_t, so promoting v to float below */
963964
inline i8_converted_t(f16_t v)
964-
: int8_(usearch::clamp<std::int8_t>(static_cast<std::int8_t>(v * divisor_k), min_k, max_k)) {}
965+
: int8_(static_cast<std::int8_t>(usearch::clamp<f32_t>(v * divisor_k, min_k, max_k))) {}
965966
inline i8_converted_t(f32_t v)
966-
: int8_(usearch::clamp<std::int8_t>(static_cast<std::int8_t>(v * divisor_k), min_k, max_k)) {}
967+
: int8_(static_cast<std::int8_t>(usearch::clamp<f32_t>(v * divisor_k, min_k, max_k))) {}
967968
inline i8_converted_t(f64_t v)
968-
: int8_(usearch::clamp<std::int8_t>(static_cast<std::int8_t>(v * divisor_k), min_k, max_k)) {}
969+
: int8_(static_cast<std::int8_t>(usearch::clamp<f64_t>(v * divisor_k, min_k, max_k))) {}
969970
};
970971

971972
f16_bits_t::f16_bits_t(i8_converted_t v) noexcept : uint16_(f32_to_f16(v)) {}

0 commit comments

Comments
 (0)