GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: lib/libm/src/s_nextafter.c Lines: 22 35 62.9 %
Date: 2017-11-07 Branches: 18 44 40.9 %

Line Branch Exec Source
1
/* @(#)s_nextafter.c 5.1 93/09/24 */
2
/*
3
 * ====================================================
4
 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
5
 *
6
 * Developed at SunPro, a Sun Microsystems, Inc. business.
7
 * Permission to use, copy, modify, and distribute this
8
 * software is freely granted, provided that this notice
9
 * is preserved.
10
 * ====================================================
11
 */
12
13
/* IEEE functions
14
 *	nextafter(x,y)
15
 *	return the next machine floating-point number of x in the
16
 *	direction toward y.
17
 *   Special cases:
18
 */
19
20
#include <float.h>
21
#include <math.h>
22
23
#include "math_private.h"
24
25
double
26
nextafter(double x, double y)
27
{
28
	int32_t hx,hy,ix,iy;
29
	u_int32_t lx,ly;
30
31
90
	EXTRACT_WORDS(hx,lx,x);
32
45
	EXTRACT_WORDS(hy,ly,y);
33
45
	ix = hx&0x7fffffff;		/* |x| */
34
45
	iy = hy&0x7fffffff;		/* |y| */
35
36

70
	if(((ix>=0x7ff00000)&&((ix-0x7ff00000)|lx)!=0) ||   /* x is nan */
37
50
	   ((iy>=0x7ff00000)&&((iy-0x7ff00000)|ly)!=0))     /* y is nan */
38
15
	   return x+y;
39
50
	if(x==y) return y;		/* x=y, return y */
40
10
	if((ix|lx)==0) {			/* x == 0 */
41
	    INSERT_WORDS(x,hy&0x80000000,1);	/* return +-minsubnormal */
42
	    y = x*x;
43
	    if(y==x) return y; else return x;	/* raise underflow flag */
44
	}
45
10
	if(hx>=0) {				/* x > 0 */
46

15
	    if(hx>hy||((hx==hy)&&(lx>ly))) {	/* x > y, x -= ulp */
47
10
		if(lx==0) hx -= 1;
48
5
		lx -= 1;
49
5
	    } else {				/* x < y, x += ulp */
50
5
		lx += 1;
51
10
		if(lx==0) hx += 1;
52
	    }
53
	} else {				/* x < 0 */
54
	    if(hy>=0||hx>hy||((hx==hy)&&(lx>ly))){/* x < y, x -= ulp */
55
		if(lx==0) hx -= 1;
56
		lx -= 1;
57
	    } else {				/* x > y, x += ulp */
58
		lx += 1;
59
		if(lx==0) hx += 1;
60
	    }
61
	}
62
10
	hy = hx&0x7ff00000;
63
10
	if(hy>=0x7ff00000) return x+x;	/* overflow  */
64
10
	if(hy<0x00100000) {		/* underflow */
65
	    y = x*x;
66
	    if(y!=x) {		/* raise underflow flag */
67
	        INSERT_WORDS(y,hx,lx);
68
		return y;
69
	    }
70
	}
71
10
	INSERT_WORDS(x,hx,lx);
72
10
	return x;
73
45
}
74
DEF_STD(nextafter);
75
LDBL_MAYBE_CLONE(nextafter);
76
77
#if	LDBL_MANT_DIG == DBL_MANT_DIG
78
MAKE_UNUSED_CLONE(nexttoward, nextafter);
79
MAKE_UNUSED_CLONE(nexttowardl, nextafter);
80
#endif	/* LDBL_MANT_DIG == DBL_MANT_DIG */