nexttowardf.c
1 /* 2 * Copyright (C) 2008-2020 Advanced Micro Devices, Inc. All rights reserved. 3 * Redistribution and use in source and binary forms, with or without modification, 4 * are permitted provided that the following conditions are met: 5 * 1. Redistributions of source code must retain the above copyright notice, 6 * this list of conditions and the following disclaimer. 7 * 2. Redistributions in binary form must reproduce the above copyright notice, 8 * this list of conditions and the following disclaimer in the documentation 9 * and/or other materials provided with the distribution. 10 * 3. Neither the name of the copyright holder nor the names of its contributors 11 * may be used to endorse or promote products derived from this software without 12 * specific prior written permission. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 16 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 17 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 18 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 19 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 20 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 21 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 23 * POSSIBILITY OF SUCH DAMAGE. 24 * 25 */ 26 27 #include "libm_amd.h" 28 #include "libm_util_amd.h" 29 #include "libm_special.h" 30 31 32 float FN_PROTOTYPE_REF(nexttowardf)(float x, long double y) 33 { 34 35 36 UT32 checkbits; 37 long double dy = (long double) y; 38 checkbits.f32=x; 39 40 41 42 /* check if the number is nan */ 43 if(((checkbits.u32 & ~SIGNBIT_SP32) > EXPBITS_SP32 )) 44 { 45 #ifdef WINDOWS 46 return __amd_handle_errorf("nexttoward", __amd_nexttoward, checkbits.u32| QNAN_MASK_32, _DOMAIN, AMD_F_NONE, EDOM, x, 0.0, 1); 47 #else 48 if (checkbits.u32 & QNAN_MASK_32) 49 return __amd_handle_errorf("nexttoward", __amd_nexttoward, checkbits.u32| QNAN_MASK_32, _DOMAIN, AMD_F_NONE, EDOM, x, 0.0, 1); 50 else 51 return __amd_handle_errorf("nexttoward", __amd_nexttoward, checkbits.u32| QNAN_MASK_32, _DOMAIN, AMD_F_INVALID, EDOM, x, 0.0, 1); 52 #endif 53 } 54 55 56 /* if x == y return y in the type of x */ 57 if( x == dy ) 58 { 59 return (float) dy; 60 } 61 62 if( x == 0.0) 63 { 64 checkbits.u32 = 1; 65 if( dy > 0.0 ) 66 return checkbits.f32; 67 else 68 return -checkbits.f32; 69 } 70 71 72 /* compute the next heigher or lower value */ 73 if(((x>0.0F) ^ (dy>x)) == 0) 74 { 75 checkbits.u32++; 76 } 77 else 78 { 79 checkbits.u32--; 80 } 81 82 /* check if the result is nan or inf */ 83 if(((checkbits.u32 & ~SIGNBIT_SP32) >= EXPBITS_SP32 )) 84 { 85 return __amd_handle_errorf("nexttowardf", __amd_nexttoward, checkbits.u32 | QNAN_MASK_32, _DOMAIN,0, EDOM, x, 0.0, 1); 86 } 87 88 return checkbits.f32; 89 } 90