this repo has no description
at fixPythonPipStalling 113 lines 2.1 kB view raw
1/* 2 * nextafterf.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 18float nextafterf( float x, float y ) 19{ 20 union{ float f; uint32_t u;} ux = { x }; 21 uint32_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 = -1; 32 } 33 34 //correct for the sign 35 int32_t signMask = (int32_t) ux.u >> 31; 36 step = (step ^ signMask) - signMask; 37 38 uint32_t absux = ux.u & 0x7fffffffU; 39 40 if( absux - 0x00800001U >= 0x7f7fffffU - 0x00800001U ) 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 == 0 ) // zero 46 { 47 ux.f = y; 48 required_multiply_float( 0x1.0p-120f, 0x1.0p-120f ); 49 ux.u = (ux.u & 0x80000000U) + 1U; 50 return ux.f; 51 } 52 else if( absux == 0x7f7fffffU ) // max finite 53 { 54 ux.u += step; 55 56 //if infinity is the result, set some flags 57 if( 0 == (ux.u & 2) ) 58 { 59 required_add_float( x, 1.0f ); //set inexact 60 required_multiply_float( x, x ); //set overflow 61 } 62 63 return ux.f; 64 } 65 66 ux.u += step; 67 if( 0 == (ux.u & 0x7f800000)) 68 required_multiply_float( 0x1.0p-120f, 0x1.0p-120f ); 69 70 return ux.f; 71 } 72 73 ux.u += step; 74 75 return ux.f; 76} 77 78#else 79 80float nextafterf( float x, float y ) 81{ 82 union{ float f; uint32_t u;} ux = { x }; 83 uint32_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 = -1; 94 } 95 96 //correct for the sign 97 int32_t signMask = (int32_t) ux.u >> 31; 98 step = (step ^ signMask) - signMask; 99 100 uint32_t absux = ux.u & 0x7fffffffU; 101 102 if( absux == 0 ) // zero 103 { 104 ux.f = y; 105 ux.u = (ux.u & 0x80000000U) + 1U; 106 return ux.f; 107 } 108 109 ux.u += step; 110 return ux.f; 111} 112 113#endif // ARMLIBM_SET_FLAGS