1
0
mirror of https://git.suyu.dev/suyu/suyu synced 2025-09-19 04:28:00 -05:00

Initial commit

This commit is contained in:
Crimson-Hawk
2024-03-05 16:42:40 +08:00
commit f1e4595ebf
39576 changed files with 7006612 additions and 0 deletions

View File

View File

View File

@@ -0,0 +1,96 @@
* text=auto !eol svneol=native#text/plain
*.gitattributes text svneol=native#text/plain
# Scriptish formats
*.bat text svneol=native#text/plain
*.bsh text svneol=native#text/x-beanshell
*.cgi text svneol=native#text/plain
*.cmd text svneol=native#text/plain
*.js text svneol=native#text/javascript
*.php text svneol=native#text/x-php
*.pl text svneol=native#text/x-perl
*.pm text svneol=native#text/x-perl
*.py text svneol=native#text/x-python
*.sh eol=lf svneol=LF#text/x-sh
configure eol=lf svneol=LF#text/x-sh
# Image formats
*.bmp binary svneol=unset#image/bmp
*.gif binary svneol=unset#image/gif
*.ico binary svneol=unset#image/ico
*.jpeg binary svneol=unset#image/jpeg
*.jpg binary svneol=unset#image/jpeg
*.png binary svneol=unset#image/png
*.tif binary svneol=unset#image/tiff
*.tiff binary svneol=unset#image/tiff
*.svg text svneol=native#image/svg%2Bxml
# Data formats
*.pdf binary svneol=unset#application/pdf
*.avi binary svneol=unset#video/avi
*.doc binary svneol=unset#application/msword
*.dsp text svneol=crlf#text/plain
*.dsw text svneol=crlf#text/plain
*.eps binary svneol=unset#application/postscript
*.gz binary svneol=unset#application/gzip
*.mov binary svneol=unset#video/quicktime
*.mp3 binary svneol=unset#audio/mpeg
*.ppt binary svneol=unset#application/vnd.ms-powerpoint
*.ps binary svneol=unset#application/postscript
*.psd binary svneol=unset#application/photoshop
*.rdf binary svneol=unset#text/rdf
*.rss text svneol=unset#text/xml
*.rtf binary svneol=unset#text/rtf
*.sln text svneol=native#text/plain
*.swf binary svneol=unset#application/x-shockwave-flash
*.tgz binary svneol=unset#application/gzip
*.vcproj text svneol=native#text/xml
*.vcxproj text svneol=native#text/xml
*.vsprops text svneol=native#text/xml
*.wav binary svneol=unset#audio/wav
*.xls binary svneol=unset#application/vnd.ms-excel
*.zip binary svneol=unset#application/zip
# Text formats
.htaccess text svneol=native#text/plain
*.bbk text svneol=native#text/xml
*.cmake text svneol=native#text/plain
*.css text svneol=native#text/css
*.dtd text svneol=native#text/xml
*.htm text svneol=native#text/html
*.html text svneol=native#text/html
*.ini text svneol=native#text/plain
*.log text svneol=native#text/plain
*.mak text svneol=native#text/plain
*.qbk text svneol=native#text/plain
*.rst text svneol=native#text/plain
*.sql text svneol=native#text/x-sql
*.txt text svneol=native#text/plain
*.xhtml text svneol=native#text/xhtml%2Bxml
*.xml text svneol=native#text/xml
*.xsd text svneol=native#text/xml
*.xsl text svneol=native#text/xml
*.xslt text svneol=native#text/xml
*.xul text svneol=native#text/xul
*.yml text svneol=native#text/plain
boost-no-inspect text svneol=native#text/plain
CHANGES text svneol=native#text/plain
COPYING text svneol=native#text/plain
INSTALL text svneol=native#text/plain
Jamfile text svneol=native#text/plain
Jamroot text svneol=native#text/plain
Jamfile.v2 text svneol=native#text/plain
Jamrules text svneol=native#text/plain
Makefile* text svneol=native#text/plain
README text svneol=native#text/plain
TODO text svneol=native#text/plain
# Code formats
*.c text svneol=native#text/plain
*.cpp text svneol=native#text/plain
*.h text svneol=native#text/plain
*.hpp text svneol=native#text/plain
*.ipp text svneol=native#text/plain
*.tpp text svneol=native#text/plain
*.jam text svneol=native#text/plain
*.java text svneol=native#text/plain

View File

@@ -0,0 +1,351 @@
# Copyright 2016-2019 Peter Dimov
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE_1_0.txt or copy at http://boost.org/LICENSE_1_0.txt)
language: cpp
sudo: false
dist: xenial
branches:
only:
- master
- develop
- /feature\/.*/
env:
matrix:
- BOGUS_JOB=true
matrix:
exclude:
- env: BOGUS_JOB=true
include:
- os: linux
compiler: g++
env: TOOLSET=gcc COMPILER=g++ CXXSTD=03,11
- os: linux
compiler: g++-4.4
env: TOOLSET=gcc COMPILER=g++-4.4 CXXSTD=98,0x
addons:
apt:
packages:
- g++-4.4
sources:
- ubuntu-toolchain-r-test
- os: linux
compiler: g++-4.6
env: TOOLSET=gcc COMPILER=g++-4.6 CXXSTD=03,0x
addons:
apt:
packages:
- g++-4.6
sources:
- ubuntu-toolchain-r-test
- os: linux
compiler: g++-4.7
env: TOOLSET=gcc COMPILER=g++-4.7 CXXSTD=03,11
addons:
apt:
packages:
- g++-4.7
sources:
- ubuntu-toolchain-r-test
- os: linux
compiler: g++-4.8
env: TOOLSET=gcc COMPILER=g++-4.8 CXXSTD=03,11
addons:
apt:
packages:
- g++-4.8
sources:
- ubuntu-toolchain-r-test
- os: linux
compiler: g++-4.9
env: TOOLSET=gcc COMPILER=g++-4.9 CXXSTD=03,11
addons:
apt:
packages:
- g++-4.9
sources:
- ubuntu-toolchain-r-test
- os: linux
compiler: g++-5
env: TOOLSET=gcc COMPILER=g++-5 CXXSTD=03,11,14,1z
addons:
apt:
packages:
- g++-5
sources:
- ubuntu-toolchain-r-test
- os: linux
compiler: g++-6
env: TOOLSET=gcc COMPILER=g++-6 CXXSTD=03,11,14,1z
addons:
apt:
packages:
- g++-6
sources:
- ubuntu-toolchain-r-test
- os: linux
compiler: g++-7
env: TOOLSET=gcc COMPILER=g++-7 CXXSTD=03,11,14,17
addons:
apt:
packages:
- g++-7
sources:
- ubuntu-toolchain-r-test
- os: linux
compiler: g++-8
env: TOOLSET=gcc COMPILER=g++-8 CXXSTD=03,11,14,17,2a
addons:
apt:
packages:
- g++-8
sources:
- ubuntu-toolchain-r-test
- os: linux
compiler: g++-9
env: TOOLSET=gcc COMPILER=g++-9 CXXSTD=03,11,14,17,2a
addons:
apt:
packages:
- g++-9
sources:
- ubuntu-toolchain-r-test
- os: linux
dist: bionic
compiler: g++-10
env: TOOLSET=gcc COMPILER=g++-10 CXXSTD=03,11,14,17,2a
addons:
apt:
packages:
- g++-10
sources:
- ubuntu-toolchain-r-test
- os: linux
compiler: g++-9
env: UBSAN=1 TOOLSET=gcc COMPILER=g++-9 CXXSTD=03,11,14,17,2a UBSAN_OPTIONS=print_stacktrace=1 LINKFLAGS=-fuse-ld=gold
addons:
apt:
packages:
- g++-9
sources:
- ubuntu-toolchain-r-test
- os: linux
compiler: clang++
env: TOOLSET=clang COMPILER=clang++ CXXSTD=03,11
- os: linux
dist: trusty
compiler: /usr/bin/clang++
env: TOOLSET=clang COMPILER=/usr/bin/clang++ CXXSTD=03,11
addons:
apt:
packages:
- clang-3.3
- os: linux
dist: trusty
compiler: /usr/bin/clang++
env: TOOLSET=clang COMPILER=/usr/bin/clang++ CXXSTD=03,11
addons:
apt:
packages:
- clang-3.4
- os: linux
compiler: clang++-3.6
env: TOOLSET=clang COMPILER=clang++-3.6 CXXSTD=03,11,14,1z
addons:
apt:
packages:
- clang-3.6
sources:
- ubuntu-toolchain-r-test
- os: linux
compiler: clang++-3.7
env: TOOLSET=clang COMPILER=clang++-3.7 CXXSTD=03,11,14,1z
addons:
apt:
packages:
- clang-3.7
sources:
- ubuntu-toolchain-r-test
- os: linux
compiler: clang++-3.8
env: TOOLSET=clang COMPILER=clang++-3.8 CXXSTD=03,11,14,1z
addons:
apt:
packages:
- clang-3.8
sources:
- ubuntu-toolchain-r-test
- os: linux
compiler: clang++-3.9
env: TOOLSET=clang COMPILER=clang++-3.9 CXXSTD=03,11,14,1z
addons:
apt:
packages:
- clang-3.9
sources:
- ubuntu-toolchain-r-test
- os: linux
compiler: clang++-4.0
env: TOOLSET=clang COMPILER=clang++-4.0 CXXSTD=03,11,14,1z
addons:
apt:
packages:
- clang-4.0
sources:
- ubuntu-toolchain-r-test
- os: linux
compiler: clang++-5.0
env: TOOLSET=clang COMPILER=clang++-5.0 CXXSTD=03,11,14,1z
addons:
apt:
packages:
- clang-5.0
sources:
- ubuntu-toolchain-r-test
- os: linux
compiler: clang++-6.0
env: TOOLSET=clang COMPILER=clang++-6.0 CXXSTD=03,11,14,17
addons:
apt:
packages:
- clang-6.0
sources:
- ubuntu-toolchain-r-test
- os: linux
compiler: clang++-7
env: TOOLSET=clang COMPILER=clang++-7 CXXSTD=03,11,14,17,2a
addons:
apt:
packages:
- clang-7
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-xenial-7
- os: linux
compiler: clang++-8
env: TOOLSET=clang COMPILER=clang++-8 CXXSTD=03,11,14,17,2a
addons:
apt:
packages:
- clang-8
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-xenial-8
- os: linux
compiler: clang++-9
env: TOOLSET=clang COMPILER=clang++-9 CXXSTD=03,11,14,17,2a
addons:
apt:
packages:
- clang-9
sources:
- ubuntu-toolchain-r-test
- sourceline: 'deb https://apt.llvm.org/xenial/ llvm-toolchain-xenial-9 main'
key_url: 'https://apt.llvm.org/llvm-snapshot.gpg.key'
- os: linux
dist: xenial
compiler: clang++-10
env: TOOLSET=clang COMPILER=clang++-10 CXXSTD=03,11,14,17,2a
addons:
apt:
packages:
- clang-10
sources:
- ubuntu-toolchain-r-test
- sourceline: 'deb https://apt.llvm.org/xenial/ llvm-toolchain-xenial-10 main'
key_url: 'https://apt.llvm.org/llvm-snapshot.gpg.key'
- os: linux
dist: xenial
compiler: clang++-10
env: UBSAN=1 TOOLSET=clang COMPILER=clang++-10 CXXSTD=03,11,14,17,2a UBSAN_OPTIONS=print_stacktrace=1
addons:
apt:
packages:
- clang-10
sources:
- ubuntu-toolchain-r-test
- sourceline: 'deb https://apt.llvm.org/xenial/ llvm-toolchain-xenial-10 main'
key_url: 'https://apt.llvm.org/llvm-snapshot.gpg.key'
- os: linux
dist: trusty
compiler: clang++-libc++
env: TOOLSET=clang COMPILER=clang++-libc++ CXXSTD=03,11,14,1z
addons:
apt:
packages:
- libc++-dev
- os: linux
dist: trusty
compiler: clang++-libc++
env: UBSAN=1 TOOLSET=clang COMPILER=clang++-libc++ CXXSTD=03,11,14,1z UBSAN_OPTIONS=print_stacktrace=1
addons:
apt:
packages:
- libc++-dev
- os: osx
compiler: clang++
env: TOOLSET=clang COMPILER=clang++ CXXSTD=03,11,14,1z
- os: osx
compiler: clang++
env: UBSAN=1 TOOLSET=clang COMPILER=clang++ CXXSTD=03,11,14,1z UBSAN_OPTIONS=print_stacktrace=1
- os: freebsd
compiler: clang++
env: TOOLSET=clang COMPILER=clang++ CXXSTD=03,11,14,17,2a
install:
- BOOST_BRANCH=develop && [ "$TRAVIS_BRANCH" == "master" ] && BOOST_BRANCH=master || true
- cd ..
- git clone -b $BOOST_BRANCH --depth 1 https://github.com/boostorg/boost.git boost-root
- cd boost-root
- git submodule update --init tools/boostdep
- cp -r $TRAVIS_BUILD_DIR/* libs/rational
- python tools/boostdep/depinst/depinst.py rational
- ./bootstrap.sh
- ./b2 headers
script:
- |-
echo "using $TOOLSET : : $COMPILER ;" > ~/user-config.jam
- ./b2 -j3 libs/rational/test toolset=$TOOLSET cxxstd=$CXXSTD variant=debug,release ${UBSAN:+cxxflags=-fsanitize=undefined cxxflags=-fno-sanitize-recover=undefined linkflags=-fsanitize=undefined define=UBSAN=1 debug-symbols=on} ${LINKFLAGS:+linkflags=$LINKFLAGS}
notifications:
email:
on_success: always

View File

@@ -0,0 +1,32 @@
# Generated by `boostdep --cmake rational`
# Copyright 2020 Peter Dimov
# Distributed under the Boost Software License, Version 1.0.
# https://www.boost.org/LICENSE_1_0.txt
cmake_minimum_required(VERSION 3.5...3.16)
project(boost_rational VERSION "${BOOST_SUPERPROJECT_VERSION}" LANGUAGES CXX)
add_library(boost_rational INTERFACE)
add_library(Boost::rational ALIAS boost_rational)
target_include_directories(boost_rational INTERFACE include)
target_link_libraries(boost_rational
INTERFACE
Boost::assert
Boost::config
Boost::core
Boost::integer
Boost::static_assert
Boost::throw_exception
Boost::type_traits
Boost::utility
)
if(BUILD_TESTING AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/test/CMakeLists.txt")
add_subdirectory(test)
endif()

View File

@@ -0,0 +1,10 @@
# Boost.Rational Library Jamfile
#
# Copyright (c) 2018 James E. King III
#
# Use, modification, and distribution are subject to the
# Boost Software License, Version 1.0. (See accompanying file
# LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
# please order by name to ease maintenance
build-project test ;

View File

@@ -0,0 +1,23 @@
Boost Software License - Version 1.0 - August 17th, 2003
Permission is hereby granted, free of charge, to any person or organization
obtaining a copy of the software and accompanying documentation covered by
this license (the "Software") to use, reproduce, display, distribute,
execute, and transmit the Software, and to prepare derivative works of the
Software, and to permit third-parties to whom the Software is furnished to
do so, all subject to the following:
The copyright notices in the Software and this entire statement, including
the above license grant, this restriction and the following disclaimer,
must be included in all copies of the Software, in whole or in part, and
all derivative works of the Software, unless such copies or derivative
works are solely in the form of machine-executable object code generated by
a source language processor.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.

View File

@@ -0,0 +1,32 @@
Rational, part of collection of the [Boost C++ Libraries](http://github.com/boostorg), provides an implementation of rational numbers.
### License
Distributed under the [Boost Software License, Version 1.0](http://www.boost.org/LICENSE_1_0.txt).
### Properties
* C++03
* Header-Only
### Build Status
Branch | Travis | Appveyor | Coverity Scan | codecov.io | Deps | Docs | Tests |
:-------------: | ------ | -------- | ------------- | ---------- | ---- | ---- | ----- |
[`master`](https://github.com/boostorg/rational/tree/master) | [![Build Status](https://travis-ci.org/boostorg/rational.svg?branch=master)](https://travis-ci.org/boostorg/rational) | [![Build status](https://ci.appveyor.com/api/projects/status/8a2on7yb2xck80fa/branch/master?svg=true)](https://ci.appveyor.com/project/jeking3/rational-lqu73/branch/master) | [![Coverity Scan Build Status](https://scan.coverity.com/projects/16002/badge.svg)](https://scan.coverity.com/projects/boostorg-rational) | [![codecov](https://codecov.io/gh/boostorg/rational/branch/master/graph/badge.svg)](https://codecov.io/gh/boostorg/rational/branch/master)| [![Deps](https://img.shields.io/badge/deps-master-brightgreen.svg)](https://pdimov.github.io/boostdep-report/master/rational.html) | [![Documentation](https://img.shields.io/badge/docs-master-brightgreen.svg)](http://www.boost.org/doc/libs/master/doc/html/rational.html) | [![Enter the Matrix](https://img.shields.io/badge/matrix-master-brightgreen.svg)](http://www.boost.org/development/tests/master/developer/rational.html)
[`develop`](https://github.com/boostorg/rational/tree/develop) | [![Build Status](https://travis-ci.org/boostorg/rational.svg?branch=develop)](https://travis-ci.org/boostorg/rational) | [![Build status](https://ci.appveyor.com/api/projects/status/8a2on7yb2xck80fa/branch/develop?svg=true)](https://ci.appveyor.com/project/jeking3/rational-lqu73/branch/develop) | [![Coverity Scan Build Status](https://scan.coverity.com/projects/16002/badge.svg)](https://scan.coverity.com/projects/boostorg-rational) | [![codecov](https://codecov.io/gh/boostorg/rational/branch/develop/graph/badge.svg)](https://codecov.io/gh/boostorg/rational/branch/develop) | [![Deps](https://img.shields.io/badge/deps-develop-brightgreen.svg)](https://pdimov.github.io/boostdep-report/develop/rational.html) | [![Documentation](https://img.shields.io/badge/docs-develop-brightgreen.svg)](http://www.boost.org/doc/libs/develop/doc/html/rational.html) | [![Enter the Matrix](https://img.shields.io/badge/matrix-develop-brightgreen.svg)](http://www.boost.org/development/tests/develop/developer/rational.html)
### Directories
| Name | Purpose |
| ----------- | ------------------------------ |
| `include` | header |
| `test` | unit tests |
### More information
* [Ask questions](http://stackoverflow.com/questions/ask?tags=c%2B%2B,boost,boost-rational)
* [Report bugs](https://github.com/boostorg/rational/issues): Be sure to mention Boost version, platform and compiler you're using. A small compilable code sample to reproduce the problem is always good as well.
* Submit your patches as pull requests against **develop** branch. Note that by submitting patches you agree to license your modifications under the [Boost Software License, Version 1.0](http://www.boost.org/LICENSE_1_0.txt).
* Discussions about the library are held on the [Boost developers mailing list](http://www.boost.org/community/groups.html#main). Be sure to read the [discussion policy](http://www.boost.org/community/policy.html) before posting and add the `[rational]` tag at the beginning of the subject line.

View File

@@ -0,0 +1,70 @@
# Copyright 2016-2019 Peter Dimov
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE_1_0.txt or copy at http://boost.org/LICENSE_1_0.txt)
version: 1.0.{build}-{branch}
shallow_clone: true
branches:
only:
- master
- develop
- /feature\/.*/
environment:
matrix:
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
TOOLSET: msvc-9.0,msvc-10.0,msvc-11.0
ADDRMD: 32
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
TOOLSET: msvc-12.0,msvc-14.0
ADDRMD: 32,64
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
TOOLSET: msvc-14.1
CXXSTD: 14,17
ADDRMD: 32,64
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
TOOLSET: clang-win
CXXSTD: 14,17
ADDRMD: 64
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
TOOLSET: msvc-14.2
CXXSTD: 14,17
ADDRMD: 32,64
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
ADDPATH: C:\cygwin\bin;
TOOLSET: gcc
CXXSTD: 03,11,14,1z
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
ADDPATH: C:\cygwin64\bin;
TOOLSET: gcc
CXXSTD: 03,11,14,1z
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
ADDPATH: C:\mingw\bin;
TOOLSET: gcc
CXXSTD: 03,11,14,1z
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
ADDPATH: C:\mingw-w64\x86_64-6.3.0-posix-seh-rt_v5-rev1\mingw64\bin;
TOOLSET: gcc
CXXSTD: 03,11,14,1z
install:
- set BOOST_BRANCH=develop
- if "%APPVEYOR_REPO_BRANCH%" == "master" set BOOST_BRANCH=master
- cd ..
- git clone -b %BOOST_BRANCH% --depth 1 https://github.com/boostorg/boost.git boost-root
- cd boost-root
- git submodule update --init tools/boostdep
- xcopy /s /e /q %APPVEYOR_BUILD_FOLDER% libs\rational\
- python tools/boostdep/depinst/depinst.py rational
- cmd /c bootstrap
- b2 -d0 headers
build: off
test_script:
- PATH=%ADDPATH%%PATH%
- if not "%CXXSTD%" == "" set CXXSTD=cxxstd=%CXXSTD%
- if not "%ADDRMD%" == "" set ADDRMD=address-model=%ADDRMD%
- b2 -j3 libs/rational/test toolset=%TOOLSET% %CXXSTD% %ADDRMD% variant=debug,release

View File

@@ -0,0 +1 @@
The documentation for Boost rational is the top-level index.html.

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,47 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<title>Boost Rational Number Library</title>
</head>
<body bgcolor="#FFFFFF" text="#000000">
<table border="1" bgcolor="#007F7F" cellpadding="2">
<tr>
<td bgcolor="#FFFFFF"><img src="../../boost.png" alt="boost.png (6897 bytes)" WIDTH="277" HEIGHT="86"></td>
<td><a href="../../index.htm"><font face="Arial" color="#FFFFFF"><big>Home </big></font></a></td>
<td><a href="../libraries.htm"><font face="Arial" color="#FFFFFF"><big>Libraries </big></font></a></td>
<td><a href="http://www.boost.org/people/people.htm"><font face="Arial" color="#FFFFFF"><big>People </big></font></a></td>
<td><a href="http://www.boost.org/more/faq.htm"><font face="Arial" color="#FFFFFF"><big>FAQ </big></font></a></td>
<td><a href="../../more/index.htm"><font face="Arial" color="#FFFFFF"><big>More </big></font></a></td>
</tr>
</table>
<h1>Rational Number library</h1>
<p>The header rational.hpp provides an implementation of rational numbers.
The implementation is template-based, in a similar manner to the standard
complex number class.</p>
<p>This implementation is intended for general use. If you are a number
theorist, or otherwise have very stringent requirements, you would be advised
to use one of the more specialist packages available.</p>
<ul>
<li><a href="rational.html">Documentation</a> (HTML).</li>
<li>Header <a href="../../boost/rational.hpp">rational.hpp</a>.</li>
<li>See the <a href="rational.html">documentation</a> for links to sample programs.</li>
<li>Submitted by <a href="http://www.boost.org/people/paul_moore.htm"> Paul Moore</a>.</li>
</ul>
<p>Revised&nbsp; December 14, 1999</p>
<p>&copy; Copyright Paul Moore 1999. Permission to copy, use, modify, sell
and distribute this document is granted provided this copyright notice
appears in all copies. This document is provided &quot;as is&quot; without
express or implied warranty, and with no claim as to its suitability for
any purpose.</p>
<!-- boostinspect:nolicense (can't find Paul Moore to change license) -->
</body>
</html>

View File

@@ -0,0 +1,15 @@
{
"key": "rational",
"name": "Rational",
"authors": [
"Paul Moore"
],
"description": "A rational number class.",
"category": [
"Math"
],
"maintainers": [
"Jonathan Turkanis <turkanis -at- coderage.com>"
],
"cxxstd": "03"
}

View File

@@ -0,0 +1,768 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<title>Rational Number Library</title>
</head>
<body>
<h1><img src="../../boost.png" alt="boost.png (6897 bytes)"
align="middle" width="277" height="86">
Rational Numbers</h1>
<h2><a name="Contents">Contents</a></h2>
<ol>
<li><a href="#Class%20rational%20synopsis">Class rational synopsis</a></li>
<li><a href="#Rationale">Rationale</a></li>
<li><a href="#Background">Background</a></li>
<li><a href="#Integer%20Type%20Requirements">Integer Type Requirements</a></li>
<li><a href="#Interface">Interface</a>
<ul>
<li><a href="#Utility%20functions">Utility functions</a></li>
<li><a href="#Constructors">Constructors</a></li>
<li><a href="#Arithmetic%20operations">Arithmetic operations</a></li>
<li><a href="#Input%20and%20Output">Input and Output</a></li>
<li><a href="#In-place%20assignment">In-place assignment</a></li>
<li><a href="#Conversions">Conversions</a></li>
<li><a href="#Numerator%20and%20Denominator">Numerator and Denominator</a></li>
</ul></li>
<li><a href="#Performance">Performance</a></li>
<li><a href="#Exceptions">Exceptions</a></li>
<li><a href="#Internal%20representation">Internal representation</a></li>
<li><a href="#Design%20notes">Design notes</a>
<ul>
<li><a href="#Minimal%20Implementation">Minimal Implementation</a></li>
<li><a href="#Limited-range%20integer%20types">Limited-range integer types</a></li>
<li><a href="#Conversion%20from%20floating%20point">Conversion from floating point</a></li>
<li><a href="#Absolute%20Value">Absolute Value</a></li>
</ul></li>
<li><a href="#References">References</a></li>
<li><a href="#History%20and%20Acknowledgements">History and Acknowledgements</a></li>
</ol>
<h2><a name="Class rational synopsis">Class rational synopsis</a></h2>
<pre>
#include &lt;boost/rational.hpp&gt;
namespace boost {
class bad_rational;
template&lt;typename I&gt; class rational {
typedef <em>implementation-defined</em> bool_type;
public:
typedef I int_type;
// Constructors
rational(); // Zero; constexpr since C++11
rational(I n); // Equal to n/1; constexpr since C++11
rational(I n, I d); // General case (n/d); constexpr since C++14
template&lt;typename J&gt;
explicit rational(const rational&lt;J&gt; &amp;r); // Cross-instantiation; constexpr since C++11
// Normal copy constructors and assignment operators
// Assignment from I
rational&amp; operator=(I n); // constexpr since C++14
// Assign in place
rational&amp; assign(I n, I d); // constexpr since C++14
// Representation
I numerator() const; // constexpr since C++11
I denominator() const; // constexpr since C++11
// In addition to the following operators, all of the "obvious" derived
// operators are available - see <a href="../utility/operators.htm">operators.hpp</a>
// Arithmetic operators
rational&amp; operator+= (const rational&amp; r); // constexpr since C++14
rational&amp; operator-= (const rational&amp; r); // constexpr since C++14
rational&amp; operator*= (const rational&amp; r); // constexpr since C++14
rational&amp; operator/= (const rational&amp; r); // constexpr since C++14
// Arithmetic with integers
rational&amp; operator+= (I i); // constexpr since C++14
rational&amp; operator-= (I i); // constexpr since C++14
rational&amp; operator*= (I i); // constexpr since C++14
rational&amp; operator/= (I i); // constexpr since C++14
// Increment and decrement
const rational&amp; operator++(); // constexpr since C++14
const rational&amp; operator--(); // constexpr since C++14
// Operator not
bool operator!() const; // constexpr since C++11
// Boolean conversion
operator bool_type() const; // constexpr since C++11
// Comparison operators
bool operator&lt; (const rational&amp; r) const; // constexpr since C++14
bool operator== (const rational&amp; r) const; // constexpr since C++11
// Comparison with integers
bool operator&lt; (I i) const; // constexpr since C++14
bool operator&gt; (I i) const; // constexpr since C++14
bool operator== (I i) const; // constexpr since C++11
};
// Unary operators
template &lt;typename I&gt; rational&lt;I&gt; operator+ (const rational&lt;I&gt;&amp; r); // constexpr since C++11
template &lt;typename I&gt; rational&lt;I&gt; operator- (const rational&lt;I&gt;&amp; r); // constexpr since C++14
// Reversed order operators for - and / between (types convertible to) I and rational
template &lt;typename I, typename II&gt; inline rational&lt;I&gt; operator- (II i, const rational&lt;I&gt;&amp; r); // constexpr since C++14
template &lt;typename I, typename II&gt; inline rational&lt;I&gt; operator/ (II i, const rational&lt;I&gt;&amp; r); // constexpr since C++14
// Absolute value
template &lt;typename I&gt; rational&lt;I&gt; abs (const rational&lt;I&gt;&amp; r); // constexpr since C++14
// Input and output
template &lt;typename I&gt; std::istream&amp; operator&gt;&gt; (std::istream&amp; is, rational&lt;I&gt;&amp; r);
template &lt;typename I&gt; std::ostream&amp; operator&lt;&lt; (std::ostream&amp; os, const rational&lt;I&gt;&amp; r);
// Type conversion
template &lt;typename T, typename I&gt; T rational_cast (const rational&lt;I&gt;&amp; r); // constexpr since C++11
</pre>
<h2><a name="Rationale">Rationale</a></h2>
Numbers come in many different forms. The most basic forms are natural numbers
(non-negative "whole" numbers), integers and real numbers. These types are
approximated by the C++ built-in types <b>unsigned int</b>, <b>int</b>, and
<b>float</b> (and their various equivalents in different sizes).
<p>The C++ Standard Library extends the range of numeric types available by
providing the <b>complex</b> type.
<p>This library provides a further numeric type, the <b>rational</b> numbers.
<p>The <b>rational</b> class is actually a implemented as a template, in a
similar manner to the standard <b>complex</b> class.
<h2><a name="Background">Background</a></h2>
The mathematical concept of a rational number is what is commonly thought of
as a fraction - that is, a number which can be represented as the ratio of two
integers. This concept is distinct from that of a real number, which can take
on many more values (for example, the square root of 2, which cannot be
represented as a fraction).
<p>
Computers cannot represent mathematical concepts exactly - there are always
compromises to be made. Machine integers have a limited range of values (often
32 bits), and machine approximations to reals are limited in precision. The
compromises have differing motivations - machine integers allow exact
calculation, but with a limited range, whereas machine reals allow a much
greater range, but at the expense of exactness.
<p>
The rational number class provides an alternative compromise. Calculations
with rationals are exact, but there are limitations on the available range. To
be precise, rational numbers are exact as long as the numerator and
denominator (which are always held in normalized form, with no common factors)
are within the range of the underlying integer type. When values go outside
these bounds, overflow occurs and the results are undefined.
<p>
The rational number class is a template to allow the programmer to control the
overflow behaviour somewhat. If an unlimited precision integer type is
available, rational numbers based on it will never overflow (modulo resource
limits) and will provide exact calculations in all circumstances.
<h2><a name="Integer Type Requirements">Integer Type Requirements</a></h2>
<p> The rational type takes a single template type parameter I. This is the
<em>underlying integer type</em> for the rational type. Any of the built-in
integer types provided by the C++ implementation are supported as values for
I. User-defined types may also be used, but users should be aware that the
performance characteristics of the rational class are highly dependent upon
the performance characteristics of the underlying integer type (often in
complex ways - for specific notes, see the <a href="#Performance">Performance</a>
section below). Note: Should the boost library support an unlimited-precision
integer type in the future, this type will be fully supported as the underlying
integer type for the rational class.
</p>
<p>
A user-defined integer type which is to be used as the underlying integer type
for the rational type must be a model of the following concepts.
</p>
<ul>
<li>Assignable
<li>Default Constructible
<li>Equality Comparable
<li>LessThan Comparable
</ul>
<p>
Furthermore, I must be an <em>integer-like</em> type, that is the following
expressions must be valid for any two values n and m of type I, with the
"expected" semantics.
<ul>
<li><code>n + m</code>
<li><code>n - m</code>
<li><code>n * m</code>
<li><code>n / m</code> (must truncate; must be nonnegative if <var>n</var> and
<var>m</var> are positive)
<li><code>n % m</code> (must be nonnegative if <var>n</var> and <var>m</var>
are positive)
<li>Assignment versions of the above
<li><code>+n</code>, <code>-n</code>
<li><code>!n</code> (must be <code>true</code> iff <var>n</var> is zero)
</ul>
<p>
There must be <em>zero</em> and <em>one</em> values available for I. It should
be possible to generate these as <tt>I(0)</tt> and <tt>I(1)</tt>,
respectively. <em>Note:</em> This does not imply that I needs to have an
implicit conversion from integer - an <tt>explicit</tt> constructor is
adequate.
<p>
It is valid for I to be an unsigned type. In that case, the derived rational
class will also be unsigned. Underflow behaviour of subtraction, where results
would otherwise be negative, is unpredictable in this case.
<ul>
<li>
The implementation of rational_cast&lt;T&gt;(rational&lt;I&gt;) relies on the
ability to static_cast from type I to type T, and on the expression x/y being
valid for any two values of type T.
<li>
The input and output operators rely on the existence of corresponding input
and output operators for type I.
</ul>
<p>
The <code>std::numeric_limits&lt;I&gt;</code> specialization must exist (and be
visible before <code>boost::rational&lt;I&gt;</code> needs to be specified).
The value of its <code>is_specialized</code> static data member must be
<var>true</var> and the value of its <code>is_signed</code> static data member
must be accurate.
<h2><a name="Interface">Interface</a></h2>
<h3><a name="Utility functions">Utility functions</a></h3>
<p>Two utility function templates may be provided, that should work with <a
href="#Integer%20Type%20Requirements">any type that can be used</a> with the
<code>boost::rational&lt;&gt;</code> class template.</p>
<table summary="Common-factor utility functions">
<tr>
<td width=5%></td>
<td><tt>gcd(n, m)</tt></td>
<td width=5%></td>
<td>The greatest common divisor of n and m</td>
</tr>
<tr>
<td width=5%></td>
<td><tt>lcm(n, m)</tt></td>
<td width=5%></td>
<td>The least common multiple of n and m</td>
</tr>
</table>
<p>These function templates now forward calls to their equivalents in the <a
href="../integer/">Boost.Integer library</a>. Their presence can be controlled at
compile time with the <code>BOOST_CONTROL_RATIONAL_HAS_GCD</code> preprocessor
constant.
<h3><a name="Constructors">Constructors</a></h3>
<p>Rationals can be constructed from zero, one, or two integer arguments;
representing default construction as zero, conversion from an integer posing as
the numerator with an implicit denominator of one, or a numerator and
denominator pair in that order, respectively. An integer argument should be of
the rational's integer type, or implicitly convertible to that type. (For the
two-argument constructor, any needed conversions are evaluated independently,
of course.) The components are stored in normalized form.
<p>Rationals can also be constructed from another rational. When the source and
destination underlying integer types match, the automatically-defined copy- or
move-constructor is used. Otherwise, a converting constructor template is used.
The constructor does member-wise initialization of the numerator and denominator.
Component-level conversions that are marked <code>explicit</code> are fine. When
the conversion ends up value-preserving, it is already normalized; but a check
for normalization is performed in case value-preservation is violated.
<p>These imply that the following statements are valid:
<pre>
I n, d;
rational&lt;I&gt; zero;
rational&lt;I&gt; r1(n);
rational&lt;I&gt; r2(n, d);
rational&lt;J&gt; r3(r2); // assuming J(n) and J(d) are well-formed
</pre>
<p>In C++11, the no-argument constructor, single-argument constructor, and
cross-version constructor template are marked as <code>constexpr</code>, making
them viable in constant-expressions when the initializers (if any) are also constant
expressions (and the necessary operations from the underlying integer type(s)
are <code>constexpr</code>-enabled). Since C++14, all constructors are
<code>constexpr</code>-enabled.
<p>The single-argument constructor is <em>not</em> declared as explicit, so
there is an implicit conversion from the underlying integer type to the
rational type. The two-argument constructor can be considered an implicit
conversion with C++11's uniform initialization syntax, since it is also not
declared explicit. The cross-version constructor template is declared explicit,
so the direction of conversion between two rational instantiations must be
specified.
<h3><a name="Arithmetic operations">Arithmetic operations</a></h3>
All of the standard numeric operators are defined for the <b>rational</b>
class. These include:
<br>
<pre>
+ +=
- -=
* *=
/ /=
++ -- (both prefix and postfix)
== !=
&lt; &gt;
&lt;= &gt;=
Unary: + - !
</pre>
<p>Since C++14, all of these operations are <code>constexpr</code>-enabled.
In C++11, only <code>operator==</code>, <code>operator!=</code>,
unary <code>operator+</code>, and <code>operator!</code> are.
<h3><a name="Input and Output">Input and Output</a></h3>
Input and output operators <tt>&lt;&lt;</tt> and <tt>&gt;&gt;</tt>
are provided. The external representation of a rational is
two integers, separated by a slash (<tt>/</tt>). On input, the format must be
exactly an integer, followed with no intervening whitespace by a slash,
followed (again with no intervening whitespace) by a second integer. The
external representation of an integer is defined by the underlying integer
type.
<h3><a name="In-place assignment">In-place assignment</a></h3>
For any <tt>rational&lt;I&gt; r</tt>, <tt>r.assign(n, m)</tt> provides an
alternate to <tt>r = rational&lt;I&gt;(n, m);</tt>, without a user-specified
construction of a temporary. While this is probably unnecessary for rationals
based on machine integer types, it could offer a saving for rationals based on
unlimited-precision integers, for example.
<p>The function will throw if the given components cannot be formed into a valid
rational number. Otherwise, it could throw only if the component-level move
assignment (in C++11; copy-assignment for earlier C++ versions) can throw. The
strong guarantee is kept if throwing happens in the first part, but there is a
risk of neither the strong nor basic guarantees happening if an exception is
thrown during the component assignments.
<h3><a name="Conversions">Conversions</a></h3>
<p>There is a conversion operator to an unspecified Boolean type (most likely a
member pointer). This operator converts a rational to <code>false</code> if it
represents zero, and <code>true</code> otherwise. This conversion allows a
rational for use as the first argument of operator <code>?:</code>; as either
argument of operators <code>&amp;&amp;</code> or <code>||</code> without
forfeiting short-circuit evaluation; as a condition for a <code>do</code>,
<code>if</code>, <code>while</code>, or <code>for</code> statement; and as a
conditional declaration for <code>if</code>, <code>while</code>, or
<code>for</code> statements. The nature of the type used, and that any names
for that nature are kept private, should prevent any inappropriate non-Boolean
use like numeric or pointer operations or as a <code>switch</code> condition.
<p>There are <em>no other</em> implicit conversions from a rational
type. Besides the explicit cross-version constructor template, there is an
explicit type-conversion function, <tt>rational_cast&lt;T&gt;(r)</tt>. This can
be used as follows:
<pre>
rational&lt;int&gt; r(22,7);
double nearly_pi = boost::rational_cast&lt;double&gt;(r);
</pre>
<p>The <tt>rational_cast&lt;T&gt;</tt> function's behaviour is undefined if the
source rational's numerator or denominator cannot be safely cast to the
appropriate floating point type, or if the division of the numerator and
denominator (in the target floating point type) does not evaluate correctly.
Also, since this function has a custom name, it cannot be called in generic code
for trading between two instantiations of the same class template, unlike the
cross-version constructor.
<p>In essence, all required conversions should be value-preserving, and all
operations should behave "sensibly". If these constraints cannot be met, a
separate user-defined conversion will be more appropriate.
<p>Boolean conversion and <tt>rational_cast</tt> are <code>constexpr</code>-enabled.
<p><em>Implementation note:</em>
<p>The implementation of the rational_cast function was
<pre>
template &lt;typename Float, typename Int&gt;
Float rational_cast(const rational&lt;Int&gt;&amp; src)
{
return static_cast&lt;Float&gt;(src.numerator()) / src.denominator();
}
</pre>
Programs should not be written to depend upon this implementation, however,
especially since this implementation is now obsolete. (It required a mixed-mode
division between types <var>Float</var> and <var>Int</var>, contrary to the <a
href="#Integer%20Type%20Requirements">Integer Type Requirements</a>.)
<h3><a name="Numerator and Denominator">Numerator and Denominator</a></h3>
Finally, access to the internal representation of rationals is provided by
the two member functions <tt>numerator()</tt> and <tt>denominator()</tt>.
These functions are <code>constexpr</code>-enabled.
<p>These functions allow user code to implement any additional required
functionality. In particular, it should be noted that there may be cases where
the above rational_cast operation is inappropriate - particularly in cases
where the rational type is based on an unlimited-precision integer type. In
this case, a specially-written user-defined conversion to floating point will
be more appropriate.
<h2><a name="Performance">Performance</a></h2>
The rational class has been designed with the implicit assumption that the
underlying integer type will act "like" the built in integer types. The
behavioural aspects of this assumption have been explicitly described above,
in the <a href="#Integer%20Type%20Requirements">Integer Type Requirements</a>
section. However, in addition to behavioural assumptions, there are implicit
performance assumptions.
<p> No attempt will be made to provide detailed performance guarantees for the
operations available on the rational class. While it is possible for such
guarantees to be provided (in a similar manner to the performance
specifications of many of the standard library classes) it is by no means
clear that such guarantees will be of significant value to users of the
rational class. Instead, this section will provide a general discussion of the
performance characteristics of the rational class.
<p>There now follows a list of the fundamental operations defined in the
<a href="../../boost/rational.hpp"> &lt;boost/rational.hpp&gt;</a> header
and an informal description of their performance characteristics. Note that
these descriptions are based on the current implementation, and as such should
be considered subject to change.
<ul>
<li>Construction of a rational is essentially just two constructions of the
underlying integer type, plus a normalization.
<li>Increment and decrement operations are essentially as cheap as addition and
subtraction on the underlying integer type.
<li>(In)equality comparison is essentially as cheap as two equality operations
on the underlying integer type.
<li>I/O operations are not cheap, but their performance is essentially
dominated by the I/O time itself.
<li>An (implicit) GCD routine call is essentially a repeated modulus operation.
Its other significant operations are construction, assignment, and comparison
against zero of IntType values. These latter operations are assumed to be
trivial in comparison with the modulus operation.
<li>The (implicit) LCM operation is essentially a GCD plus a multiplication,
division, and comparison.
<li>The addition and subtraction operations are complex. They will require
approximately two gcd operations, 3 divisions, 3 multiplications and an
addition on the underlying integer type.
<li>The multiplication and division operations require two gcd operations, two
multiplications, and four divisions.
<li>The compare-with-integer operation does a single integer division &amp;
modulus pair, at most one extra integer addition and decrement, and at most
three integer comparisons.
<li>The compare-with-rational operation does two double-sized GCD operations,
two extra additions and decrements, and three comparisons in the worst case.
(The GCD operations are double-sized because they are done in piecemeal and the
interim quotients are retained and compared, whereas a direct GCD function only
retains and compares the remainders.)
<li>The final fundamental operation is normalizing a rational. This operation
is performed whenever a rational is constructed (and assigned in place). All
other operations are careful to maintain rationals in a normalized state.
Normalization costs the equivalent of one gcd and two divisions.
</ul>
<p>Note that it is implicitly assumed that operations on IntType have the
"usual" performance characteristics - specifically, that the expensive
operations are multiplication, division, and modulo, with addition and
subtraction being significantly cheaper. It is assumed that construction (from
integer literals 0 and 1, and copy construction) and assignment are relatively
cheap, although some effort is taken to reduce unnecessary construction and
copying. It is also assumed that comparison (particularly against zero) is
cheap.
<p>Integer types which do not conform to these assumptions will not be
particularly effective as the underlying integer type for the rational class.
Specifically, it is likely that performance will be severely sub-optimal.
<h2><a name="Exceptions">Exceptions</a></h2>
Rationals can never have a denominator of zero. (This library does not support
representations for infinity or NaN). Should a rational result ever generate a
denominator of zero, or otherwise fail during normalization, the exception
<tt>boost::bad_rational</tt> (a subclass of <tt>std::domain_error</tt>) is
thrown. This should only occur if the user attempts to explicitly construct a
rational with a denominator of zero, to divide a rational by a zero value, or
generate a negative denominator too large to be normalized. The exception can
be thrown during a cross-instantiation conversion, when at least one of the
components ends up not being value-preserved and the new combination is not
considered normalized.
<p>In addition, if operations on the underlying integer type can generate
exceptions, these will be propagated out of the operations on the rational
class. No particular assumptions should be made - it is only safe to assume
that any exceptions which can be thrown by the integer class could be thrown
by any rational operation. In particular, the rational constructor may throw
exceptions from the underlying integer type as a result of the normalization
step. The only exception to this rule is that the rational destructor will
only throw exceptions which can be thrown by the destructor of the underlying
integer type (usually none).
<p>If the component-level assignment operator(s) can throw, then a rational
object's invariants may be violated if an exception happens during the second
component's assignment. (The <code>assign</code> member function counts here
too.) This violates both the strong and basic guarantees.
<h2><a name="Internal representation">Internal representation</a></h2>
<em>Note:</em> This information is for information only. Programs should not
be written in such a way as to rely on these implementation details.
<p>Internally, rational numbers are stored as a pair (numerator, denominator)
of integers (whose type is specified as the template parameter for the
rational type). Rationals are always stored in fully normalized form (ie,
gcd(numerator,denominator) = 1, and the denominator is always positive).
<h2><a name="Design notes">Design notes</a></h2>
<h3><a name="Minimal Implementation">Minimal Implementation</a></h3>
The rational number class is designed to keep to the basics. The minimal
operations required of a numeric class are provided, along with access to the
underlying representation in the form of the numerator() and denominator()
member functions. With these building-blocks, it is possible to implement any
additional functionality required.
<p>Areas where this minimality consideration has been relaxed are in providing
input/output operators, and rational_cast. The former is generally
uncontroversial. However, there are a number of cases where rational_cast is
not the best possible method for converting a rational to a floating point
value (notably where user-defined types are involved). In those cases, a
user-defined conversion can and should be implemented. There is no need
for such an operation to be named rational_cast, and so the rational_cast
function does <em>not</em> provide the necessary infrastructure to allow for
specialisation/overloading.
<h3><a name="Limited-range integer types">Limited-range integer types</a></h3>
The rational number class is designed for use in conjunction with an
unlimited precision integer class. With such a class, rationals are always
exact, and no problems arise with precision loss, overflow or underflow.
<p>Unfortunately, the C++ standard does not offer such a class <s>(and neither
does boost, at the present time)</s>. It is therefore likely that the rational
number class will in many cases be used with limited-precision integer types,
such as the built-in <tt>int</tt> type.
<p>When used with a limited precision integer type, the rational class suffers
from many of the precision issues which cause difficulty with floating point
types. While it is likely that precision issues will not affect simple uses of
the rational class, users should be aware that such issues exist.
<p>As a simple illustration of the issues associated with limited precision
integers, consider a case where the C++ <tt>int</tt> type is a 32-bit signed
representation. In this case, the smallest possible positive
rational&lt;int&gt; is <tt>1/0x7FFFFFFF</tt>. In other words, the
"granularity" of the rational&lt;int&gt; representation around zero is
approximately 4.66e-10. At the other end of the representable range, the
largest representable rational&lt;int&gt; is <tt>0x7FFFFFFF/1</tt>, and the
next lower representable rational&lt;int&gt; is <tt>0x7FFFFFFE/1</tt>. Thus,
at this end of the representable range, the granularity ia 1. This type of
magnitude-dependent granularity is typical of floating point representations.
However, it does not "feel" natural when using a rational number class.
<p>Limited-precision integer types may raise issues with the range sizes of
their allowable negative values and positive values. If the negative range is
larger, then the extremely-negative numbers will not have an additive inverse in
the positive range, making them unusable as denominator values since they cannot
be normalized to positive values (unless the user is lucky enough that the input
components are not relatively prime pre-normalization).
<p>It is up to the user of a rational type based on a limited-precision integer
type to be aware of, and code in anticipation of, such issues.
<h3><a name="Conversion from floating point">Conversion from floating point</a></h3>
The library does not offer a conversion function from floating point to
rational. A number of requests were received for such a conversion, but
extensive discussions on the boost list reached the conclusion that there was
no "best solution" to the problem. As there is no reason why a user of the
library cannot write their own conversion function which suits their
particular requirements, the decision was taken not to pick any one algorithm
as "standard".
<p>The key issue with any conversion function from a floating point value is
how to handle the loss of precision which is involved in floating point
operations. To provide a concrete example, consider the following code:
<pre>
// These two values could in practice be obtained from user input,
// or from some form of measuring instrument.
double x = 1.0;
double y = 3.0;
double z = x/y;
rational&lt;I&gt; r = rational_from_double(z);
</pre>
<p>The fundamental question is, precisely what rational should r be? A naive
answer is that r should be equal to 1/3. However, this ignores a multitude of
issues.
<p>In the first instance, z is not exactly 1/3. Because of the limitations of
floating point representation, 1/3 is not exactly representable in any of the
common representations for the double type. Should r therefore not contain an
(exact) representation of the actual value represented by z? But will the user
be happy with a value of 33333333333333331/100000000000000000 for r?
<p>Before even considering the above issue, we have to consider the accuracy
of the original values, x and y. If they came from an analog measuring
instrument, for example, they are not infinitely accurate in any case. In such
a case, a rational representation like the above promises far more accuracy
than there is any justification for.
<p>All of this implies that we should be looking for some form of "nearest
simple fraction". Algorithms to determine this sort of value do exist.
However, not all applications want to work like this. In other cases, the
whole point of converting to rational is to obtain an exact representation, in
order to prevent accuracy loss during a series of calculations. In this case,
a completely precise representation is required, regardless of how "unnatural"
the fractions look.
<p>With these conflicting requirements, there is clearly no single solution
which will satisfy all users. Furthermore, the algorithms involved are
relatively complex and specialised, and are best implemented with a good
understanding of the application requirements. All of these factors make such
a function unsuitable for a general-purpose library such as this.
<h3><a name="Absolute Value">Absolute Value</a></h3>
In the first instance, it seems logical to implement
abs(rational&lt;IntType&gt;) in terms of abs(IntType).
However, there are a number of issues which arise with doing so.
<p>The first issue is that, in order to locate the appropriate implementation
of abs(IntType) in the case where IntType is a user-defined type in a user
namespace, Koenig lookup is required. Not all compilers support Koenig lookup
for functions at the current time. For such compilers, clumsy workarounds,
which require cooperation from the user of the rational class, are required to
make things work.
<p>The second, and potentially more serious, issue is that for non-standard
built-in integer types (for example, 64-bit integer types such as
<em>long long</em> or <em>__int64</em>), there is no guarantee that the vendor
has supplied a built in abs() function operating on such types. This is a
quality-of-implementation issue, but in practical terms, vendor support for
types such as <em>long long</em> is still very patchy.
<p>As a consequence of these issues, it does not seem worth implementing
abs(rational&lt;IntType&gt;) in terms of abs(IntType). Instead, a simple
implementation with an inline implementation of abs() is used:
<pre>
template &lt;typename IntType&gt;
inline rational&lt;IntType&gt; abs(const rational&lt;IntType&gt;&amp; r)
{
if (r.numerator() &gt;= IntType(0))
return r;
return rational&lt;IntType&gt;(-r.numerator(), r.denominator());
}
</pre>
<p>The same arguments imply that where the absolute value of an IntType is
required elsewhere, the calculation is performed inline.
<h2><a name="References">References</a></h2>
<ul>
<li>The rational number header itself: <a href="../../boost/rational.hpp">rational.hpp</a>
<li>Some example code: <a href="test/rational_example.cpp">rational_example.cpp</a>
<li>The regression test: <a href="test/rational_test.cpp">rational_test.cpp</a>
</ul>
<h2><a name="History and Acknowledgements">History and Acknowledgements</a></h2>
<p>
In December, 1999, I implemented the initial version of the rational number
class, and submitted it to the <A HREF="http://www.boost.org/">boost.org</A>
mailing list. Some discussion of the implementation took place on the mailing
list. In particular, Andrew D. Jewell pointed out the importance of ensuring
that the risk of overflow was minimised, and provided overflow-free
implementations of most of the basic operations. The name rational_cast was
suggested by Kevlin Henney. Ed Brey provided invaluable comments - not least
in pointing out some fairly stupid typing errors in the original code!</p>
<p>David Abrahams contributed helpful feedback on the documentation.</p>
<p>
A long discussion of the merits of providing a conversion from floating
point to rational took place on the boost list in November 2000. Key
contributors included Reggie Seagraves, Lutz Kettner and Daniel Frey (although
most of the boost list seemed to get involved at one point or another!). Even
though the end result was a decision <em>not</em> to implement anything, the
discussion was very valuable in understanding the issues.
</p>
<p>
Stephen Silver contributed useful experience on using the rational class
with a user-defined integer type.
</p>
<p>
Nickolay Mladenov provided the current implementation of operator+= and
operator-=.
</p>
<p>
Discussion of the issues surrounding Koenig lookup and std::swap took place
on the boost list in January 2001.
</p>
<p>
Daryle Walker provided a Boolean conversion operator, so that a rational can
be used in the same Boolean contexts as the built-in numeric types, in December
2005. He added the cross-instantiation constructor template in August 2013.
</p>
<p>
July 2014: Updated numerator/denominator accessors to return values by constant
reference: this gives a performance improvement when using with multiprecision (class) types.
</p>
<p>
July 2014: Updated to use BOOST_THROW_EXCEPTION uniformly throughout.
</p>
<p>
July 2014: Added support for C++11 constexpr constructors, plus tests to match.
</p>
<p>
Nov 2014: Added support for gcd and lcm of rational numbers.
</p>
<p>
Dec 2016: Reworked constructors and operators to prohibit narrowing implicit
conversions, in particular accidental conversion from floating point types.
</p>
<p>
Oct/Nov 2018: Add more constexpr.
</p>
<p>Revised July 14, 2017</p>
<p>&copy; Copyright Paul Moore 1999-2001; &copy; Daryle Walker 2005, 2013.
Permission to copy, use, modify, sell and distribute this document is granted
provided this copyright notice appears in all copies. This document is provided
&quot;as is&quot; without express or implied warranty, and with no claim as to
its suitability for any purpose.</p>
<!-- boostinspect:nolicense (can't find Paul Moore to change license) -->
</body>
</html>

View File

@@ -0,0 +1,29 @@
# Copyright 2021 Peter Dimov
# Distributed under the Boost Software License, Version 1.0.
# https://www.boost.org/LICENSE_1_0.txt
include(BoostTest OPTIONAL RESULT_VARIABLE HAVE_BOOST_TEST)
if(NOT HAVE_BOOST_TEST)
return()
endif()
set(BOOST_TEST_LINK_LIBRARIES Boost::rational)
boost_test(TYPE run SOURCES rational_example.cpp)
boost_test(TYPE run SOURCES rational_test.cpp LINK_LIBRARIES Boost::unit_test_framework)
boost_test(TYPE run SOURCES constexpr_test.cpp COMPILE_FEATURES cxx_constexpr)
boost_test(TYPE compile-fail SOURCES expected_fail_01.cpp)
boost_test(TYPE compile-fail SOURCES expected_fail_02.cpp)
boost_test(TYPE compile-fail SOURCES expected_fail_03.cpp)
boost_test(TYPE compile-fail SOURCES expected_fail_04.cpp)
boost_test(TYPE compile-fail SOURCES expected_fail_05.cpp)
boost_test(TYPE compile-fail SOURCES expected_fail_06.cpp)
boost_test(TYPE compile-fail SOURCES expected_fail_07.cpp)
boost_test(TYPE compile-fail SOURCES expected_fail_08.cpp)
boost_test(TYPE compile-fail SOURCES expected_fail_09.cpp)
boost_test(TYPE compile-fail SOURCES expected_fail_10.cpp)
boost_test(TYPE compile-fail SOURCES expected_fail_11.cpp)
boost_test(TYPE compile SOURCES expected_compile_12.cpp)

View File

@@ -0,0 +1,25 @@
#~ Copyright Rene Rivera 2008
#~ Distributed under the Boost Software License, Version 1.0.
#~ (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
import testing ;
import ../../config/checks/config : requires ;
test-suite rational
: [ run rational_example.cpp ]
[ run rational_test.cpp
/boost/test//boost_unit_test_framework/<link>static ]
[ run constexpr_test.cpp : : : [ requires cxx11_constexpr ] ]
[ compile-fail expected_fail_01.cpp ]
[ compile-fail expected_fail_02.cpp ]
[ compile-fail expected_fail_03.cpp ]
[ compile-fail expected_fail_04.cpp ]
[ compile-fail expected_fail_05.cpp ]
[ compile-fail expected_fail_06.cpp ]
[ compile-fail expected_fail_07.cpp ]
[ compile-fail expected_fail_08.cpp ]
[ compile-fail expected_fail_09.cpp ]
[ compile-fail expected_fail_10.cpp ]
[ compile-fail expected_fail_11.cpp ]
[ compile expected_compile_12.cpp ]
;

View File

@@ -0,0 +1,29 @@
///////////////////////////////////////////////////////////////////////////////
// Copyright 2015 John Maddock. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include <boost/rational.hpp>
int main()
{
#ifndef BOOST_NO_CXX11_CONSTEXPR
constexpr boost::rational<int> i1;
constexpr boost::rational<int> i2(3);
constexpr boost::rational<long long> i3(i2);
constexpr boost::rational<short> i4(i2);
constexpr boost::rational<long long> i5(23u); // converting constructor
// constexpr boost::rational<short> i6(23u); // Not supported, needs an explicit typecast in constructor.
static_assert(i1.numerator() == 0, "constexpr test");
static_assert(i1.denominator() == 1, "constexpr test");
static_assert(i2.numerator() == 3, "constexpr test");
static_assert(i2.denominator() == 1, "constexpr test");
static_assert(i3.numerator() == 3, "constexpr test");
static_assert(i3.denominator() == 1, "constexpr test");
static_assert(!i1, "constexpr test");
static_assert(i2, "constexpr test");
#endif
return 0;
}

View File

@@ -0,0 +1,24 @@
///////////////////////////////////////////////////////////////////////////////
// Copyright 2019. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
// For more information read https://github.com/boostorg/rational/issues/26
#include <boost/rational.hpp>
void test(const char* text)
{
(void)text;
}
void test(const boost::rational<int>& rational)
{
(void)rational;
}
int main()
{
test("Some text");
return 0;
}

View File

@@ -0,0 +1,11 @@
///////////////////////////////////////////////////////////////////////////////
// Copyright 2015 John Maddock. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include <boost/rational.hpp>
int main()
{
boost::rational<int> rat(3.14);
}

View File

@@ -0,0 +1,12 @@
///////////////////////////////////////////////////////////////////////////////
// Copyright 2015 John Maddock. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include <boost/rational.hpp>
int main()
{
boost::rational<int> rat(2);
rat = 0.5;
}

View File

@@ -0,0 +1,12 @@
///////////////////////////////////////////////////////////////////////////////
// Copyright 2015 John Maddock. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include <boost/rational.hpp>
int main()
{
boost::rational<int> rat(2);
return rat == 0.5;
}

View File

@@ -0,0 +1,12 @@
///////////////////////////////////////////////////////////////////////////////
// Copyright 2015 John Maddock. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include <boost/rational.hpp>
int main()
{
boost::rational<int> rat(2);
rat += 0.5;
}

View File

@@ -0,0 +1,12 @@
///////////////////////////////////////////////////////////////////////////////
// Copyright 2015 John Maddock. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include <boost/rational.hpp>
int main()
{
boost::rational<int> rat(2);
rat -= 0.5;
}

View File

@@ -0,0 +1,12 @@
///////////////////////////////////////////////////////////////////////////////
// Copyright 2015 John Maddock. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include <boost/rational.hpp>
int main()
{
boost::rational<int> rat(2);
rat *= 0.5;
}

View File

@@ -0,0 +1,12 @@
///////////////////////////////////////////////////////////////////////////////
// Copyright 2015 John Maddock. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include <boost/rational.hpp>
int main()
{
boost::rational<int> rat(2);
rat /= 0.5;
}

View File

@@ -0,0 +1,12 @@
///////////////////////////////////////////////////////////////////////////////
// Copyright 2015 John Maddock. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include <boost/rational.hpp>
int main()
{
boost::rational<int> rat(2);
rat = rat + 0.5;
}

View File

@@ -0,0 +1,12 @@
///////////////////////////////////////////////////////////////////////////////
// Copyright 2015 John Maddock. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include <boost/rational.hpp>
int main()
{
boost::rational<int> rat(2);
rat = rat - 0.5;
}

View File

@@ -0,0 +1,12 @@
///////////////////////////////////////////////////////////////////////////////
// Copyright 2015 John Maddock. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include <boost/rational.hpp>
int main()
{
boost::rational<int> rat(2);
rat = rat / 0.5;
}

View File

@@ -0,0 +1,12 @@
///////////////////////////////////////////////////////////////////////////////
// Copyright 2015 John Maddock. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include <boost/rational.hpp>
int main()
{
boost::rational<int> rat(2);
rat = rat * 0.5;
}

View File

@@ -0,0 +1,108 @@
// rational number example program ----------------------------------------//
// (C) Copyright Paul Moore 1999. Permission to copy, use, modify, sell
// and distribute this software is granted provided this copyright notice
// appears in all copies. This software is provided "as is" without express or
// implied warranty, and with no claim as to its suitability for any purpose.
// boostinspect:nolicense (don't complain about the lack of a Boost license)
// (Paul Moore hasn't been in contact for years, so there's no way to change the
// license.)
// Revision History
// 14 Dec 99 Initial version
#include <iostream>
#include <cassert>
#include <cstdlib>
#include <boost/config.hpp>
#ifndef BOOST_NO_LIMITS
#include <limits>
#else
#include <limits.h>
#endif
#include <exception>
#include <boost/rational.hpp>
using std::cout;
using std::endl;
using boost::rational;
#ifdef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP
// This is a nasty hack, required because MSVC does not implement "Koenig
// Lookup". Basically, if I call abs(r), the C++ standard says that the
// compiler should look for a definition of abs in the namespace which
// contains r's class (in this case boost) - among other places.
// Koenig Lookup is a relatively recent feature, and other compilers may not
// implement it yet. If so, try including this line.
using boost::abs;
#endif
int main ()
{
rational<int> half(1,2);
rational<int> one(1);
rational<int> two(2);
// Some basic checks
assert(half.numerator() == 1);
assert(half.denominator() == 2);
assert(boost::rational_cast<double>(half) == 0.5);
// Arithmetic
assert(half + half == one);
assert(one - half == half);
assert(two * half == one);
assert(one / half == two);
// With conversions to integer
assert(half+half == 1);
assert(2 * half == one);
assert(2 * half == 1);
assert(one / half == 2);
assert(1 / half == 2);
// Sign handling
rational<int> minus_half(-1,2);
assert(-half == minus_half);
assert(abs(minus_half) == half);
// Do we avoid overflow?
#ifndef BOOST_NO_LIMITS
int maxint = (std::numeric_limits<int>::max)();
#else
int maxint = INT_MAX;
#endif
rational<int> big(maxint, 2);
assert(2 * big == maxint);
// Print some of the above results
cout << half << "+" << half << "=" << one << endl;
cout << one << "-" << half << "=" << half << endl;
cout << two << "*" << half << "=" << one << endl;
cout << one << "/" << half << "=" << two << endl;
cout << "abs(" << minus_half << ")=" << half << endl;
cout << "2 * " << big << "=" << maxint
<< " (rational: " << rational<int>(maxint) << ")" << endl;
// Some extras
rational<int> pi(22,7);
cout << "pi = " << boost::rational_cast<double>(pi) << " (nearly)" << endl;
// Exception handling
try {
rational<int> r; // Forgot to initialise - set to 0
r = 1/r; // Boom!
}
catch (const boost::bad_rational &e) {
cout << "Bad rational, as expected: " << e.what() << endl;
}
catch (...) {
cout << "Wrong exception raised!" << endl;
}
return 0;
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,7 @@
-- Downloading https://github.com/boostorg/rational/archive/boost-1.79.0.tar.gz -> boostorg-rational-boost-1.79.0.tar.gz...
-- Extracting source D:/a/1/s/externals/vcpkg/downloads/boostorg-rational-boost-1.79.0.tar.gz
-- Using source at D:/a/1/s/externals/vcpkg/buildtrees/boost-rational/src/ost-1.79.0-91e0df0347.clean
-- Copying headers
-- Copying headers done
-- Installing: D:/a/1/s/externals/vcpkg/packages/boost-rational_x64-windows/share/boost-rational/usage
-- Installing: D:/a/1/s/externals/vcpkg/packages/boost-rational_x64-windows/share/boost-rational/copyright

View File

@@ -0,0 +1,20 @@
boost-assert a50eed453b8be6c8932fb3d5f8feaf194a2ebeaed7982db4e36e3ba17f3ec107
boost-config 797535e8975ed7cf5bbe11d9f7fe26caa5da8fe819888564758d82a21109fade
boost-core 498aea0b6b68bcfe1ec683e76c2f0d32477dfe9ba958f518980ff806b6faba90
boost-integer 7a387f2417014a6cf56a8a8cd689c8153efaaf93ea6beba8f390f5b9577da9cb
boost-static-assert 795e87a155fce50821163bc84e802f28dce54e4af6a3a86045f9ecec76ad4c95
boost-throw-exception 4bb4a0182f0f071c3c1ffd9cbd82fbc3bc7db4a35346f930bbe504e7e3a94e0a
boost-type-traits 74f62124585467fbb6c4fa16015164d11e1a079d6bdb70ec1c3fe7cf65b9a594
boost-utility cbe2d95223a1f8fb253145878922052018dccca3926ffb59d0e20676d6b0d3ac
boost-vcpkg-helpers c81c7b003df356a1a120a7c0c2f5a2ac95f3c33b006a2a5b4c02dcf0c9f3deaa
cmake 3.23.2
features core
portfile.cmake 4cae7d1f838508121728ce1197601a0c1b96a02e964bdd38026511e4046c8269
ports.cmake 366c60b768113102408b32ac1d7c7b48ef7d30a477af2a220ecc222d9ffa3166
post_build_checks 2
powershell 7.2.5
triplet x64-windows
triplet_abi 4556164a2cd3dd6f4742101eabb46def7e71b6e5856faa88e5d005aac12a803c-c0600b35e024ce0485ed253ef5419f3686f7257cfb58cb6a24febcb600fc4b4c-27ebd443f77a6c449168adfa6ce8def60cf46e88
vcpkg.json 075a7c2de3ff99ee343924860f058fe107a67087a61cf270b73da7bbd0941992
vcpkg_from_git 0aab20e34e84d52ba4763f009e539bfa8f418c41c918c8cf700156f1a8551a10
vcpkg_from_github b743742296a114ea1b18ae99672e02f142c4eb2bef7f57d36c038bedbfb0502f