Skip to content

Commit

Permalink
Fix: uint32_t to uint40_t cast (#404)
Browse files Browse the repository at this point in the history
Co-authored-by: Ash Vardanian <[email protected]>
  • Loading branch information
Ngalstyan4 and ashvardanian authored May 8, 2024
1 parent 30a490b commit 37b47b0
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 2 deletions.
34 changes: 34 additions & 0 deletions cpp/test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,39 @@ template <typename index_at> struct aligned_wrapper_gt {
}
};

/**
* Tests the functionality of the custom uint40_t type ensuring consistent
* behavior across various constructors from uint32_t, uint64_t, and size_t types.
*/
void test_uint40() {
// Constants for tests
std::uint64_t max_uint40_k = (1ULL << 40) - 1;

for (std::uint64_t original_value : {
42ull, // Typical small number
4242ull, // Larger number still within uint40 range
1ull << 40, // Exactly at the boundary of uint40
(1ull << 40) + 1, // Just beyond the boundary of uint40
1ull << 63 // Well beyond the uint40 boundary, tests masking
}) {
std::uint32_t v_32 = static_cast<std::uint32_t>(original_value);
std::uint64_t v_64 = original_value;
std::size_t v_size = static_cast<std::size_t>(original_value);

// Create uint40_t instances from different types
uint40_t n_40_from_32(v_32);
uint40_t n_40_from_64(v_64);
uint40_t n_40_from_size(v_size);

// Expected value after masking
std::uint64_t expected_value = original_value & max_uint40_k;

// Check if all conversions are equal to the masked value
expect(n_40_from_32 == expected_value);
expect(n_40_from_64 == expected_value);
expect(n_40_from_size == expected_value);
}
}
/**
* Tests the behavior of various move-constructors and move-assignment operators for the index.
*
Expand Down Expand Up @@ -700,6 +733,7 @@ template <typename key_at, typename slot_at> void test_replacing_update() {
}

int main(int, char**) {
test_uint40();

// Weird corner cases
test_replacing_update<std::int64_t, std::uint32_t>();
Expand Down
4 changes: 2 additions & 2 deletions include/usearch/index.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -785,7 +785,7 @@ class usearch_pack_m uint40_t {

public:
inline uint40_t() noexcept { broadcast(0); }
inline uint40_t(std::uint32_t n) noexcept { std::memcpy(&octets[1], &n, 4); }
inline uint40_t(std::uint32_t n) noexcept { std::memcpy(&octets, &n, 4); }

#ifdef USEARCH_64BIT_ENV
inline uint40_t(std::uint64_t n) noexcept { std::memcpy(octets, &n, 5); }
Expand All @@ -811,7 +811,7 @@ class usearch_pack_m uint40_t {
#ifdef USEARCH_64BIT_ENV
std::memcpy(&result, octets, 5);
#else
std::memcpy(&result, octets + 1, 4);
std::memcpy(&result, octets, 4);
#endif
return result;
}
Expand Down

0 comments on commit 37b47b0

Please sign in to comment.