From 198b6f1b1210e39aec466afd63fe3fcf36b070e6 Mon Sep 17 00:00:00 2001 From: Rangi42 Date: Mon, 30 Dec 2024 13:52:33 -0500 Subject: [PATCH] Avoid division by zero with fixed-point `DIV` and `LOG` --- src/asm/fixpoint.cpp | 11 +++++++++-- test/asm/math.asm | 3 +++ 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/asm/fixpoint.cpp b/src/asm/fixpoint.cpp index 04b35cab05..3ea0aa0b54 100644 --- a/src/asm/fixpoint.cpp +++ b/src/asm/fixpoint.cpp @@ -73,7 +73,11 @@ int32_t fix_Mul(int32_t i, int32_t j, int32_t q) { } int32_t fix_Div(int32_t i, int32_t j, int32_t q) { - return double2fix(fix2double(i, q) / fix2double(j, q), q); + double dividend = fix2double(i, q); + double divisor = fix2double(j, q); + if (divisor == 0.0) + return dividend < 0 ? INT32_MIN : dividend > 0 ? INT32_MAX : 0; + return double2fix(dividend / divisor, q); } int32_t fix_Mod(int32_t i, int32_t j, int32_t q) { @@ -85,7 +89,10 @@ int32_t fix_Pow(int32_t i, int32_t j, int32_t q) { } int32_t fix_Log(int32_t i, int32_t j, int32_t q) { - return double2fix(log(fix2double(i, q)) / log(fix2double(j, q)), q); + double divisor = log(fix2double(j, q)); + if (divisor == 0.0) + return INT32_MAX; + return double2fix(log(fix2double(i, q)) / divisor, q); } int32_t fix_Round(int32_t i, int32_t q) { diff --git a/test/asm/math.asm b/test/asm/math.asm index 9f87a11b3e..14dbafff99 100644 --- a/test/asm/math.asm +++ b/test/asm/math.asm @@ -37,6 +37,9 @@ ENDM assert LOG(100.0, 10.0) == 2.0 assert LOG(256.0, 2.0) == 8.0 + assert LOG(10.0, 1.0) == $7fff_ffff ; +inf + assert LOG(0.0, 2.71828) == $8000_0000 ; -inf + assert LOG(-1.0, 2.71828) == 0 ; nan assert ROUND(1.5) == 2.0 assert ROUND(-1.5) == -2.0