1/* Test of splitting a double into fraction and mantissa. 2 Copyright (C) 2007-2010 Free Software Foundation, Inc. 3 4 This program is free software: you can redistribute it and/or modify 5 it under the terms of the GNU General Public License as published by 6 the Free Software Foundation; either version 3 of the License, or 7 (at your option) any later version. 8 9 This program is distributed in the hope that it will be useful, 10 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 GNU General Public License for more details. 13 14 You should have received a copy of the GNU General Public License 15 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 16 17/* Written by Bruno Haible <bruno@clisp.org>, 2007. */ 18 19#include <config.h> 20 21#include "printf-frexp.h" 22 23#include <float.h> 24 25#include "macros.h" 26 27static double 28my_ldexp (double x, int d) 29{ 30 for (; d > 0; d--) 31 x *= 2.0; 32 for (; d < 0; d++) 33 x *= 0.5; 34 return x; 35} 36 37int 38main () 39{ 40 int i; 41 /* The use of 'volatile' guarantees that excess precision bits are dropped 42 when dealing with denormalized numbers. It is necessary on x86 systems 43 where double-floats are not IEEE compliant by default, to avoid that the 44 results become platform and compiler option dependent. 'volatile' is a 45 portable alternative to gcc's -ffloat-store option. */ 46 volatile double x; 47 48 for (i = 1, x = 1.0; i <= DBL_MAX_EXP; i++, x *= 2.0) 49 { 50 int exp = -9999; 51 double mantissa = printf_frexp (x, &exp); 52 ASSERT (exp == i - 1); 53 ASSERT (mantissa == 1.0); 54 } 55 for (i = 1, x = 1.0; i >= DBL_MIN_EXP; i--, x *= 0.5) 56 { 57 int exp = -9999; 58 double mantissa = printf_frexp (x, &exp); 59 ASSERT (exp == i - 1); 60 ASSERT (mantissa == 1.0); 61 } 62 for (; i >= DBL_MIN_EXP - 100 && x > 0.0; i--, x *= 0.5) 63 { 64 int exp = -9999; 65 double mantissa = printf_frexp (x, &exp); 66 ASSERT (exp == DBL_MIN_EXP - 1); 67 ASSERT (mantissa == my_ldexp (1.0, i - DBL_MIN_EXP)); 68 } 69 70 for (i = 1, x = 1.01; i <= DBL_MAX_EXP; i++, x *= 2.0) 71 { 72 int exp = -9999; 73 double mantissa = printf_frexp (x, &exp); 74 ASSERT (exp == i - 1); 75 ASSERT (mantissa == 1.01); 76 } 77 for (i = 1, x = 1.01; i >= DBL_MIN_EXP; i--, x *= 0.5) 78 { 79 int exp = -9999; 80 double mantissa = printf_frexp (x, &exp); 81 ASSERT (exp == i - 1); 82 ASSERT (mantissa == 1.01); 83 } 84 for (; i >= DBL_MIN_EXP - 100 && x > 0.0; i--, x *= 0.5) 85 { 86 int exp = -9999; 87 double mantissa = printf_frexp (x, &exp); 88 ASSERT (exp == DBL_MIN_EXP - 1); 89 ASSERT (mantissa >= my_ldexp (1.0, i - DBL_MIN_EXP)); 90 ASSERT (mantissa <= my_ldexp (2.0, i - DBL_MIN_EXP)); 91 ASSERT (mantissa == my_ldexp (x, - exp)); 92 } 93 94 for (i = 1, x = 1.73205; i <= DBL_MAX_EXP; i++, x *= 2.0) 95 { 96 int exp = -9999; 97 double mantissa = printf_frexp (x, &exp); 98 ASSERT (exp == i - 1); 99 ASSERT (mantissa == 1.73205); 100 } 101 for (i = 1, x = 1.73205; i >= DBL_MIN_EXP; i--, x *= 0.5) 102 { 103 int exp = -9999; 104 double mantissa = printf_frexp (x, &exp); 105 ASSERT (exp == i - 1); 106 ASSERT (mantissa == 1.73205); 107 } 108 for (; i >= DBL_MIN_EXP - 100 && x > 0.0; i--, x *= 0.5) 109 { 110 int exp = -9999; 111 double mantissa = printf_frexp (x, &exp); 112 ASSERT (exp == DBL_MIN_EXP - 1); 113 ASSERT (mantissa >= my_ldexp (1.0, i - DBL_MIN_EXP)); 114 ASSERT (mantissa <= my_ldexp (2.0, i - DBL_MIN_EXP)); 115 ASSERT (mantissa == my_ldexp (x, - exp)); 116 } 117 118 return 0; 119} 120