this repo has no description
1/* This module provides declarations and definitions common to the
2 implementations of C standard math functions nanf, nan, and nanl in nan.c
3 and nanl.c.
4
5 $Revision: 1.4 $, $Date: 2006/02/01 18:36:35 $
6*/
7
8
9/*
10 * Copyright (c) 2005 Apple Computer, Inc. All rights reserved.
11 *
12 * @APPLE_LICENSE_HEADER_START@
13 *
14 * The contents of this file constitute Original Code as defined in and
15 * are subject to the Apple Public Source License Version 1.1 (the
16 * "License"). You may not use this file except in compliance with the
17 * License. Please obtain a copy of the License at
18 * http://www.apple.com/publicsource and read it before using this file.
19 *
20 * This Original Code and all software distributed under the License are
21 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
22 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
23 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
24 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
25 * License for the specific language governing rights and limitations
26 * under the License.
27 *
28 * @APPLE_LICENSE_HEADER_END@
29 */
30
31
32/* These definitions and the implementations of nanf, nan, and nanl rely on:
33
34 The C 1999 standard, ISO/IEC 9899:1999(E), Programming Languages--C.
35
36 IEEE Std 754-1985, IEEE Standard for Binary Floating-Point Arithmetic.
37 (Later designated IEC 60559 and IEC 559.)
38
39 GCC behavior:
40
41 __BIG_ENDIAN__ is defined iff the most significant bytes of an
42 object appear at lower addresses.
43
44 Data may be written to one member of a union and read with a new
45 interpretation from another member.
46
47 In the run-time character set, the digits 0 through 9 must be
48 consecutive characters, the letters A through F must be consecutive
49 characters, and the letters a through f must be consecutive
50 characters.
51
52 __POWERPC__ and __i386__ are defined when compiling for the
53 corresponding architectures.
54
55 __LONG_DOUBLE_128__ is defined iff long double is implemented as
56 pair of doubles.
57
58 PowerPC and Intel IA-32 architecture:
59
60 The floating-point format, including that the most significant bit
61 of the significand of a NaN is true iff the NaN is quiet.
62
63 Motorola (later separated into Freescale), Programming
64 Environments Manual for 32-Bit Implementations of the PowerPC
65 Architecture, MPCFPE32B/AD 12/2002 Revision 2, section 3.3,
66 "Floating-Point Execution Models--UISA."
67
68 Intel, IA-32 Intel Architecture Software Developer's Manual,
69 Volume 1: Basic Architecture, 2002, 245470-007, section 4.8,
70 "Real Numbers and Floating-Point Formats."
71*/
72
73
74#include "math.h"
75#include <stdint.h>
76#include <stdlib.h>
77
78
79// Define the type Float to access the representation of a float.
80typedef union
81{
82 float f;
83 struct
84 {
85 #if defined __BIG_ENDIAN__
86 unsigned int sign : 1;
87 unsigned int exponent : 8;
88 unsigned int quiet : 1;
89 unsigned int significand : 22;
90 #else
91 unsigned int significand : 22;
92 unsigned int quiet : 1;
93 unsigned int exponent : 8;
94 unsigned int sign : 1;
95 #endif
96 } s;
97} Float;
98
99
100// Define the type Double to access the representation of a double.
101typedef union
102{
103 double d;
104 struct
105 {
106 #if defined __BIG_ENDIAN__
107 unsigned int sign : 1;
108 unsigned int exponent : 11;
109 unsigned int quiet : 1;
110 uint64_t significand : 51;
111 #else
112 uint64_t significand : 51;
113 unsigned int quiet : 1;
114 unsigned int exponent : 11;
115 unsigned int sign : 1;
116 #endif
117 } s;
118} Double;
119
120
121/* Define the type LongDouble to access the representation of a long double.
122
123 This has some complications. On a PowerPC, a long double is implemented
124 either as two doubles (with -mlong-double-128, the default) or as a single
125 double (with -mlong-double-64, provided primarily for Unix 2003
126 compliance). In a long double NaN, the value of the second double, if
127 present, is ignored. Only the significand of the first double is used.
128
129 On IA-32, a long double has a different format, with an explicit integer
130 bit in the significand.
131
132 We mostly handle these differences in this type definition. The nanl code
133 has some additional code that is conditional on the differences.
134
135 It is probably overkill to provide both big- and little-endian definitions
136 for each of PowerPC and IA-32, but it does not hurt to be prepared.
137*/
138typedef union
139{
140 long double ld;
141 #if defined __POWERPC__ // Architecture.
142 struct
143 {
144 #if defined __BIG_ENDIAN__
145 unsigned int sign : 1;
146 unsigned int exponent : 11;
147 unsigned int quiet : 1;
148 uint64_t significand : 51;
149 #if defined __LONG_DOUBLE_128__
150 double d;
151 #endif
152 #else
153 #if defined __LONG_DOUBLE_128__
154 double d;
155 #endif
156 uint64_t significand : 51;
157 unsigned int quiet : 1;
158 unsigned int exponent : 11;
159 unsigned int sign : 1;
160 #endif
161 } s;
162 #elif ( defined( __i386__ ) || defined( __x86_64__ ) ) // Architecture.
163 struct
164 {
165 #if defined __BIG_ENDIAN__
166 unsigned int sign : 1;
167 unsigned int exponent : 15;
168 unsigned int integer : 1;
169 unsigned int quiet : 1;
170 uint64_t significand : 62;
171 #else
172 uint64_t significand : 62;
173 unsigned int quiet : 1;
174 unsigned int integer : 1;
175 unsigned int exponent : 15;
176 unsigned int sign : 1;
177 #endif
178 } __attribute__((packed)) s;
179 #else // Architecture.
180 // Code for long doubles must be written for this architecture.
181 #error "Unrecognized architecture."
182 #endif // Architecture.
183} LongDouble;
184
185
186/* ConstructSignificand parses the tagp argument of nanf, nan, or nanl and
187 returns a 64-bit number that should be placed into the significand of the
188 NaN being returned.
189
190 (This returns the low 64 bits of the number represented by the numeral in
191 tagp, and the appropriate number of low bits should be copied into the
192 NaN.)
193
194 If tagp does not consist of a recognized numeral, zero is returned.
195*/
196static uint_least64_t ConstructSignificand(const char *tagp)
197{
198 if (tagp == NULL)
199 return 0;
200
201 // Determine the numeral base from the leading characters.
202 if (*tagp == '0')
203 {
204 ++tagp; // Consume the zero.
205 if (*tagp == 'x' || *tagp == 'X')
206 {
207 ++tagp; // Consume the x.
208
209 /* "0x" or "0X" indicates hexadecimal.
210
211 For each hexadecimal digit, shift the significand left and
212 insert the new digit on the right. If any character other
213 than a hexadecimal digit is encountered, return zero.
214
215 Observe that "0x" is accepted as a hexadecimal numeral, but it
216 returns 0, the same value we use for rejected strings. If the
217 value returned for rejected strings changes, the code here has
218 to check whether there is at least one digit.
219 */
220 char c;
221 uint_least64_t significand = 0;
222 while (c = *tagp++)
223 if ('0' <= c && c <= '9')
224 significand = significand<<4 | c - '0';
225 else if ('a' <= c && c <= 'f')
226 significand = significand<<4 | c - 'a' + 0xa;
227 else if ('A' <= c && c <= 'F')
228 significand = significand<<4 | c - 'A' + 0xa;
229 else
230 return 0;
231 return significand;
232 }
233 else
234 {
235 /* "0" without "x" or "X" indicates octal.
236
237 For each octal digit, shift the significand left and insert the
238 new digit on the right. If any character other than an octal
239 digit is encountered, return zero.
240 */
241 char c;
242 uint_least64_t significand = 0;
243 while (c = *tagp++)
244 if ('0' <= c && c <= '7')
245 significand = significand<<3 | c - '0';
246 else
247 return 0;
248 return significand;
249 }
250 }
251 else
252 {
253 /* For each decimal digit, multiply the value by ten and add the
254 new digit. If any character other than a decimal digit is
255 encountered, return zero.
256 */
257 char c;
258 uint_least64_t significand = 0;
259 while (c = *tagp++)
260 if ('0' <= c && c <= '9')
261 significand = significand*10 + c - '0';
262 else
263 return 0;
264 return significand;
265 }
266}