octave-bug-tracker
[Top][All Lists]
Advanced

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

[Octave-bug-tracker] [bug #40668] -NA is inconsistent with other operati


From: Rik
Subject: [Octave-bug-tracker] [bug #40668] -NA is inconsistent with other operations on NA
Date: Wed, 16 Aug 2017 01:46:29 -0400 (EDT)
User-agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:54.0) Gecko/20100101 Firefox/54.0

Follow-up Comment #12, bug #40668 (project octave):

I found the section in the R manual that you did with a description of NA.


The representation of the special values for R numeric and complex types is
machine-dependent, and possibly also compiler-dependent. The simplest way to
make use of them is to link an external application against the standalone
Rmath library which exports double constants NA_REAL, R_PosInf and R_NegInf,
and include the header Rmath.h which defines the macros ISNAN and R_FINITE.

If that is not possible, on all current platforms IEC 60559 (aka IEEE 754)
arithmetic is used, so standard C facilities can be used to test for or set
Inf, -Inf and NaN values. On such platforms NA is represented by the NaN value
with low-word 0x7a2 (1954 in decimal). 


In liboctave/util/lo-ieee.cc there is both a new and an old NA routine.


int
__lo_ieee_is_NA (double x)
{
  lo_ieee_double t;
  t.value = x;
  return (__lo_ieee_isnan (x) && t.word[lo_ieee_hw] == LO_IEEE_NA_HW
          && t.word[lo_ieee_lw] == LO_IEEE_NA_LW) ? 1 : 0;
}

int
__lo_ieee_is_old_NA (double x)
{
  lo_ieee_double t;
  t.value = x;
  return (__lo_ieee_isnan (x) && t.word[lo_ieee_lw] == LO_IEEE_NA_LW_OLD
          && t.word[lo_ieee_hw] == LO_IEEE_NA_HW_OLD) ? 1 : 0;
}


And finally from lo-ieee.h


#define LO_IEEE_NA_LW_OLD 1954
#define LO_IEEE_NA_HW 0x7FF840F4
#define LO_IEEE_NA_LW 0x40000000
#define LO_IEEE_NA_FLOAT   0x7FC207A2
#define LO_IEEE_NA_HW_OLD 0x7ff00000


The old and new are weird, and from the R documentation I think Octave is
trying to be too specific.  The code shouldn't need to test the upper word.  I
think testing only for isnan and the lower word equal to 1954 is enough.  But
this brings up another issue.  Like the code which determines endianness, this
code writes to one struct member, and then reads from another, the behavior of
which is not guaranteed in C++.  Either this file needs to be a straight C
file and compiled with a C compiler, or it should be re-coded.

Here's an attempt


__lo_ieee_is_NA (double x)
{
  return ((__lo_ieee_isnan (x) && (reinterpret_cast<uint32_t *> (&x) == 1954))
? 1 : 0;)   
}



I think this depends on a little-endian machine though.



    _______________________________________________________

Reply to this item at:

  <http://savannah.gnu.org/bugs/?40668>

_______________________________________________
  Message sent via/by Savannah
  http://savannah.gnu.org/




reply via email to

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