On 8/20/23 16:11, Bruno Haible wrote:
The new code not only assume two's complement, but also that
right-shift of negative 'int' works as in two's complement.

It's easy enough to remove that assumption, and this makes the code a bit simpler, and not significantly less efficient since GCC implements N % 2 and N / 2 by masking and shifting. I installed the attached.
From 3703c742aa9b90d57bc7427b94cec21a6492d106 Mon Sep 17 00:00:00 2001
From: Paul Eggert <[email protected]>
Date: Sun, 20 Aug 2023 17:55:03 -0700
Subject: [PATCH] =?UTF-8?q?ldexp:=20port=20to=20non-two=E2=80=99s=20comple?=
 =?UTF-8?q?ment?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

* lib/ldexp.c (FUNC): Don’t assume two’s-complement.
---
 ChangeLog   | 5 +++++
 lib/ldexp.c | 9 ++++-----
 2 files changed, 9 insertions(+), 5 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 6575ee12b6..8f346acff5 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2023-08-20  Paul Eggert  <[email protected]>
+
+	ldexp: port to non-two’s complement
+	* lib/ldexp.c (FUNC): Don’t assume two’s-complement.
+
 2023-08-20  Bruno Haible  <[email protected]>
 
 	readutmp, boot-time: Fix the result on runit and s6 init systems.
diff --git a/lib/ldexp.c b/lib/ldexp.c
index 844fd11f53..8bc4073527 100644
--- a/lib/ldexp.c
+++ b/lib/ldexp.c
@@ -57,16 +57,15 @@ FUNC (DOUBLE x, int exp)
   BEGIN_ROUNDING ();
 
   /* Check for zero, nan and infinity. */
-  if (!(ISNAN (x) || x + x == x || exp == 0))
+  if (!(ISNAN (x) || x + x == x))
     {
-      bool negexp = exp < 0;
-      DOUBLE factor = negexp ? L_(0.5) : L_(2.0);
+      DOUBLE factor = exp < 0 ? L_(0.5) : L_(2.0);
 
       while (true)
         {
-          if (exp & 1)
+          if (exp % 2 != 0)
             x *= factor;
-          exp = (exp + negexp) >> 1;
+          exp /= 2;
           if (exp == 0)
             break;
           factor = factor * factor;
-- 
2.41.0

Reply via email to