GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: lib/libm/src/s_nexttowardf.c Lines: 0 35 0.0 %
Date: 2017-11-07 Branches: 0 36 0.0 %

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
 *	nexttowardf(x,y)
15
 *	return the next machine floating-point number of x in the
16
 *	direction toward y.
17
 * This is for machines which use the same binary type for double and
18
 * long double.
19
 *   Special cases:
20
 */
21
22
#include <math.h>
23
#include <float.h>
24
25
#include "math_private.h"
26
27
float
28
nexttowardf(float x, long double y)
29
{
30
	int32_t hx,hy,ix,iy;
31
	u_int32_t ly;
32
33
	GET_FLOAT_WORD(hx,x);
34
	EXTRACT_WORDS(hy,ly,y);
35
	ix = hx&0x7fffffff;		/* |x| */
36
	iy = hy&0x7fffffff;		/* |y| */
37
38
	if((ix>0x7f800000) ||				   /* x is nan */
39
	   ((iy>=0x7ff00000)&&((iy-0x7ff00000)|ly)!=0))    /* y is nan */
40
	   return x+y;
41
	if((long double) x==y) return y;	/* x=y, return y */
42
	if(ix==0) {				/* x == 0 */
43
	    volatile float u;
44
	    SET_FLOAT_WORD(x,(u_int32_t)(hy&0x80000000)|1);/* return +-minsub*/
45
	    u = x;
46
	    u = u * u;				/* raise underflow flag */
47
	    return x;
48
	}
49
	if(hx>=0) {				/* x > 0 */
50
	    if(hy<0||(ix>>23)>(iy>>20)-0x380
51
	       || ((ix>>23)==(iy>>20)-0x380
52
		   && (ix&0x7fffff)>(((hy<<3)|(ly>>29))&0x7fffff)))	/* x > y, x -= ulp */
53
		hx -= 1;
54
	    else				/* x < y, x += ulp */
55
		hx += 1;
56
	} else {				/* x < 0 */
57
	    if(hy>=0||(ix>>23)>(iy>>20)-0x380
58
	       || ((ix>>23)==(iy>>20)-0x380
59
		   && (ix&0x7fffff)>(((hy<<3)|(ly>>29))&0x7fffff)))	/* x < y, x -= ulp */
60
		hx -= 1;
61
	    else				/* x > y, x += ulp */
62
		hx += 1;
63
	}
64
	hy = hx&0x7f800000;
65
	if(hy>=0x7f800000) {
66
	  x = x+x;	/* overflow  */
67
	  return x;
68
	}
69
	if(hy<0x00800000) {
70
	    volatile float u = x*x;		/* underflow */
71
	    if(u==x) {
72
		SET_FLOAT_WORD(x,hx);
73
		return x;
74
	    }
75
	}
76
	SET_FLOAT_WORD(x,hx);
77
	return x;
78
}