1 /* 2 mkvmerge -- utility for splicing together matroska files 3 from component media subtypes 4 5 Distributed under the GPL v2 6 see the file COPYING for details 7 or visit https://www.gnu.org/licenses/old-licenses/gpl-2.0.html 8 9 math helper functions 10 11 Written by Moritz Bunkus <moritz@bunkus.org>. 12 */ 13 14 #include "common/common_pch.h" 15 16 #include "common/math.h" 17 18 namespace mtx::math { 19 20 uint64_t round_to_nearest_pow2(uint64_t value)21round_to_nearest_pow2(uint64_t value) { 22 uint64_t best_value = 0; 23 uint64_t test_value = 1; 24 25 while (0x8000000000000000ull >= test_value) { 26 if ( (value > test_value ? value - test_value : test_value - value) 27 < (value > best_value ? value - best_value : best_value - value)) 28 best_value = test_value; 29 test_value <<= 1; 30 } 31 32 return best_value; 33 } 34 35 int int_log2(uint64_t value)36int_log2(uint64_t value) { 37 for (int bit = 63; bit >= 0; --bit) 38 if (value & (1ull << bit)) 39 return bit; 40 41 return -1; 42 } 43 44 double int_to_double(int64_t value)45int_to_double(int64_t value) { 46 if (static_cast<uint64_t>(value + value) > (0xffeull << 52)) 47 return static_cast<double>(NAN); 48 return std::ldexp(((value & ((1ll << 52) - 1)) + (1ll << 52)) * (value >> 63 | 1), (value >> 52 & 0x7ff) - 1075); 49 } 50 51 mtx_mp_rational_t clamp_values_to(mtx_mp_rational_t const & r,int64_t max_value)52clamp_values_to(mtx_mp_rational_t const &r, 53 int64_t max_value) { 54 auto num = boost::multiprecision::numerator(r); 55 auto den = boost::multiprecision::denominator(r); 56 57 if (!num || !den || ((num <= max_value) && (den <= max_value))) 58 return r; 59 60 // 333 / 1000 , clamp = 500, mul = 1/2 = 1/(max/clamp) = clamp/max 61 62 auto mult = mtx::rational(max_value, std::max(num, den)); 63 den = mtx::to_int(den * mult); 64 65 return mtx::rational(num * mult, den ? den : 1); 66 } 67 } 68