<commit_before>/*
 * Copyright (C) 2007 <NAME>, <NAME>
 * 
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 * 
 * As a special exception, you may use this file as part of a free
 * software library without restriction. Specifically, if other files
 * instantiate templates or use macros or inline functions from this
 * file, or you compile this file and link it with other files to
 * produce an executable, this file does not by itself cause the
 * resulting executable to be covered by the GNU General Public
 * License. This exception does not however invalidate any other
 * reasons why the executable file might be covered by the GNU Library
 * General Public License.
 * 
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */

#ifndef TNTDB_DECIMAL_H
#define TNTDB_DECIMAL_H

#include <string>
#include <iostream>
#include <sstream>
#include <stdexcept>
#include <stdint.h>

namespace tntdb
{
  /**
   * This class holds a decimal floating point number.  It is necessary to
   * convert it to some other type to perform arithmetic and other operations.
   * Decimal is implemented with a 64 bit unsigned integer mantissa, and a
   * 32 bit exponent.  For conversions from integer types, strings, and reading
   * from the database, Decimal tries to maintain accuracy if the result will
   * fit in the 64 bit unsigned mantissa and exponent.  When converting to
   * integer types, Decimal will throw std::overflow exception if the result
   * will not fit.  For converting to binary floating point numbers, binary
   * floating point is used in the conversion, and the result is an
   * approximation.
   */
  class Decimal
  {
  public:
    typedef uint64_t MantissaType;
    typedef int32_t ExponentType;
    typedef int8_t FlagsType;
    typedef int8_t PrintFlagsType;
    enum { Base = 10 };
    /// Flags used for denoting positive or negative, infinity and not a number.
    enum FlagsTypeEnum
    {
      positive = 0x01,                          ///< Set if this Decimal is positive, else this Decimal is negative.
      infinity = 0x02,                          ///< Set if this Decimal is positive or negative infinity.
      negativeInfinity = infinity,              ///< Negative infinity.
      positiveInfinity = infinity | positive,   ///< Positive infinity.
      NaN = 0x04                                ///< Not a Number.
    };
    /// How infinity is printed on output.
    enum InfinityOutputType
    {
      infinityShort,   ///< Affects output only, print Inf or -Inf.
      infinityLong,    ///< Affects output only, print Infinity or -Infinity instead of Inf or -Inf.
      infinityTilde    ///< Affects output only, print ~ or -~ (as used in Oracle) instead of Inf or -Inf.
    };
    /// Rounding algorithm.
    enum RoundingAlgorithmType
    {
      truncate,        ///< 1.1, 1.5, and 1.6 and all rounded down to 1.0.
      round,           ///< 1.1 is rounded down to 1.0, 1.5, and 1.6 are rounded up to 2.0.
      bankersRound     ///< 1.1 and 1.5 are rounded down to 1.0, 1.6 is rounded up to 2.0.
    };
  private:
    MantissaType mantissa;
    ExponentType exponent;
    FlagsType flags;
    PrintFlagsType defaultPrintFlags;

  public:
    /// Initializes the Decimal-object with empty values.
    Decimal();
    /// Initializes the Decimal-object with the given double value.
    /// @param value double to initialize it with.
    explicit Decimal(double value);

    /// Initialize this Decimal-object with the given decimal mantissa and exponent.
    /// @param man integer decimal mantissa value to set this Decimal number to.
    /// @param exp integer base 10 exponent to set this Decimal number to.
    Decimal(int64_t man, ExponentType exp);

    /// Initializes the Decimal-object with the given MantissaType mantissa
    /// and ExponentType exponent
    /// @param man integer decimal mantissa value to set this Decimal number to.
    /// @param exp integer base 10 exponent to set this Decimal number to.
    /// @param f the flags, need to specify positive or negative. @link Decimal::FlagsTypeEnum @endlink
    /// @param pf the print flags for infinity and not a number. @link Decimal::InfinityOutputType @endlink
    Decimal(MantissaType man, ExponentType exp, FlagsType f, PrintFlagsType pf = infinityShort);
    /// Return the decimal mantissa.
    /// @return the decimal mantissa.
    MantissaType getMantissa() const;
    /// Return the base 10 exponent.
    /// @return the base 10 exponent.
    ExponentType getExponent() const;

    /// Is this Decimal number positive?
    /// @return true if this Decimal number is positive, else return false.
    bool isPositive() const
      { return flags & positive; }

    /// Is this Decimal number positive or negative infinity?
    /// @return true if this Decimal number is either positive or negative
    /// infinity, else return false.
    bool isInfinity() const;

    /// Is this Decimal number positive or negative infinity?
    /// @param positiveInfinity
    /// @return If postitiveInfinity is true, then return true if this
    /// Decimal number is postitive infinity.
    /// Else if postitiveInfinity is false, then return true if this
    /// Decimal number is negative infinity.
    /// Else return false.
    bool isInfinity(bool positiveInfinity) const;

    /// Is this Decimal not a number?
    /// @return true if this Decimal number is Not a Number.
    /// Else return false.
    bool isNaN() const;

    /// Is this Decimal number zero?
    /// @return true if this Number object is zero, else return false.
    bool isZero() const;

    /// Split this decimal number into integral part, fractional
    /// and exponent parts.  An optional user specified exponent
    /// offset can be used to first scale the decimal number.
    /// @param integral the part of the decimal floating point
    /// number to the left of the decimal point.
    /// @param fractional the part to the decimal floating point
    /// number to the right of the decimal point.
    /// @param ex the exponent of the decimal floating point number
    /// @param optionalUserSpecifiedExponentOffset optional user
    /// specified exponent offset can be used to first scale the decimal number.
    /// @throw std::overflow_error if the result will not fit
    template <typename ManType>
    void getIntegralFractionalExponent(ManType &integral,
                                       ManType &fractional,
                                       ExponentType &ex,
                                       ExponentType optionalUserSpecifiedExponentOffset = 0) const throw(std::overflow_error);

    /// Return the number of decimal digits in n.
    template <typename IntegerType>
    IntegerType numberOfDigits(IntegerType n) const;

    /// Return this number as a C++ integer type.
    /// @param roundingAlgorithm @link Decimal::RoundingAlgorithmType @endlink
    /// @return integer result if the result will fit.
    /// @throw std::overflow_error if the result will not fit
    template <typename IntegerType>
    IntegerType getInteger(RoundingAlgorithmType roundingAlgorithm = round) const throw(std::overflow_error);

    /// Return this number as a C++ floating point type.
    /// @return binary floating point result, which is computed
    /// with binary floating point arithmetic, and hence is an approximation.
    template <typename FloatingPointType>
    FloatingPointType getFloatingPoint() const;

    /// Return this decimal number rounded as a C++ int.
    /// @return int result if the result will fit.
    /// @throw std::overflow_error if the result will not fit
    int getInt() const throw(std::overflow_error)
      { return getInteger<int>(); }

    /// Return this decimal number rounded as a C++ long.
    /// @return long result if the result will fit.
    /// @throw std::overflow_error if the result will not fit
    int getLong() const throw(std::overflow_error)
      { return getInteger<long>(); }

    /// Return this decimal number rounded as a C++ int32_t.
    /// @return int32_t result if the result will fit.<commit_msg>getLong should return a long instead of int<commit_after>/*
 * Copyright (C) 2007 <NAME>, <NAME>right
 * 
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 * 
 * As a special exception, you may use this file as part of a free
 * software library without restriction. Specifically, if other files
 * instantiate templates or use macros or inline functions from this
 * file, or you compile this file and link it with other files to
 * produce an executable, this file does not by itself cause the
 * resulting executable to be covered by the GNU General Public
 * License. This exception does not however invalidate any other
 * reasons why the executable file might be covered by the GNU Library
 * General Public License.
 * 
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */

#ifndef TNTDB_DECIMAL_H
#define TNTDB_DECIMAL_H

#include <string>
#include <iostream>
#include <sstream>
#include <stdexcept>
#include <stdint.h>

namespace tntdb
{
  /**
   * This class holds a decimal floating point number.  It is necessary to
   * convert it to some other type to perform arithmetic and other operations.
   * Decimal is implemented with a 64 bit unsigned integer mantissa, and a
   * 32 bit exponent.  For conversions from integer types, strings, and reading
   * from the database, Decimal tries to maintain accuracy if the result will
   * fit in the 64 bit unsigned mantissa and exponent.  When converting to
   * integer types, Decimal will throw std::overflow exception if the result
   * will not fit.  For converting to binary floating point numbers, binary
   * floating point is used in the conversion, and the result is an
   * approximation.
   */
  class Decimal
  {
  public:
    typedef uint64_t MantissaType;
    typedef int32_t ExponentType;
    typedef int8_t FlagsType;
    typedef int8_t PrintFlagsType;
    enum { Base = 10 };
    /// Flags used for denoting positive or negative, infinity and not a number.
    enum FlagsTypeEnum
    {
      positive = 0x01,                          ///< Set if this Decimal is positive, else this Decimal is negative.
      infinity = 0x02,                          ///< Set if this Decimal is positive or negative infinity.
      negativeInfinity = infinity,              ///< Negative infinity.
      positiveInfinity = infinity | positive,   ///< Positive infinity.
      NaN = 0x04                                ///< Not a Number.
    };
    /// How infinity is printed on output.
    enum InfinityOutputType
    {
      infinityShort,   ///< Affects output only, print Inf or -Inf.
      infinityLong,    ///< Affects output only, print Infinity or -Infinity instead of Inf or -Inf.
      infinityTilde    ///< Affects output only, print ~ or -~ (as used in Oracle) instead of Inf or -Inf.
    };
    /// Rounding algorithm.
    enum RoundingAlgorithmType
    {
      truncate,        ///< 1.1, 1.5, and 1.6 and all rounded down to 1.0.
      round,           ///< 1.1 is rounded down to 1.0, 1.5, and 1.6 are rounded up to 2.0.
      bankersRound     ///< 1.1 and 1.5 are rounded down to 1.0, 1.6 is rounded up to 2.0.
    };
  private:
    MantissaType mantissa;
    ExponentType exponent;
    FlagsType flags;
    PrintFlagsType defaultPrintFlags;

  public:
    /// Initializes the Decimal-object with empty values.
    Decimal();
    /// Initializes the Decimal-object with the given double value.
    /// @param value double to initialize it with.
    explicit Decimal(double value);

    /// Initialize this Decimal-object with the given decimal mantissa and exponent.
    /// @param man integer decimal mantissa value to set this Decimal number to.
    /// @param exp integer base 10 exponent to set this Decimal number to.
    Decimal(int64_t man, ExponentType exp);

    /// Initializes the Decimal-object with the given MantissaType mantissa
    /// and ExponentType exponent
    /// @param man integer decimal mantissa value to set this Decimal number to.
    /// @param exp integer base 10 exponent to set this Decimal number to.
    /// @param f the flags, need to specify positive or negative. @link Decimal::FlagsTypeEnum @endlink
    /// @param pf the print flags for infinity and not a number. @link Decimal::InfinityOutputType @endlink
    Decimal(MantissaType man, ExponentType exp, FlagsType f, PrintFlagsType pf = infinityShort);
    /// Return the decimal mantissa.
    /// @return the decimal mantissa.
    MantissaType getMantissa() const;
    /// Return the base 10 exponent.
    /// @return the base 10 exponent.
    ExponentType getExponent() const;

    /// Is this Decimal number positive?
    /// @return true if this Decimal number is positive, else return false.
    bool isPositive() const
      { return flags & positive; }

    /// Is this Decimal number positive or negative infinity?
    /// @return true if this Decimal number is either positive or negative
    /// infinity, else return false.
    bool isInfinity() const;

    /// Is this Decimal number positive or negative infinity?
    /// @param positiveInfinity
    /// @return If postitiveInfinity is true, then return true if this
    /// Decimal number is postitive infinity.
    /// Else if postitiveInfinity is false, then return true if this
    /// Decimal number is negative infinity.
    /// Else return false.
    bool isInfinity(bool positiveInfinity) const;

    /// Is this Decimal not a number?
    /// @return true if this Decimal number is Not a Number.
    /// Else return false.
    bool isNaN() const;

    /// Is this Decimal number zero?
    /// @return true if this Number object is zero, else return false.
    bool isZero() const;

    /// Split this decimal number into integral part, fractional
    /// and exponent parts.  An optional user specified exponent
    /// offset can be used to first scale the decimal number.
    /// @param integral the part of the decimal floating point
    /// number to the left of the decimal point.
    /// @param fractional the part to the decimal floating point
    /// number to the right of the decimal point.
    /// @param ex the exponent of the decimal floating point number
    /// @param optionalUserSpecifiedExponentOffset optional user
    /// specified exponent offset can be used to first scale the decimal number.
    /// @throw std::overflow_error if the result will not fit
    template <typename ManType>
    void getIntegralFractionalExponent(ManType &integral,
                                       ManType &fractional,
                                       ExponentType &ex,
                                       ExponentType optionalUserSpecifiedExponentOffset = 0) const throw(std::overflow_error);

    /// Return the number of decimal digits in n.
    template <typename IntegerType>
    IntegerType numberOfDigits(IntegerType n) const;

    /// Return this number as a C++ integer type.
    /// @param roundingAlgorithm @link Decimal::RoundingAlgorithmType @endlink
    /// @return integer result if the result will fit.
    /// @throw std::overflow_error if the result will not fit
    template <typename IntegerType>
    IntegerType getInteger(RoundingAlgorithmType roundingAlgorithm = round) const throw(std::overflow_error);

    /// Return this number as a C++ floating point type.
    /// @return binary floating point result, which is computed
    /// with binary floating point arithmetic, and hence is an approximation.
    template <typename FloatingPointType>
    FloatingPointType getFloatingPoint() const;

    /// Return this decimal number rounded as a C++ int.
    /// @return int result if the result will fit.
    /// @throw std::overflow_error if the result will not fit
    int getInt() const throw(std::overflow_error)
      { return getInteger<int>(); }

    /// Return this decimal number rounded as a C++ long.
    /// @return long result if the result will fit.
    /// @throw std::overflow_error if the result will not fit
    long getLong() const throw(std::overflow_error)
      { return getInteger<long>(); }

    /// Return this decimal number rounded as a C++ int32_t.
    /// @return int32_t result if the result will fit.
{'fraction_non_alphanumeric': 0.07482525495588403, 'fraction_numerical': 0.009510713876475306, 'mean_word_length': 2.6871567384875368, 'pattern_counts': {'":': 0, '<': 51, '<?xml version=': 0, '>': 29, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 6, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6061481', 'n_tokens_mistral': 4633, 'n_tokens_neox': 4376, 'n_words': 2146}