|
|
1 //! @file a68g-conversion.c 2 //! @author J. Marcel van der Veer 3 4 //! @section Copyright 5 //! 6 //! This file is part of Algol68G - an Algol 68 compiler-interpreter. 7 //! Copyright 2001-2026 J. Marcel van der Veer [algol68g@algol68genie.nl]. 8 9 //! @section License 10 //! 11 //! This program is free software; you can redistribute it and/or modify it 12 //! under the terms of the GNU General Public License as published by the 13 //! Free Software Foundation; either version 3 of the License, or 14 //! (at your option) any later version. 15 //! 16 //! This program is distributed in the hope that it will be useful, but 17 //! WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 18 //! or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 19 //! more details. You should have received a copy of the GNU General Public 20 //! License along with this program. If not, see [http://www.gnu.org/licenses/]. 21 22 //! @section Synopsis 23 //! 24 //! Conversion tables for IEEE platforms. 25 26 #include "a68g.h" 27 #include "a68g-prelude.h" 28 29 // A list of 10 ^ 2 ^ n for conversion purposes on IEEE 754 platforms. 30 31 #if (A68G_LEVEL >= 3) 32 33 //! @brief 10 ** expo 34 35 DOUBLE_T ten_up_double (int expo) 36 { 37 static DOUBLE_T pow_10_double[] = { 38 10.0q, 100.0q, 1.0e4q, 1.0e8q, 1.0e16q, 1.0e32q, 1.0e64q, 1.0e128q, 1.0e256q, 1.0e512q, 1.0e1024q, 1.0e2048q, 1.0e4096q 39 }; 40 // This appears sufficiently accurate. 41 if (expo == 0) { 42 return 1.0q; 43 } 44 BOOL_T neg_expo = (BOOL_T) (expo < 0); 45 if (neg_expo) { 46 expo = -expo; 47 } 48 if (expo > MAX_DOUBLE_EXPO) { 49 expo = 0; 50 errno = EDOM; 51 } 52 ABEND (expo > MAX_DOUBLE_EXPO, ERROR_INVALID_VALUE, NO_TEXT); 53 DOUBLE_T dbl_expo = 1.0q; 54 for (DOUBLE_T *dep = pow_10_double; expo != 0; expo >>= 1, dep++) { 55 if (expo & 0x1) { 56 dbl_expo *= *dep; 57 } 58 } 59 return neg_expo ? 1.0q / dbl_expo : dbl_expo; 60 } 61 62 #endif 63 64 //! @brief 10 ** expo 65 66 REAL_T ten_up (int expo) 67 { 68 static REAL_T pow_10[] = { 69 10.0, 100.0, 1.0e4, 1.0e8, 1.0e16, 1.0e32, 1.0e64, 1.0e128, 1.0e256 70 }; 71 // This appears sufficiently accurate. 72 BOOL_T neg_expo = (BOOL_T) (expo < 0); 73 if (neg_expo) { 74 expo = -expo; 75 } 76 ABEND (expo > MAX_REAL_EXPO, ERROR_INVALID_VALUE, NO_TEXT); 77 REAL_T dbl_expo = 1.0; 78 for (REAL_T *dep = pow_10; expo != 0; expo >>= 1, dep++) { 79 if (expo & 0x1) { 80 dbl_expo *= *dep; 81 } 82 } 83 return neg_expo ? 1 / dbl_expo : dbl_expo; 84 }
© 2001-2026 J.M. van der Veer
jmvdveer@algol68genie.nl