diff options
author | Jarkko Hietaniemi <jhi@iki.fi> | 2015-02-07 13:12:33 -0500 |
---|---|---|
committer | Jarkko Hietaniemi <jhi@iki.fi> | 2015-02-08 21:54:49 -0500 |
commit | a307a0b0d83c509cc2adaad8cebb44260294bf36 (patch) | |
tree | 03b188d2e823e53d93fb0d80c36ec9f73c33d5fe | |
parent | 6640aa2c3b93d7ac78e4e86983fe5948b3ca55f2 (diff) | |
download | perl-a307a0b0d83c509cc2adaad8cebb44260294bf36.tar.gz |
infnan: add nan_is_signaling
-rw-r--r-- | embed.fnc | 1 | ||||
-rw-r--r-- | embed.h | 1 | ||||
-rw-r--r-- | numeric.c | 35 | ||||
-rw-r--r-- | proto.h | 1 |
4 files changed, 38 insertions, 0 deletions
@@ -821,6 +821,7 @@ Apd |UV |grok_oct |NN const char* start|NN STRLEN* len_p|NN I32* flags|NULLOK NV Apdn |UV |grok_atou |NN const char* pv|NULLOK const char** endptr Apd |U8* |nan_hibyte|NN NV *nvp|NN U8* mask Apd |void |nan_signaling_set|NN NV *nvp|bool signaling +Apd |int |nan_is_signaling|NV nv : These are all indirectly referenced by globals.c. This is somewhat annoying. p |int |magic_clearenv |NN SV* sv|NN MAGIC* mg p |int |magic_clear_all_env|NN SV* sv|NN MAGIC* mg @@ -357,6 +357,7 @@ #define my_strerror(a) Perl_my_strerror(aTHX_ a) #define my_strftime(a,b,c,d,e,f,g,h,i,j) Perl_my_strftime(aTHX_ a,b,c,d,e,f,g,h,i,j) #define nan_hibyte(a,b) Perl_nan_hibyte(aTHX_ a,b) +#define nan_is_signaling(a) Perl_nan_is_signaling(aTHX_ a) #define nan_signaling_set(a,b) Perl_nan_signaling_set(aTHX_ a,b) #define newANONATTRSUB(a,b,c,d) Perl_newANONATTRSUB(aTHX_ a,b,c,d) #define newANONHASH(a) Perl_newANONHASH(aTHX_ a) @@ -629,6 +629,41 @@ Perl_nan_signaling_set(NV *nvp, bool signaling) } /* +=for apidoc nan_is_signaling + +Returns true if the nv is a NaN is a signaling NaN. + +=cut +*/ +int +Perl_nan_is_signaling(NV nv) +{ + /* Quiet NaN bit pattern (64-bit doubles, ignore endianness): + * x86 00 00 00 00 00 00 f8 7f + * sparc 7f ff ff ff ff ff ff ff + * mips 7f f7 ff ff ff ff ff ff + * hppa 7f f4 00 00 00 00 00 00 + * The "7ff" is the exponent. The most significant bit of the NaN + * (note: here, not the most significant bit of the byte) is of + * interest: in the x86 style (also in sparc) the bit on means + * 'quiet', in the mips style the bit off means 'quiet'. */ +#ifdef Perl_fp_classify_snan + return Perl_fp_classify_snan(nv); +#else + if (Perl_isnan(nv)) { + U8 mask; + U8 *hibyte = Perl_nan_hibyte(&nv, &mask); + /* Hoping NV_NAN is a quiet nan - this might be a false hope. + * XXX Configure test */ + const NV nan = NV_NAN; + return (*hibyte & mask) != (((U8*)&nan)[hibyte - (U8*)&nv] & mask); + } else { + return 0; + } +#endif +} + +/* =for apidoc grok_infnan Helper for grok_number(), accepts various ways of spelling "infinity" @@ -2844,6 +2844,7 @@ PERL_CALLCONV U8* Perl_nan_hibyte(pTHX_ NV *nvp, U8* mask) #define PERL_ARGS_ASSERT_NAN_HIBYTE \ assert(nvp); assert(mask) +PERL_CALLCONV int Perl_nan_is_signaling(pTHX_ NV nv); PERL_CALLCONV void Perl_nan_signaling_set(pTHX_ NV *nvp, bool signaling) __attribute__nonnull__(pTHX_1); #define PERL_ARGS_ASSERT_NAN_SIGNALING_SET \ |