this repo has no description
at fixPythonPipStalling 207 lines 6.0 kB view raw
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#include <machine/endian.h> 78 79 80// Define the type Float to access the representation of a float. 81typedef union 82{ 83 float f; 84 struct 85 { 86 #if defined __BIG_ENDIAN__ 87 unsigned int sign : 1; 88 unsigned int exponent : 8; 89 unsigned int quiet : 1; 90 unsigned int significand : 22; 91 #else 92 unsigned int significand : 22; 93 unsigned int quiet : 1; 94 unsigned int exponent : 8; 95 unsigned int sign : 1; 96 #endif 97 } s; 98} Float; 99 100 101// Define the type Double to access the representation of a double. 102typedef union 103{ 104 double d; 105 struct 106 { 107 #if defined __BIG_ENDIAN__ 108 unsigned int sign : 1; 109 unsigned int exponent : 11; 110 unsigned int quiet : 1; 111 uint64_t significand : 51; 112 #else 113 uint64_t significand : 51; 114 unsigned int quiet : 1; 115 unsigned int exponent : 11; 116 unsigned int sign : 1; 117 #endif 118 } s; 119} Double; 120 121 122// Long double and double are the same in cLibm 123typedef Double LongDouble; 124 125/* ConstructSignificand parses the tagp argument of nanf, nan, or nanl and 126 returns a 64-bit number that should be placed into the significand of the 127 NaN being returned. 128 129 (This returns the low 64 bits of the number represented by the numeral in 130 tagp, and the appropriate number of low bits should be copied into the 131 NaN.) 132 133 If tagp does not consist of a recognized numeral, zero is returned. 134*/ 135static uint_least64_t ConstructSignificand(const char *tagp) 136{ 137 if (tagp == NULL) 138 return 0; 139 140 // Determine the numeral base from the leading characters. 141 if (*tagp == '0') 142 { 143 ++tagp; // Consume the zero. 144 if (*tagp == 'x' || *tagp == 'X') 145 { 146 ++tagp; // Consume the x. 147 148 /* "0x" or "0X" indicates hexadecimal. 149 150 For each hexadecimal digit, shift the significand left and 151 insert the new digit on the right. If any character other 152 than a hexadecimal digit is encountered, return zero. 153 154 Observe that "0x" is accepted as a hexadecimal numeral, but it 155 returns 0, the same value we use for rejected strings. If the 156 value returned for rejected strings changes, the code here has 157 to check whether there is at least one digit. 158 */ 159 char c; 160 uint_least64_t significand = 0; 161 while (0 != (c = *tagp++)) 162 { 163 if ('0' <= c && c <= '9') 164 significand = (significand<<4) | (c - '0'); 165 else if ('a' <= c && c <= 'f') 166 significand = (significand<<4) | (c - 'a' + 0xa); 167 else if ('A' <= c && c <= 'F') 168 significand = (significand<<4) | (c - 'A' + 0xa); 169 else 170 return 0; 171 } 172 return significand; 173 } 174 else 175 { 176 /* "0" without "x" or "X" indicates octal. 177 178 For each octal digit, shift the significand left and insert the 179 new digit on the right. If any character other than an octal 180 digit is encountered, return zero. 181 */ 182 char c; 183 uint_least64_t significand = 0; 184 while (0 != (c = *tagp++)) 185 if ('0' <= c && c <= '7') 186 significand = (significand<<3) | (c - '0'); 187 else 188 return 0; 189 return significand; 190 } 191 } 192 else 193 { 194 /* For each decimal digit, multiply the value by ten and add the 195 new digit. If any character other than a decimal digit is 196 encountered, return zero. 197 */ 198 char c; 199 uint_least64_t significand = 0; 200 while (0 != (c = *tagp++)) 201 if ('0' <= c && c <= '9') 202 significand = significand*10 + c - '0'; 203 else 204 return 0; 205 return significand; 206 } 207}