Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions v6/modules/math.cppm
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,7 @@ export template<std::integral T>
return static_cast<unsigned_t>(difference);
}
}

/**
* @ingroup Math
* @brief Determines if two values are equal within a relative error.
Expand Down Expand Up @@ -240,4 +241,45 @@ export [[nodiscard]] constexpr bool equals(std::floating_point auto p_value1,
return relative_error < p_epsilon;
}
}

/**
* @ingroup Math
* @brief Proportionally scale input value up to fill the desired output integer
* container.
*
* @tparam int_t - output integer storage to be filled with the proportional
* contents of p_value
* @tparam bit_width - width of the input value
* @param p_value - the number to scale to the size of the int_t container
* @return constexpr int_t -
*/
export template<std::unsigned_integral int_t, usize bit_width>
[[nodiscard]] constexpr int_t upscale(int_t p_value)
{
constexpr usize resultant_bit_width = sizeof(int_t) * CHAR_BIT;
static_assert(bit_width > 0 && bit_width <= resultant_bit_width,
"Bit width must be between 1 and 32");
// If already 32 bits, return as-is
if constexpr (bit_width == resultant_bit_width) {
return p_value;
}

// Create mask for the input bits
constexpr auto over_sized_mask = (1LL << bit_width) - 1LL;
constexpr auto mask = static_cast<int_t>(over_sized_mask);

// Calculate number of iterations needed (ceiling(32/bit_width) - 1)
constexpr auto iterations =
(resultant_bit_width + bit_width - 1) / bit_width - 1;

// Place cleaned input value in MSB position
constexpr auto shift_distance = resultant_bit_width - bit_width;
int_t result = (p_value & mask) << shift_distance;

// Replicate the pattern for the calculated number of iterations
for (auto i = 0U; i < iterations; ++i) {
result |= (result >> bit_width);
}
return result;
}
} // namespace hal::inline v6
10 changes: 4 additions & 6 deletions v6/modules/units.cppm
Original file line number Diff line number Diff line change
Expand Up @@ -52,12 +52,10 @@ export [[nodiscard]] constexpr hal::u64 cycles_per(
// hal::time_duration::period::num == 1
// hal::time_duration::period::den == 1,000,000

auto const denominator =
static_cast<float>(decltype(p_duration)::period::den);
auto const float_count = static_cast<float>(p_duration.count());
auto const source_hz =
static_cast<float>(p_source.numerical_value_in(hertz::unit));
auto const cycle_count = (float_count * source_hz) / denominator;
auto const denominator = decltype(p_duration)::period::den;
auto const count = p_duration.count();
auto const source_hz = p_source.numerical_value_in(hertz::unit);
auto const cycle_count = (count * source_hz) / denominator;

return static_cast<hal::u64>(cycle_count);
}
Expand Down
5 changes: 0 additions & 5 deletions v6/test_package/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,6 @@ target_compile_features(${PROJECT_NAME} PRIVATE cxx_std_23)
target_compile_options(${PROJECT_NAME} PRIVATE -fno-rtti)
target_link_libraries(${PROJECT_NAME} PRIVATE libhal::util)

if(NOT CMAKE_CROSSCOMPILING)
target_compile_options(${PROJECT_NAME} PRIVATE -fsanitize=address)
target_link_options(${PROJECT_NAME} PRIVATE -g -fsanitize=address)
endif()

add_custom_target(copy_compile_commands ALL
COMMAND ${CMAKE_COMMAND} -E copy_if_different
${CMAKE_BINARY_DIR}/compile_commands.json
Expand Down
4 changes: 1 addition & 3 deletions v6/tests/units.test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,7 @@ void units_test()
expect(that % 192'000 == hal::cycles_per(12'000'000 * si::hertz, 16ms));
expect(that % 960'000'000 == hal::cycles_per(8'000'000 * si::hertz, 2min));
expect(that % 57'600'000 == hal::cycles_per(32'000 * si::hertz, 30min));
// Should be 600'000'000'000 but due to floating point precision loss it
// cannot be represented
expect(that % 599'999'971'328 ==
expect(that % 18'446'744'064'966'997'184ULL ==
hal::cycles_per(1'000'000'000 * si::hertz, 10min));

// Result of zero means that the time period is smaller than the
Expand Down
Loading