/**************************************************************************** * Core Library Version 1.7, August 2004 * Copyright (c) 1995-2004 Exact Computation Project * All rights reserved. * * This file is part of CORE (http://cs.nyu.edu/exact/core/); you may * redistribute it under the terms of the Q Public License version 1.0. * See the file LICENSE.QPL distributed with CORE. * * Licensees holding a valid commercial license may use this file in * accordance with the commercial license agreement provided with the * software. * * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. * * * File: CoreAux.cpp * Synopsis: * Auxiliary routines such as ceiling of log_2, etc. * they are not specific to any Core classes. * * Written by * Chee Yap * Chen Li * Zilin Du * * WWW URL: http://cs.nyu.edu/exact/ * Email: exact@cs.nyu.edu * * $URL$ * $Id$ ***************************************************************************/ #include "CGAL/CORE/CoreAux.h" #include CORE_BEGIN_NAMESPACE //////////////////////////////////////////////////////////// // More useful functions to implement: // // To convert digits into bits: // given X, compute X * log_2(10) // To convert bits into digits: // given X, compute X * log_10(2) // //////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////// // flrLg(x) // returns floor log base 2 of abs(x) // CONVENTION lg(0) = -1 (Slight improvement, Zilin/Chee 8/5/02) //////////////////////////////////////////////////////////// int flrLg(long x) { if (x == LONG_MIN) { // special treatment as -LONG_MIN would be not representable as "long" return LONG_BIT - 1; } else { // 1 <= |x| <= LONG_MAX if (x < 0) x = - x; int lg = -1; while (x > 0) { lg++; x >>= 1; } return lg; } } //////////////////////////////////////////////////////////// // floor log base 2 of unsigned long x // CONVENTION lg(0) = -1 (Slight improvement, Zilin/Chee 8/5/02) //////////////////////////////////////////////////////////// int flrLg(unsigned long x) { int lg = -1; while (x > 0) { lg++; x >>= 1; } return lg; } //////////////////////////////////////////////////////////// // ceiling log base 2 of abs(x) // CONVENTION lg(0) = -1 (Slight improvement, Zilin/Chee 8/5/02) //////////////////////////////////////////////////////////// int clLg(long x) { if (x == LONG_MIN) return LONG_BIT - 1; if (x < 0) x = -x; // use absolute value if (x > (LONG_MAX >> 1)) // the leading data bit is 1 return (LONG_BIT - 1); // exclude the sign bit if (x >= 2) return flrLg((unsigned long)((x << 1) - 1)); // SINCE ceilLog_2(x) = floorLog_2(2x-1) for x>=2 if (x == 1) return 0; return -1; // x must be 0 here } //////////////////////////////////////////////////////////// // ceiling log base 2 of unsigned long x // CONVENTION lg(0) = -1 //////////////////////////////////////////////////////////// int clLg(unsigned long x) { if (x > (ULONG_MAX >> 1)) // the leading bit is 1 return LONG_BIT; if (x >= 2) return flrLg((x << 1) - 1); // SINCE ceilLog_2(x) = floorLog_2(2x-1) for x>=2. if (x == 1) return 0; return -1; // x must be equal to 0 } /// gcd for machine type long /** This is needed when we construct Polynomials with int or long coefficients */ long gcd(long m, long n) { if (m == 0) return core_abs(n); if (n == 0) return core_abs(m); long p = core_abs(m); long q = core_abs(n); if (p0) { long r = p % q; p = q; q = r; } return p; } // return a gmp_randstate_t structure gmp_randstate_t* getRandstate() { static gmp_randstate_t rstate; static bool initialized = false; if (!initialized) { gmp_randinit(rstate, GMP_RAND_ALG_DEFAULT, 32L); initialized = true; } return &rstate; } // char* core_itoa(int n, char* buffer) // returns a pointer to the null-terminated string in buffer // NOTES: // 0. Buffer size should be 17 bytes (resp., 33 bytes, 65 bytes) on 16-bit // (resp., 32-bit, 64-bit) machines. Formula: 1+sizeof(int)*8 bytes. // 1. itoa(...) is available on some stdlib.h, but it is // not defined by ANSI-C and so not all compilers support it. // 2. Our use of sprintf(...) to do the job is known to // be inefficient, but this is hardly critical for our usage. // 3. A more general program should take a 3rd argument (the radix of // output number). We assume radix 10. char * core_itoa(int n, char* buffer) { std::sprintf(buffer, "%d", n); return buffer; } /// implements the "integer mantissa" function // (See CORE_PATH/progs/ieee/frexp.cpp for details) double IntMantissa(double d) { int e; return std::ldexp(std::frexp(d, &e), 53); } /// implements the "integer exponent" function // (See CORE_PATH/progs/ieee/frexp.cpp for details) int IntExponent(double d) { int e; std::frexp(d, &e); return e-53; } /// CORE_DIAGFILE is file name for core_error(..) output. const char* CORE_DIAGFILE = "Core_Diagnostics"; // global file name /// core_error is the method to write Core Library warning or error messages /** Both warnings and errors are written to a file called CORE_DIAGFILE. * But errors are also written on std:cerr (similar to std::perror()). * */ // Usage: core_error(message, file_with_error, line_number, err_type) // where err_type=0 means WARNING, error_type=0 means ERROR void core_error(std::string msg, std::string file, int lineno, bool err) { std::ofstream outFile(CORE_DIAGFILE, std::ios::app); // open to append if (!outFile) { // perror("CORE ERROR: cannot open Core Diagnostics file"); std::cerr << "CORE ERROR: can't open Core Diagnostics file"<