/** @file * @brief Fixed-point numbers. */ /** @mainpage Project 2 - FIxed-Point Numbers * This program is Project 2 in Exploring C++, * by Ray Lischner (Apress). * * Your task for Project 2 is to implement a simple fixed-point * number class. The class represents fixed-point numbers using * an integer type. The number of places after the decimal point * is a fixed constant, four. For example, represent the number * 3.1415 as the integer 31415 and 3.14 as 31400. You must overload * the arithmetic, comparison, and I/O operators to maintain the * fixed-point fiction. * * Source files: * - @link fixed.hpp fixed.hpp @endlink * - @link fixed.cpp fixed.cpp @endlink * - @link test.cpp test.cpp @endlink: test program * - @link test.hpp test.hpp @endlink: test header (see Exploration 28) * - @link ioflags.hpp ioflags.hpp @endlink: save and restore I/O stream flags (Exploration 37) * * @author Ray Lischner */ #ifndef FIXED_HPP_ #define FIXED_HPP_ #include #include #include /** @brief Implement a fixed-point number class. * Values have @c places places after the decimal point. * All arithmetic follows the usual rules. */ class fixed { public: typedef int value_type; ///< Type of the actual value static int const places = 4; ///< number of decimal places static value_type const places10 = 10000; ///< 10places /// Default constructor initializes to zero. fixed() : value_(0) {} /// Construct from separate integer and fractional parts, /// e.g., initialize to 123.45 with fixed(123, 45). Initialize /// to 12.07 with fixed(12, 7). fixed(value_type integer, value_type fraction); /// Construct from an integer, with no fraction. fixed(value_type integer); /// Construct by rounding off a floating point number. fixed(double value) : value_(static_cast(value * places10 + (value < 0 ? -0.5 : 0.5))) {} /// Convert to a string. /// @returns a string representation of the value, e.g., "123.04" std::string as_string() const; /// Read from a stream. /// Overwrite this value with the value read from the stream. /// @param strm the stream to read /// @returns true for success or false for failure bool read(std::istream& strm); /// Convert to long double. double as_long_double() const { return static_cast(value()) / places10; } /// Convert to double. double as_double() const { return static_cast(value()) / places10; } /// Convert to float float as_float() const { return static_cast(value()) / places10; } /// Return just the integer part, rounded off to the nearest integer. /// If the value lies equidistant between two integers, round even /// numbers up and odd numbers down (banker's rounding). value_type round() const; /// Return the integer part (which is the same as trunc()). value_type integer() const { return value() / places10; } /// Return the fractional part, e.g., 3 for 12.03 value_type fraction() const; /// Addition assignment operator fixed& operator+=(fixed f); /// Subtraction assignment operator fixed& operator-=(fixed f); /// Multiplication assignment operator fixed& operator*=(fixed f); /// Division assignment operator fixed& operator/=(fixed f); /// Negate this value. void negate(); /// Pre-increment fixed& operator++(); /// Post-increment fixed operator++(int); /// Pre-decrement fixed& operator--(); /// Post-decrement fixed operator--(int); /// Return the internal value. value_type value() const { return value_; } private: /// Reduce frac to the range [0, places10) by discarding digits to the right. value_type reduce(value_type frac); value_type value_; }; /// Read a fixed value std::istream& operator>>(std::istream& strm, fixed& f); /// Write a fixed value std::ostream& operator<<(std::ostream& strm, fixed f); /// Add fixed values fixed operator+(fixed a, fixed b); /// Subtract fixed values fixed operator-(fixed a, fixed b); /// Multiply fixed values fixed operator*(fixed a, fixed b); /// Divide fixed values fixed operator/(fixed a, fixed b); /// Negate a fixed value fixed operator-(fixed a); /// Compare fixed values for equality by comparing the underlying values. bool operator==(fixed a, fixed b); /// Compare fixed values for inequality by comparing the underlying values. bool operator!=(fixed a, fixed b); /// Compare fixed values for less-than by comparing the underlying values. bool operator<(fixed a, fixed b); /// Compare fixed values for greater-than by comparing the underlying values. bool operator>(fixed a, fixed b); /// Compare fixed values for less-than-or-equal by comparing the underlying values. bool operator<=(fixed a, fixed b); /// Compare fixed values for greater-than-or-equal by comparing the underlying values. bool operator>=(fixed a, fixed b); #endif