1/* 2 * Copyright (c) 2010 Apple Inc. All rights reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. Neither the name of Apple Inc. ("Apple") nor the names of its 16 * contributors may be used to endorse or promote products derived from 17 * this software without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY 20 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY 23 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 26 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 * 30 * Portions of this software have been released under the following terms: 31 * 32 * (c) Copyright 1989-1993 OPEN SOFTWARE FOUNDATION, INC. 33 * (c) Copyright 1989-1993 HEWLETT-PACKARD COMPANY 34 * (c) Copyright 1989-1993 DIGITAL EQUIPMENT CORPORATION 35 * 36 * To anyone who acknowledges that this file is provided "AS IS" 37 * without any express or implied warranty: 38 * permission to use, copy, modify, and distribute this file for any 39 * purpose is hereby granted without fee, provided that the above 40 * copyright notices and this notice appears in all source code copies, 41 * and that none of the names of Open Software Foundation, Inc., Hewlett- 42 * Packard Company or Digital Equipment Corporation be used 43 * in advertising or publicity pertaining to distribution of the software 44 * without specific, written prior permission. Neither Open Software 45 * Foundation, Inc., Hewlett-Packard Company nor Digital 46 * Equipment Corporation makes any representations about the suitability 47 * of this software for any purpose. 48 * 49 * Copyright (c) 2007, Novell, Inc. All rights reserved. 50 * Redistribution and use in source and binary forms, with or without 51 * modification, are permitted provided that the following conditions 52 * are met: 53 * 54 * 1. Redistributions of source code must retain the above copyright 55 * notice, this list of conditions and the following disclaimer. 56 * 2. Redistributions in binary form must reproduce the above copyright 57 * notice, this list of conditions and the following disclaimer in the 58 * documentation and/or other materials provided with the distribution. 59 * 3. Neither the name of Novell Inc. nor the names of its contributors 60 * may be used to endorse or promote products derived from this 61 * this software without specific prior written permission. 62 * 63 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 64 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 65 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 66 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY 67 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 68 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 69 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 70 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 71 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 72 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 73 * 74 * @APPLE_LICENSE_HEADER_END@ 75 */ 76 77#if HAVE_CONFIG_H 78#include <config.h> 79#endif 80 81/* 82** 83** NAME: 84** 85** round.c.h 86** 87** FACILITY: 88** 89** IDL Stub Runtime Support 90** 91** ABSTRACT: 92** 93** This module is an include file. 94** 95** This module rounds CVT floating point data to any specified position. 96** Any of the following rounding modes can be applied: 97** 98** Note: None of the following implementations ever perform true truncation 99** on their values. Whenever truncation becomes necessary - either 100** by being specified directly or by being required indirectly 101** through rounding - values are actually left untouched. Users 102** of this routine must zero out fractional fields themselves if 103** true truncation is needed. 104** 105** VAX ROUNDING 106** 107** Input data are rounded such that the representable value nearest 108** the infinitely precise result is delivered; if two representable 109** values are equally near, the one greatest in magnitude is 110** delivered. 111** 112** ROUND TO NEAREST 113** 114** Input data are rounded such that the representable value nearest 115** the infinitely precise result is delivered; if two representable 116** values are equally near, the one with its least significant bit 117** zero is delivered. 118** 119** ROUND TO POSITIVE INFINITY 120** 121** Input data are rounded such that the representable value closest 122** to and no less than the infinitely precise result is delivered. 123** 124** ROUND TO NEGATIVE INFINITY 125** 126** Input data are rounded such that the representable value closest 127** to and no greater than the infinitely precise result is 128** delivered. 129** 130** TRUNCATION (ROUND TOWARDS ZERO) 131** 132** True truncation is not implemented here. Input values are 133** delivered in their original, untouched form. 134** 135** A definition of "true" truncation follows: Truncation, or 136** rounding towards zero, implies input data are rounded such 137** that the representable value closest to and no greater in 138** magnitude than the infinitely precise result is delivered. 139** 140** VERSION: DCE 1.0 141** 142*/ 143 144/* 145** 146** Implicit input/output: 147** 148** r On input, a valid CVT floating point number. 149** On output, a rounded representation of the 150** input. 151** 152** 153** Implicit input: 154** 155** round_bit_position An integer specifying the position to round to. 156** 0 <= round_bit_position <= 127. 157** 158** Note: Valid CVT mantissa bits are addressed as 1 159** through 128. Accordingly, specifying 0 as a 160** position to round to implies an exponent 161** increase whenever rounding occurs. As for 162** truncation: truncation allways leaves a CVT 163** number untouched. 164** 165** options A valid CVT options bit mask in which at least 166** one, and only one, CVT rounding mode is 167** specified. If no rounding mode is specified, 168** results are unpredictable. Rounding is 169** performed in accordance with this mask. 170** 171** i An uninitialized integer used for indexing. 172** 173** 174** Note: for efficiency this routine performs no explicit error checking. 175** 176*/ 177 178{ 179 int roundup, more_bits; 180 unsigned32 bit_mask; 181 182 /* Check TRUNCATE option */ 183 184 if ( ! (options & CVT_C_TRUNCATE) ) { 185 186 /* Determine which word the round bit resides in */ 187 188 i = (round_bit_position >> 5) + 1; 189 190 /* Create a mask isolating the round bit */ 191 192 bit_mask = 0x1 << (31 - (round_bit_position & 0x1FL)); 193 194 /* Check VAX ROUNDING option */ 195 196 if (options & CVT_C_VAX_ROUNDING) 197 roundup = r[i] & bit_mask; 198 199 else { 200 roundup = 0; 201 switch ( r[i] & bit_mask ) { 202 203 /* If round bit is clear, and ROUND TO NEAREST option */ 204 /* is selected we truncate */ 205 206 case 0 : if (options & CVT_C_ROUND_TO_NEAREST) 207 break; 208 209 /* Otherwise, make note of wheather there are any bits set */ 210 /* after the round bit, and then check the remaining cases */ 211 212 default : if ( ! (more_bits = r[i] & (bit_mask - 1)) ) 213 switch ( i ) { 214 case 1 : more_bits = r[2]; 215 case 2 : more_bits |= r[3]; 216 case 3 : more_bits |= r[4]; 217 default : break; 218 } 219 220 /* Re-check ROUND TO NEAREST option. NOTE: if we've reached */ 221 /* this point and ROUND TO NEAREST has been selected, the */ 222 /* round bit is set. */ 223 224 if (options & CVT_C_ROUND_TO_NEAREST) { 225 if ( ! ( roundup = more_bits ) ) 226 { 227 if ( bit_mask << 1 ) 228 roundup = r[i] & (bit_mask << 1); 229 else if (i != 1) 230 roundup = r[i-1] & 1; 231 } 232 233 /* Check ROUND TO POSITIVE INFINITY option */ 234 235 } else if (options & CVT_C_ROUND_TO_POS) { 236 if ( !(r[U_R_FLAGS] & U_R_NEGATIVE) ) 237 roundup = (r[i] & bit_mask) | more_bits; 238 239 /* Check ROUND TO NEGITIVE INFINITY option */ 240 241 } else if (r[U_R_FLAGS] & U_R_NEGATIVE) 242 roundup = (r[i] & bit_mask) | more_bits; 243 } 244 } 245 246 if ( roundup ) { /* Perform rounding if necessary */ 247 248 /* Add 1 at round position */ 249 250 bit_mask <<= 1; 251 r[i] = (r[i] & ~(bit_mask - 1)) + bit_mask; 252 253 /* Propagate any carry */ 254 255 while ( ! r[i] ) 256 r[--i] += 1; 257 258 /* If carry reaches exponent MSB gets zeroed and must be reset */ 259 260 if ( ! i ) 261 r[1] = 0x80000000L; 262 } 263 } 264} 265