avr-libc-dev
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [avr-libc-dev] [bug #1929] -Inf not detected


From: E. Weddington
Subject: Re: [avr-libc-dev] [bug #1929] -Inf not detected
Date: Tue, 07 Jun 2005 17:19:52 -0600
User-agent: Mozilla Thunderbird 1.0.2 (Windows/20050317)

Dmitry K. wrote:

On Tuesday 07 June 2005 14:21, Dmitry K. wrote:
...
4.
Avr-libc's functions 'isnan' and 'isinf' are not conform to other
library. For example, next program is failed in AVR/avr-libc:

---------------------------------------
#include <float.h>
#include <math.h>
volatile double vx;

int main ()
{
   vx = DBL_MAX;
   vx = vx * vx;       /* overflow must        */

   if (!isinf(vx) && !isnan(vx))
       return 1;       /* error: vx is not detekted, as non-normal     */

   return 0;
}
---------------------------------------

5.
'isinf', probably, should return always 0 as arithmetics with Inf is not
realized.

I have write a corrected variant 'isnan' (7 words only). I shall send it
after testing.

Rationale for `isnan': it must return non-zero value for all numbers, that
are rejected by libm/avr-libc.

isnan.s (Without extra info lines):
---------------------------------------------
   .text
   .global     isnan
isnan:
       lsl     r24
       rol     r25             ; r25 := exponent
       cpi     r25, 0xff       ; C set, if not equal
       ldi     r25, 0
       ldi     r24, 1
       sbci    r24, 0
       ret
   .end
---------------------------------------------

Small test for isnan:
---------------------------------------------
#include <float.h>
#include <math.h>
#include <stdlib.h>

volatile union {
   long lo;
   float fl;
} vx1, vx2;

void t_isnan (double x, int testno)
{
   /* Is 'x' rejected by avr-libc?     */
   vx1.fl = x / 2.0;
   vx2.fl = vx1.fl / 2.0;
   if (vx2.lo != vx1.lo)       /* force pure comparison        */
       exit(0x0100 + testno);          /* 'x' is not rejected  */

   if (!isnan(x))
       exit(0x200 + testno);           /* isnan() is not work  */
}

void t_isnormal (double x, int testno)
{
   /* Indirect checking: is 'x' a normal number?       */
   vx1.fl = x / 2.0;
   vx2.fl = vx1.fl / 2.0;
   if (vx2.lo == vx1.lo) {     /* force pure comparison        */
       if (vx2.fl != 0)
           exit(0x0300 + testno);      /* 'x' is not rejected  */
   }

   if (isnan(x))
       exit(0x400 + testno);           /* isnan() is not work  */
}

int main ()
{
   static union {
       long lo;
       float fl;
   } x1[] = {                          /* NaNs */
       { 0x7fc0ffff }, { 0xffc0ffff },
       { 0x7f800000 }, { 0xff800000 },
       { 0x7fffffff }, { 0xffffffff },
   };
   static union {
       long lo;
       float fl;
   } x2[] = {                          /* not NaNs     */
       { 0x00000000 }, { 0x80000000 },
       { 0x00800000 }, { 0x80800000 },
       { 0x3f800000 }, { 0xbf800000 },
       { 0x3fffffff }, { 0xbfffffff },
   };
   int i;

   for (i = 0; i < (int)(sizeof(x1)/sizeof(x1[0])); i++)
       t_isnan (x1[i].fl, i+1);
   for (i = 0; i < (int)(sizeof(x2)/sizeof(x2[0])); i++)
       t_isnormal (x2[i].fl, i+1);
   return 0;
}
-------------------------------------------------------------------

Dmitry.
Hi Dmitry,

Could you put this information in the actual bug report please? That way it won't get lost.

Thanks
Eric




reply via email to

[Prev in Thread] Current Thread [Next in Thread]