This is the mail archive of the newlib@sourceware.org mailing list for the newlib project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Problems VPATH, pow


Ok Daniel, if I understand correctly, you are building newlib with --enable-newlib-hw-fp. Correct?

Anyway, I did find a problem with the mathfp pow routines as you had mentioned. They were attempting to do log (fabs (x)) in the x == 0.0 case which is incorrect. I just checked in the attached patch so feel free to try it out.

Using the regular libm/math pow routines, I am seeing the correct result.

-- Jeff J.

Davies, Daniel wrote:
Jeff,

Thanks for your very quick response!

Thanks also for pushing me into making a simple test case.  I discovered
along the way that there was a tangle of dependencies between my RTOS
and newlib that resulted in using the RTOS's buggy version of modf.

When that was straightened out, I discovered that pow(0,2) works fine,
but pow(0,0.5) fails.  That's what had actually triggered my first bug,
but I generalized the problem incorrectly based on my mis-reading of the
pow source code.  Sorry!

#include <stdio.h>
#include <math.h>

int
main(int argc, char **argv)
{
    printf("pow (1,2) is %f\n", pow(1,2));

printf("pow (0,2) is %f\n", pow(0,2));

printf("pow (0,1) is %f\n", pow(0,1));

printf("pow (0,0.5) is %f\n", pow(0,0.5));

printf("pow (0,0.1) is %f\n", pow(0,0.1));

printf("pow (4,0.5) is %f\n", pow(4,0.5));

printf("pow (2,2) is %f\n", pow(2,2));

    return 0;
}

Produces the following output on my system (powerpc-unknown-eabialtivec,
an embedded board.  The boards has a 7447A.  The code is compiled with
gcc-4.0.1 using hard floating point).

pow (1,2) is 1.000000
pow (0,2) is 0.000000
pow (0,1) is 0.000000
pow (0,0.5) is 1.000000		<wrong>
pow (0,0.1) is 1.000000		<wrong>
pow (4,0.5) is 2.000000
pow (2,2) is 4.000000

Dan



-----Original Message-----
From: Jeff Johnston [mailto:jjohnstn@redhat.com] Sent: Tuesday, August 30, 2005 10:11 AM
To: Davies, Daniel
Cc: newlib@sources.redhat.com
Subject: Re: Problems VPATH, pow


Davies, Daniel wrote:

Sorry for the subject-less message - I hit the send button too soon.

-----Original Message-----
From: Davies, Daniel
Sent: Monday, August 29, 2005 1:57 PM
To: 'newlib@sources.redhat.com'
Cc: Davies, Daniel
Subject:


First, let me thank everyone involved with newlib, it has certainly made my life easier!

I'm cross compiling newlib 1.13.0 for powerpc-unknown-eabialtivec on i386-pc-solaris2.10. I'm using version 3.80 of gnu make and gcc

4.0.1.



Two nits:


1. This is probably a solairs-ism. The VPATH declaration in newlib-1.13.0/libgloss/rs6000/Makefile.in is

VPATH = @srcdir@ @srcdir@/..

This does not work in Solairs.

VPATH = @srcdir@:@srcdir@/..

(replaced space with colon) works.



I have changed this over to use colon as gnu make accepts either space
or colon.


2. pow(0, y) = 1 for all y > 0, e.g. 0^2 = 1. It looks like pow doesn't check for this case, takes the log of 0 (which is undefined), gets a number very close to 0 instead of an approximation to minus infinity, later takes exp of this number and gets 1.



Can you provide a test that demonstrates your problem?  I have a simple
test which when run on mn10300 and linux, works as expected (result of
pow (0,2) is 0).

#include <stdio.h>
#include <math.h>

int main (void)
{
   printf ("pow (1,2) is %g\n", pow (1, 2));
   printf ("pow (0,2) is %g\n", pow (0, 2));
   printf ("pow (2,2) is %g\n", pow (2, 2));
   return 0;
}
~
bash-3.00$ ./a.out
pow (1,2) is 1
pow (0,2) is 0
pow (2,2) is 4



Dan



Index: libm/mathfp/s_pow.c
===================================================================
RCS file: /cvs/src/src/newlib/libm/mathfp/s_pow.c,v
retrieving revision 1.3
diff -u -p -r1.3 s_pow.c
--- libm/mathfp/s_pow.c	20 Oct 2003 18:46:38 -0000	1.3
+++ libm/mathfp/s_pow.c	1 Sep 2005 17:51:14 -0000
@@ -75,9 +75,10 @@ double pow (double x, double y)
         }
     }
 
-  if (x == 0.0 && y <= 0.0)
+  if (x == 0.0)
     {
-      errno = EDOM;
+      if (y <= 0.0)
+        errno = EDOM;
     }
   else if ((t = y * log (fabs (x))) >= BIGX) 
     {
Index: libm/mathfp/sf_pow.c
===================================================================
RCS file: /cvs/src/src/newlib/libm/mathfp/sf_pow.c,v
retrieving revision 1.3
diff -u -p -r1.3 sf_pow.c
--- libm/mathfp/sf_pow.c	28 Jun 2002 15:32:45 -0000	1.3
+++ libm/mathfp/sf_pow.c	1 Sep 2005 17:51:14 -0000
@@ -29,9 +29,10 @@ float powf (float x, float y)
         }
     }
 
-  if (x == 0.0 && y <= 0.0)
+  if (x == 0.0)
     {
-      errno = EDOM;
+      if (y <= 0.0)
+        errno = EDOM;
     }
   else if ((t = y * log (fabsf (x))) >= BIGX) 
     {

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]