/**************************************************************************/1/* math_funcs_binary.h */2/**************************************************************************/3/* This file is part of: */4/* GODOT ENGINE */5/* https://godotengine.org */6/**************************************************************************/7/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */8/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */9/* */10/* Permission is hereby granted, free of charge, to any person obtaining */11/* a copy of this software and associated documentation files (the */12/* "Software"), to deal in the Software without restriction, including */13/* without limitation the rights to use, copy, modify, merge, publish, */14/* distribute, sublicense, and/or sell copies of the Software, and to */15/* permit persons to whom the Software is furnished to do so, subject to */16/* the following conditions: */17/* */18/* The above copyright notice and this permission notice shall be */19/* included in all copies or substantial portions of the Software. */20/* */21/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */22/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */23/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */24/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */25/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */26/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */27/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */28/**************************************************************************/2930#pragma once3132#include "core/typedefs.h"3334namespace Math {3536/* Functions to handle powers of 2 and shifting. */3738// Returns `true` if a positive integer is a power of 2, `false` otherwise.39template <typename T>40constexpr bool is_power_of_2(const T x) {41return x && ((x & (x - 1)) == 0);42}4344// Function to find the next power of 2 to an integer.45constexpr uint64_t next_power_of_2(uint64_t p_number) {46if (p_number == 0) {47return 0;48}4950--p_number;51p_number |= p_number >> 1;52p_number |= p_number >> 2;53p_number |= p_number >> 4;54p_number |= p_number >> 8;55p_number |= p_number >> 16;56p_number |= p_number >> 32;5758return ++p_number;59}6061constexpr uint32_t next_power_of_2(uint32_t p_number) {62if (p_number == 0) {63return 0;64}6566--p_number;67p_number |= p_number >> 1;68p_number |= p_number >> 2;69p_number |= p_number >> 4;70p_number |= p_number >> 8;71p_number |= p_number >> 16;7273return ++p_number;74}7576// Function to find the previous power of 2 to an integer.77constexpr uint64_t previous_power_of_2(uint64_t p_number) {78p_number |= p_number >> 1;79p_number |= p_number >> 2;80p_number |= p_number >> 4;81p_number |= p_number >> 8;82p_number |= p_number >> 16;83p_number |= p_number >> 32;84return p_number - (p_number >> 1);85}8687constexpr uint32_t previous_power_of_2(uint32_t p_number) {88p_number |= p_number >> 1;89p_number |= p_number >> 2;90p_number |= p_number >> 4;91p_number |= p_number >> 8;92p_number |= p_number >> 16;93return p_number - (p_number >> 1);94}9596// Function to find the closest power of 2 to an integer.97constexpr uint64_t closest_power_of_2(uint64_t p_number) {98uint64_t nx = next_power_of_2(p_number);99uint64_t px = previous_power_of_2(p_number);100return (nx - p_number) > (p_number - px) ? px : nx;101}102103constexpr uint32_t closest_power_of_2(uint32_t p_number) {104uint32_t nx = next_power_of_2(p_number);105uint32_t px = previous_power_of_2(p_number);106return (nx - p_number) > (p_number - px) ? px : nx;107}108109// Get a shift value from a power of 2.110constexpr int32_t get_shift_from_power_of_2(uint64_t p_bits) {111for (uint64_t i = 0; i < (uint64_t)64; i++) {112if (p_bits == (uint64_t)((uint64_t)1 << i)) {113return i;114}115}116117return -1;118}119120constexpr int32_t get_shift_from_power_of_2(uint32_t p_bits) {121for (uint32_t i = 0; i < (uint32_t)32; i++) {122if (p_bits == (uint32_t)((uint32_t)1 << i)) {123return i;124}125}126127return -1;128}129130template <typename T>131constexpr T nearest_power_of_2_templated(T p_number) {132--p_number;133134// The number of operations on x is the base two logarithm135// of the number of bits in the type. Add three to account136// for sizeof(T) being in bytes.137constexpr size_t shift_steps = get_shift_from_power_of_2((uint64_t)sizeof(T)) + 3;138139// If the compiler is smart, it unrolls this loop.140// If it's dumb, this is a bit slow.141for (size_t i = 0; i < shift_steps; i++) {142p_number |= p_number >> (1 << i);143}144145return ++p_number;146}147148// Function to find the nearest (bigger) power of 2 to an integer.149constexpr uint64_t nearest_shift(uint64_t p_number) {150uint64_t i = 63;151do {152i--;153if (p_number & ((uint64_t)1 << i)) {154return i + (uint64_t)1;155}156} while (i != 0);157158return 0;159}160161constexpr uint32_t nearest_shift(uint32_t p_number) {162uint32_t i = 31;163do {164i--;165if (p_number & ((uint32_t)1 << i)) {166return i + (uint32_t)1;167}168} while (i != 0);169170return 0;171}172173// constexpr function to find the floored log2 of a number174template <typename T>175constexpr T floor_log2(T x) {176return x < 2 ? x : 1 + floor_log2(x >> 1);177}178179// Get the number of bits needed to represent the number.180// IE, if you pass in 8, you will get 4.181// If you want to know how many bits are needed to store 8 values however, pass in (8 - 1).182template <typename T>183constexpr T get_num_bits(T x) {184return floor_log2(x);185}186187} //namespace Math188189190