this repo has no description
at fixPythonPipStalling 113 lines 2.2 kB view raw
1/* 2 * nextafter.c 3 * cLibm 4 * 5 * Created by Ian Ollmann on 6/14/07. 6 * Copyright 2007 Apple Inc. All rights reserved. 7 * 8 */ 9 10#include <math.h> 11#include <stdint.h> 12 13#ifdef ARMLIBM_SET_FLAGS 14#include <fenv.h> 15#include "required_arithmetic.h" 16#pragma STDC FENV_ACCESS ON 17 18double nextafter( double x, double y ) 19{ 20 union{ double d; uint64_t u;} ux = { x }; 21 uint64_t step = 1; 22 23 if( y != y || x != x) 24 return x + y; 25 26 if( y <= x ) // a subtraction here would risk Inf-Inf 27 { 28 if( y == x ) 29 return y; //make sure sign of 0 is correct 30 31 step = -1LL; 32 } 33 34 //correct for the sign 35 int64_t signMask = (int64_t) ux.u >> 63; 36 step = (step ^ signMask) - signMask; 37 38 uint64_t absux = ux.u & 0x7fffffffffffffffULL; 39 40 if( absux - 0x0010000000000001ULL >= 0x7fefffffffffffffULL - 0x0010000000000001ULL ) 41 { //0, Inf, max finite, min normal, denorm 42 //Nan is handled above and won't occur here 43 //Inf can just fall through. We are only here if y!=x. 44 45 if( absux == 0ULL ) // zero 46 { 47 ux.d = y; 48 required_multiply_double( 0x1.0p-1000, 0x1.0p-1000 ); 49 ux.u = (ux.u & 0x8000000000000000ULL) + 1U; 50 return ux.d; 51 } 52 else if( absux == 0x7fefffffffffffffULL ) // max finite 53 { 54 ux.u += step; 55 56 //if infinity is the result, set some flags 57 if( 0 == (ux.u & 2ULL) ) 58 { 59 required_add_double( x, 1.0 ); //set inexact 60 required_multiply_double( x, x ); //set overflow 61 } 62 63 return ux.d; 64 } 65 66 ux.u += step; 67 if( 0ULL == (ux.u & 0x7ff0000000000000ULL)) 68 required_multiply_double( 0x1.0p-1000, 0x1.0p-1000 ); 69 70 return ux.d; 71 } 72 73 ux.u += step; 74 75 return ux.d; 76} 77 78#else 79 80double nextafter( double x, double y ) 81{ 82 union{ double d; uint64_t u;} ux = { x }; 83 uint64_t step = 1; 84 85 if( y != y || x != x) 86 return x + y; 87 88 if( y <= x ) // a subtraction here would risk Inf-Inf 89 { 90 if( y == x ) 91 return y; //make sure sign of 0 is correct 92 93 step = -1LL; 94 } 95 96 //correct for the sign 97 int64_t signMask = (int64_t) ux.u >> 63; 98 step = (step ^ signMask) - signMask; 99 100 uint64_t absux = ux.u & 0x7fffffffffffffffULL; 101 102 if( absux == 0ULL ) // zero 103 { 104 ux.d = y; 105 ux.u = (ux.u & 0x8000000000000000ULL) + 1U; 106 return ux.d; 107 } 108 109 ux.u += step; 110 return ux.d; 111} 112 113#endif // ARMLIBM_SET_FLAGS