Fix #128102: Integer Math division has only float precision
The additional division modes were implemented with float division then rounding to match float > int conversion in existing float to int node. As pointed out in the bug report the precision here is limited. This patch replaces the float division with integer math which increases the precision to much higher numbers. Divide Round by due to the way it is calculated has less precision than Divide Floor and Divide Ceil. Pull Request: https://projects.blender.org/blender/blender/pulls/128123
This commit is contained in:
committed by
Jacques Lucke
parent
b96a7b7204
commit
c0a864aaa3
@@ -105,6 +105,14 @@ static void node_label(const bNodeTree * /*ntree*/, const bNode *node, char *lab
|
||||
BLI_strncpy(label, IFACE_(name), maxlen);
|
||||
}
|
||||
|
||||
/* Derived from `divide_round_i` but fixed to be safe and handle negative inputs. */
|
||||
static int safe_divide_round_i(const int a, const int b)
|
||||
{
|
||||
const int c = math::abs(b);
|
||||
return (a >= 0) ? math::safe_divide((2 * a + c), (2 * c)) * math::sign(b) :
|
||||
-math::safe_divide((2 * -a + c), (2 * c)) * math::sign(b);
|
||||
}
|
||||
|
||||
static const mf::MultiFunction *get_multi_function(const bNode &bnode)
|
||||
{
|
||||
NodeIntegerMathOperation operation = NodeIntegerMathOperation(bnode.custom1);
|
||||
@@ -119,16 +127,14 @@ static const mf::MultiFunction *get_multi_function(const bNode &bnode)
|
||||
"Divide", [](int a, int b) { return math::safe_divide(a, b); }, exec_preset);
|
||||
static auto divide_floor_fn = mf::build::SI2_SO<int, int, int>(
|
||||
"Divide Floor",
|
||||
[](int a, int b) { return int(math::floor(math::safe_divide(float(a), float(b)))); },
|
||||
[](int a, int b) { return (b != 0) ? divide_floor_i(a, b) : 0; },
|
||||
exec_preset);
|
||||
static auto divide_ceil_fn = mf::build::SI2_SO<int, int, int>(
|
||||
"Divide Ceil",
|
||||
[](int a, int b) { return int(math::ceil(math::safe_divide(float(a), float(b)))); },
|
||||
[](int a, int b) { return (b != 0) ? -divide_floor_i(a, -b) : 0; },
|
||||
exec_preset);
|
||||
static auto divide_round_fn = mf::build::SI2_SO<int, int, int>(
|
||||
"Divide Round",
|
||||
[](int a, int b) { return int(math::round(math::safe_divide(float(a), float(b)))); },
|
||||
exec_preset);
|
||||
"Divide Round", [](int a, int b) { return safe_divide_round_i(a, b); }, exec_preset);
|
||||
static auto pow_fn = mf::build::SI2_SO<int, int, int>(
|
||||
"Power", [](int a, int b) { return math::pow(a, b); }, exec_preset);
|
||||
static auto madd_fn = mf::build::SI3_SO<int, int, int, int>(
|
||||
|
||||
Reference in New Issue
Block a user