~xnox/ubuntu/trusty/gcc-arm-linux-androideabi/dima

« back to all changes in this revision

Viewing changes to android/bionic/libm/src/s_nexttoward.c

  • Committer: Package Import Robot
  • Author(s): Dmitrijs Ledkovs
  • Date: 2013-07-05 10:12:24 UTC
  • Revision ID: package-import@ubuntu.com-20130705101224-6qo3e8jbz8p31aa1
Tags: upstream-0.20130705.1
ImportĀ upstreamĀ versionĀ 0.20130705.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
#ifndef lint
 
14
static char rcsid[] = "$FreeBSD: src/lib/msun/src/s_nexttoward.c,v 1.1 2005/03/07 04:56:46 das Exp $";
 
15
#endif
 
16
 
 
17
/*
 
18
 * We assume that a long double has a 15-bit exponent.  On systems
 
19
 * where long double is the same as double, nexttoward() is an alias
 
20
 * for nextafter(), so we don't use this routine.
 
21
 */
 
22
 
 
23
#include <float.h>
 
24
 
 
25
#include "fpmath.h"
 
26
#include "math.h"
 
27
#include "math_private.h"
 
28
 
 
29
#if LDBL_MAX_EXP != 0x4000
 
30
#error "Unsupported long double format"
 
31
#endif
 
32
 
 
33
double
 
34
nexttoward(double x, long double y)
 
35
{
 
36
        union IEEEl2bits uy;
 
37
        volatile double t;
 
38
        int32_t hx,ix;
 
39
        u_int32_t lx;
 
40
 
 
41
        EXTRACT_WORDS(hx,lx,x);
 
42
        ix = hx&0x7fffffff;             /* |x| */
 
43
        uy.e = y;
 
44
 
 
45
        if(((ix>=0x7ff00000)&&((ix-0x7ff00000)|lx)!=0) ||
 
46
            (uy.bits.exp == 0x7fff &&
 
47
             ((uy.bits.manh&~LDBL_NBIT)|uy.bits.manl) != 0))
 
48
           return x+y;  /* x or y is nan */
 
49
        if(x==y) return (double)y;              /* x=y, return y */
 
50
        if(x==0.0) {
 
51
            INSERT_WORDS(x,uy.bits.sign<<31,1); /* return +-minsubnormal */
 
52
            t = x*x;
 
53
            if(t==x) return t; else return x;   /* raise underflow flag */
 
54
        }
 
55
        if(hx>0.0 ^ x < y) {                    /* x -= ulp */
 
56
            if(lx==0) hx -= 1;
 
57
            lx -= 1;
 
58
        } else {                                /* x += ulp */
 
59
            lx += 1;
 
60
            if(lx==0) hx += 1;
 
61
        }
 
62
        ix = hx&0x7ff00000;
 
63
        if(ix>=0x7ff00000) return x+x;  /* overflow  */
 
64
        if(ix<0x00100000) {             /* underflow */
 
65
            t = x*x;
 
66
            if(t!=x) {          /* raise underflow flag */
 
67
                INSERT_WORDS(y,hx,lx);
 
68
                return y;
 
69
            }
 
70
        }
 
71
        INSERT_WORDS(x,hx,lx);
 
72
        return x;
 
73
}