-----Original Message-----
From: r-devel-bounces at r-project.org
[mailto:r-devel-bounces at r-project.org] On Behalf Of William Dunlap
Sent: Friday, May 01, 2009 7:50 AM
To: Martin Maechler
Cc: r-devel at r-project.org
Subject: Re: [Rd] NA_real_ <op> NaN -> NA or NaN, should we care?
From: Martin Maechler [mailto:maechler at stat.math.ethz.ch]
Sent: Friday, May 01, 2009 5:15 AM
To: William Dunlap
Cc: r-devel at r-project.org
Subject: Re: [Rd] NA_real_ <op> NaN -> NA or NaN, should we care?
William Dunlap <wdunlap at tibco.com>
on Thu, 30 Apr 2009 10:51:43 -0700 writes:
> On Linux when I compile R 2.10.0(devel)
(src/main/arithmetic.c in
> particular)
> with gcc 3.4.5 using the flags -g -O2 I get
noncommutative behavior when
is this really gcc 3.4.5 (which is quite old) ?
Yes, it was 3.4.5, but here is a self-contained example of the same
issue using gcc 4.1.3 on an Ubuntu Linux machine:
% gcc -O2 t.c -o a.out ; ./a.out
NA : 7ff00000000007a2
NaN: fff8000000000000
NA+NaN: 7ff80000000007a2
NaN+NA: fff8000000000000
% gcc t.c -o a.out ; ./a.out
NA : 7ff00000000007a2
NaN: fff8000000000000
NA+NaN: 7ff80000000007a2
NaN+NA: 7ff80000000007a2
% gcc -v
Using built-in specs.
Target: i486-linux-gnu
Configured with: ../src/configure -v
--enable-languages=c,c++,fortran,objc,obj-c++,treelang
--prefix=/usr --enable-shared --with-system-zlib
--libexecdir=/usr/lib --without-included-gettext
--enable-threads=posix --enable-nls
--with-gxx-include-dir=/usr/include/c++/4.1.3
--program-suffix=-4.1 --enable-__cxa_atexit
--enable-clocale=gnu --enable-libstdcxx-debug --enable-mpfr
--enable-checking=release i486-linux-gnu
Thread model: posix
gcc version 4.1.3 20070929 (prerelease) (Ubuntu 4.1.2-16ubuntu2)
% cat t.c
#include <stdio.h>
#include <stdint.h>
#include <string.h>
int main(int argc, char *argv[])
{
int64_t NA_int64 = 0x7ff00000000007a2LL ;
int64_t NaN_int64 = 0xfff8000000000000LL ;
int64_t sum_int64 ;
double NA_double, NaN_double, sum_double ;
memcpy((void*)&NA_double, (void*)&NA_int64, 8) ;
memcpy((void*)&NaN_double, (void*)&NaN_int64, 8) ;
NaN_double = 1/0.0 - 1/0.0 ;
printf("NA : %Lx\n", *(int64_t*)&NA_double);
printf("NaN: %Lx\n", *(int64_t*)&NaN_double);
sum_double = NA_double + NaN_double ;
memcpy((void*)&sum_int64, (void*)&sum_double, 8) ;
printf("NA+NaN: %Lx\n", sum_int64) ;
sum_double = NaN_double + NA_double ;
memcpy((void*)&sum_int64, (void*)&sum_double, 8) ;
printf("NaN+NA: %Lx\n", sum_int64);
return 0 ;
}
When I add -Wall to the -O2 then it gives me some warnings about the
*(int64_t)&doubleVal in the printf statements for the inputs,
but I used
memcpy() to avoid the warnings when printing the outputs.
% gcc -Wall -O2 t.c -o a.out ; ./a.out
t.c: In function ?main?:
t.c:17: warning: dereferencing type-punned pointer will break
strict-aliasing rules
t.c:18: warning: dereferencing type-punned pointer will break
strict-aliasing rules
NA : 7ff00000000007a2
NaN: fff8000000000000
NA+NaN: 7ff80000000007a2
NaN+NA: fff8000000000000
Bill Dunlap
TIBCO Software Inc - Spotfire Division
wdunlap tibco.com