this repo has no description
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
15#include <fenv.h>
16#include "required_arithmetic.h"
17#pragma STDC FENV_ACCESS ON
18
19float nexttowardf( float x, long double y )
20{
21 union{ float f; uint32_t u;} ux = { x };
22 uint32_t step = 1;
23
24 if( y != y || x != x)
25 return x + y;
26
27 if( y <= (long double) x ) // a subtraction here would risk Inf-Inf
28 {
29 if( y == x )
30 return (float) y; //make sure sign of 0 is correct
31
32 step = -1;
33 }
34
35 //correct for the sign
36 int32_t signMask = (int32_t) ux.u >> 31;
37 step = (step ^ signMask) - signMask;
38
39 uint32_t absux = ux.u & 0x7fffffffU;
40
41 if( absux - 0x00800001U >= 0x7f7fffffU - 0x00800001U )
42 { //0, Inf, max finite, min normal, denorm
43 //Nan is handled above and won't occur here
44 //Inf can just fall through. We are only here if y!=x.
45
46 if( absux == 0 ) // zero
47 {
48 ux.f = (float) y;
49 required_multiply_float( 0x1.0p-120f, 0x1.0p-120f );
50 ux.u = (ux.u & 0x80000000U) + 1U;
51 return ux.f;
52 }
53 else if( absux == 0x7f7fffffU ) // max finite
54 {
55 ux.u += step;
56
57 //if infinity is the result, set some flags
58 if( 0 == (ux.u & 2) )
59 {
60 required_add_float( x, 1.0f ); //set inexact
61 required_multiply_float( x, x ); //set overflow
62 }
63
64 return ux.f;
65 }
66
67 ux.u += step;
68 if( 0 == (ux.u & 0x7f800000))
69 required_multiply_float( 0x1.0p-120f, 0x1.0p-120f );
70
71 return ux.f;
72 }
73
74 ux.u += step;
75
76 return ux.f;
77}
78
79#else
80
81float nexttowardf( float x, long double y )
82{
83 union{ float f; uint32_t u;} ux = { x };
84 uint32_t step = 1;
85
86 if( y != y || x != x)
87 return x + y;
88
89 if( y <= (long double) x ) // a subtraction here would risk Inf-Inf
90 {
91 if( y == x )
92 return (float) y; //make sure sign of 0 is correct
93
94 step = -1;
95 }
96
97 //correct for the sign
98 int32_t signMask = (int32_t) ux.u >> 31;
99 step = (step ^ signMask) - signMask;
100
101 uint32_t absux = ux.u & 0x7fffffffU;
102
103 if( absux == 0 ) // zero
104 {
105 ux.f = (float) y;
106 ux.u = (ux.u & 0x80000000U) + 1U;
107 return ux.f;
108 }
109
110 ux.u += step;
111 return ux.f;
112}
113
114#endif
115