xref: /illumos-gate/usr/src/head/nan.h (revision b4203d75)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
57c478bd9Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
67c478bd9Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
77c478bd9Sstevel@tonic-gate  * with the License.
87c478bd9Sstevel@tonic-gate  *
97c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
107c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
117c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
127c478bd9Sstevel@tonic-gate  * and limitations under the License.
137c478bd9Sstevel@tonic-gate  *
147c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
157c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
167c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
177c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
187c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
197c478bd9Sstevel@tonic-gate  *
207c478bd9Sstevel@tonic-gate  * CDDL HEADER END
217c478bd9Sstevel@tonic-gate  */
227c478bd9Sstevel@tonic-gate /*	Copyright (c) 1988 AT&T	*/
23*b4203d75SMarcel Telka /*	  All Rights Reserved	*/
247c478bd9Sstevel@tonic-gate 
257c478bd9Sstevel@tonic-gate 
267c478bd9Sstevel@tonic-gate /*
27ba3594baSGarrett D'Amore  * Copyright 2014 Garrett D'Amore <garrett@damore.org>
28ba3594baSGarrett D'Amore  *
297c478bd9Sstevel@tonic-gate  * Copyright (c) 1996, by Sun Microsystems, Inc.
307c478bd9Sstevel@tonic-gate  * All Rights Reserved
317c478bd9Sstevel@tonic-gate  */
327c478bd9Sstevel@tonic-gate 
337c478bd9Sstevel@tonic-gate #ifndef _NAN_H
347c478bd9Sstevel@tonic-gate #define	_NAN_H
357c478bd9Sstevel@tonic-gate 
367c478bd9Sstevel@tonic-gate /*
377c478bd9Sstevel@tonic-gate  * Handling of Not_a_Number's (only in IEEE floating-point standard)
387c478bd9Sstevel@tonic-gate  */
397c478bd9Sstevel@tonic-gate 
407c478bd9Sstevel@tonic-gate #include <sys/isa_defs.h>
417c478bd9Sstevel@tonic-gate #include <values.h>
427c478bd9Sstevel@tonic-gate 
437c478bd9Sstevel@tonic-gate #ifdef	__cplusplus
447c478bd9Sstevel@tonic-gate extern "C" {
457c478bd9Sstevel@tonic-gate #endif
467c478bd9Sstevel@tonic-gate 
477c478bd9Sstevel@tonic-gate #if defined(_IEEE_754)
487c478bd9Sstevel@tonic-gate /*
497c478bd9Sstevel@tonic-gate  * Structure order is endian dependent.  Only the common variants of
507c478bd9Sstevel@tonic-gate  * big and little endian are supported.
517c478bd9Sstevel@tonic-gate  */
527c478bd9Sstevel@tonic-gate 
537c478bd9Sstevel@tonic-gate #if defined(_BIG_ENDIAN)
547c478bd9Sstevel@tonic-gate 
557c478bd9Sstevel@tonic-gate typedef union
567c478bd9Sstevel@tonic-gate {
577c478bd9Sstevel@tonic-gate 	struct
587c478bd9Sstevel@tonic-gate 	{
597c478bd9Sstevel@tonic-gate 		unsigned sign		: 1;
607c478bd9Sstevel@tonic-gate 		unsigned exponent	:11;
617c478bd9Sstevel@tonic-gate 		unsigned bits		:20;
627c478bd9Sstevel@tonic-gate 		unsigned fraction_low	:32;
637c478bd9Sstevel@tonic-gate 	} inf_parts;
647c478bd9Sstevel@tonic-gate 	struct
657c478bd9Sstevel@tonic-gate 	{
667c478bd9Sstevel@tonic-gate 		unsigned sign		: 1;
677c478bd9Sstevel@tonic-gate 		unsigned exponent	:11;
687c478bd9Sstevel@tonic-gate 		unsigned qnan_bit	: 1;
697c478bd9Sstevel@tonic-gate 		unsigned bits		:19;
707c478bd9Sstevel@tonic-gate 		unsigned fraction_low	:32;
717c478bd9Sstevel@tonic-gate 	} nan_parts;
727c478bd9Sstevel@tonic-gate 	double d;
737c478bd9Sstevel@tonic-gate 
747c478bd9Sstevel@tonic-gate } dnan;
757c478bd9Sstevel@tonic-gate 
767c478bd9Sstevel@tonic-gate #else	/* Must be _LITTLE_ENDIAN */
777c478bd9Sstevel@tonic-gate 
787c478bd9Sstevel@tonic-gate typedef union
797c478bd9Sstevel@tonic-gate {
807c478bd9Sstevel@tonic-gate 	struct {
817c478bd9Sstevel@tonic-gate 		unsigned fraction_low	:32;
827c478bd9Sstevel@tonic-gate 		unsigned bits		:20;
837c478bd9Sstevel@tonic-gate 		unsigned exponent	:11;
847c478bd9Sstevel@tonic-gate 		unsigned sign		: 1;
857c478bd9Sstevel@tonic-gate 	} inf_parts;
867c478bd9Sstevel@tonic-gate 	struct {
877c478bd9Sstevel@tonic-gate 		unsigned fraction_low	:32;
887c478bd9Sstevel@tonic-gate 		unsigned bits		:19;
897c478bd9Sstevel@tonic-gate 		unsigned qnan_bit	: 1;
907c478bd9Sstevel@tonic-gate 		unsigned exponent	:11;
917c478bd9Sstevel@tonic-gate 		unsigned sign		: 1;
927c478bd9Sstevel@tonic-gate 	} nan_parts;
937c478bd9Sstevel@tonic-gate 	double d;
947c478bd9Sstevel@tonic-gate } dnan;
957c478bd9Sstevel@tonic-gate 
967c478bd9Sstevel@tonic-gate #endif	/* Endian based selection */
977c478bd9Sstevel@tonic-gate 
987c478bd9Sstevel@tonic-gate /*
997c478bd9Sstevel@tonic-gate  * IsNANorINF checks that exponent of double == 2047
1007c478bd9Sstevel@tonic-gate  * i.e. that number is a NaN or an infinity
1017c478bd9Sstevel@tonic-gate  */
1027c478bd9Sstevel@tonic-gate #define	IsNANorINF(X)  (((dnan *)&(X))->nan_parts.exponent == 0x7ff)
1037c478bd9Sstevel@tonic-gate 
1047c478bd9Sstevel@tonic-gate /*
1057c478bd9Sstevel@tonic-gate  * IsINF must be used after IsNANorINF has checked the exponent
1067c478bd9Sstevel@tonic-gate  */
1077c478bd9Sstevel@tonic-gate #define	IsINF(X)	(((dnan *)&(X))->inf_parts.bits == 0 && \
1087c478bd9Sstevel@tonic-gate 			    ((dnan *)&(X))->inf_parts.fraction_low == 0)
1097c478bd9Sstevel@tonic-gate 
1107c478bd9Sstevel@tonic-gate /*
1117c478bd9Sstevel@tonic-gate  * IsPosNAN and IsNegNAN can be used to check the sign of infinities too
1127c478bd9Sstevel@tonic-gate  */
1137c478bd9Sstevel@tonic-gate #define	IsPosNAN(X)	(((dnan *)&(X))->nan_parts.sign == 0)
1147c478bd9Sstevel@tonic-gate 
1157c478bd9Sstevel@tonic-gate #define	IsNegNAN(X)	(((dnan *)&(X))->nan_parts.sign == 1)
1167c478bd9Sstevel@tonic-gate 
1177c478bd9Sstevel@tonic-gate /*
1187c478bd9Sstevel@tonic-gate  * GETNaNPC gets the leftmost 32 bits of the fraction part
1197c478bd9Sstevel@tonic-gate  */
1207c478bd9Sstevel@tonic-gate #define	GETNaNPC(dval)	(((dnan *)&(dval))->inf_parts.bits << 12 | \
1217c478bd9Sstevel@tonic-gate 			    ((dnan *)&(dval))->nan_parts.fraction_low >> 20)
1227c478bd9Sstevel@tonic-gate 
1237c478bd9Sstevel@tonic-gate #define	KILLFPE()	(void) _kill(_getpid(), 8)
1247c478bd9Sstevel@tonic-gate #define	NaN(X)		(((dnan *)&(X))->nan_parts.exponent == 0x7ff)
1257c478bd9Sstevel@tonic-gate #define	KILLNaN(X)	if (NaN(X)) KILLFPE()
1267c478bd9Sstevel@tonic-gate 
1277c478bd9Sstevel@tonic-gate #else	/* defined(_IEEE_754) */
1287c478bd9Sstevel@tonic-gate /* #error is strictly ansi-C, but works as well as anything for K&R systems. */
1297c478bd9Sstevel@tonic-gate #error ISA not supported
1307c478bd9Sstevel@tonic-gate #endif	/* defined(_IEEE_754) */
1317c478bd9Sstevel@tonic-gate 
1327c478bd9Sstevel@tonic-gate #ifdef	__cplusplus
1337c478bd9Sstevel@tonic-gate }
1347c478bd9Sstevel@tonic-gate #endif
1357c478bd9Sstevel@tonic-gate 
1367c478bd9Sstevel@tonic-gate #endif	/* _NAN_H */
137