MyNixOS website logo
Description

Convert Decimals to Fractions.

Provides functions for converting decimals to a matrix of numerators and denominators or a character vector of fractions. Supports mixed or improper fractions, finding common denominators for vectors of fractions, limiting denominators to powers of ten, and limiting denominators to a maximum value. Also includes helper functions for finding the least common multiple and greatest common divisor for a vector of integers. Implemented using C++ for maximum speed.

fracture

License:MIT R buildstatus Dependencies

Convert decimals to fractions in R

Installation

You can install the released version of fracture from CRAN with:

install.packages("fracture")

or the development version from GitHub with:

# install.packages("remotes")
remotes::install_github("rossellhayes/fracture")

Usage

Convert decimals to a character vector of fractions

fracture converts decimals into fractions.

fracture(0.5)
#> [1] 1/2

fracture((1:11) / 12)
#>  [1] 1/12  1/6   1/4   1/3   5/12  1/2   7/12  2/3   3/4   5/6   11/12

Math with fractures

fractures are implemented using an S3 class. This means we can perform mathematical operations on them like real fractions.

fracture(0.25) * 2
#> [1] 1/2

fracture(0.25) + fracture(1/6)
#> [1] 5/12

Stylish fractures

frac_style() uses Unicode to provide stylish formatting for inline fractions.

`r frac_style(pi, mixed = TRUE, max_denom = 500)`

3 ¹⁶/₁₁₃

Arguments

Additional arguments help you get exactly the result you expect:

Set denominator

fracture((1:12) / 12, denom = 100)
#>  [1] 8/100   17/100  25/100  33/100  42/100  50/100  58/100  67/100  75/100 
#> [10] 83/100  92/100  100/100

Common denominators

fracture((1:12) / 12, common_denom = TRUE)
#>  [1] 1/12  2/12  3/12  4/12  5/12  6/12  7/12  8/12  9/12  10/12 11/12 12/12

Base-10 denominators

fracture(1 / (2:12), base_10 = TRUE)
#>  [1] 5/10             3333333/10000000 25/100           2/10            
#>  [5] 1666667/10000000 1428571/10000000 125/1000         1111111/10000000
#>  [9] 1/10             909091/10000000  833333/10000000

Maximum denominators

fracture(sqrt(1 / (1:12)), max_denom = 100)
#>  [1] 1/1   70/99 56/97 1/2   17/38 20/49 31/82 35/99 1/3   6/19  19/63 28/97

Mixed fractions

fracture((1:9) / 3, mixed = TRUE)
#> [1] "1/3"   "2/3"   "1"     "1 1/3" "1 2/3" "2"     "2 1/3" "2 2/3" "3"

Convert decimals to a fraction matrix

For more advanced work, you may prefer to work with a fraction matrix:

frac_mat((1:11) / 12)
#>             [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11]
#> numerator      1    1    1    1    5    1    7    2    3     5    11
#> denominator   12    6    4    3   12    2   12    3    4     6    12

frac_mat() accepts all the same arguments as fracture().

When mixed fractions are used, frac_mat() has three rows:

frac_mat((1:9) / 3, mixed = TRUE, common_denom = TRUE)
#>             [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9]
#> integer        0    0    1    1    1    2    2    2    3
#> numerator      1    2    0    1    2    0    1    2    0
#> denominator    3    3    3    3    3    3    3    3    3

Just a fun example

Use fracture to find the best approximations of π for each maximum denominator.

unique(purrr::map_chr(1:50000, ~ fracture(pi, max_denom = .x)))
#>  [1] "3/1"          "6/2"          "9/3"          "12/4"         "15/5"        
#>  [6] "18/6"         "22/7"         "333/106"      "355/113"      "103993/33102"
#> [11] "104348/33215"

Isn’t is interesting that there’s such a wide gap between ³⁵⁵/₁₁₃ and ¹⁰³⁹⁹³/₃₃₁₀₂?

Advantages 🚀

fracture is implemented using optimized C++ with Rcpp and S3 methods. This allows it to run faster than alternatives like MASS::fractions() or fractional::fractional().*

# Performance with a single value
single_benchmark
#> # A tibble: 3 × 6
#>   expression                            min median `itr/sec` mem_alloc `gc/sec`
#>   <bch:expr>                          <dbl>  <dbl>     <dbl>     <dbl>    <dbl>
#> 1 print(fracture(x[1]))                1      1         1.47       1       1.50
#> 2 print(MASS::fractions(x[1]))         1.38   1.37      1.06      26.4     2.50
#> 3 print(fractional::fractional(x[1]))  1.29   1.40      1         18.3     1

# Performance with a vector of length 1000
vector_benchmark
#> # A tibble: 3 × 6
#>   expression                         min median `itr/sec` mem_alloc `gc/sec`
#>   <bch:expr>                       <dbl>  <dbl>     <dbl>     <dbl>    <dbl>
#> 1 print(fracture(x))                1      1         2.37      1        1   
#> 2 print(MASS::fractions(x))         3.29   1.82      1.29      6.47     1.64
#> 3 print(fractional::fractional(x))  4.25   2.26      1         1.66     1.57

* fractional() does not compute a decimal’s fractional equivalent until it is printed. Therefore, benchmarking the time to print provides a fairer test of the three packages’ capabilities.


Hex sticker fonts are Source Sans and Hasklig.

Please note that fracture is released with a Contributor Code of Conduct. By contributing to this project, you agree to abide by its terms.

Metadata

Version

0.2.1

License

Unknown

Platforms (75)

    Darwin
    FreeBSD
    Genode
    GHCJS
    Linux
    MMIXware
    NetBSD
    none
    OpenBSD
    Redox
    Solaris
    WASI
    Windows
Show all
  • aarch64-darwin
  • aarch64-genode
  • aarch64-linux
  • aarch64-netbsd
  • aarch64-none
  • aarch64_be-none
  • arm-none
  • armv5tel-linux
  • armv6l-linux
  • armv6l-netbsd
  • armv6l-none
  • armv7a-darwin
  • armv7a-linux
  • armv7a-netbsd
  • armv7l-linux
  • armv7l-netbsd
  • avr-none
  • i686-cygwin
  • i686-darwin
  • i686-freebsd
  • i686-genode
  • i686-linux
  • i686-netbsd
  • i686-none
  • i686-openbsd
  • i686-windows
  • javascript-ghcjs
  • loongarch64-linux
  • m68k-linux
  • m68k-netbsd
  • m68k-none
  • microblaze-linux
  • microblaze-none
  • microblazeel-linux
  • microblazeel-none
  • mips-linux
  • mips-none
  • mips64-linux
  • mips64-none
  • mips64el-linux
  • mipsel-linux
  • mipsel-netbsd
  • mmix-mmixware
  • msp430-none
  • or1k-none
  • powerpc-netbsd
  • powerpc-none
  • powerpc64-linux
  • powerpc64le-linux
  • powerpcle-none
  • riscv32-linux
  • riscv32-netbsd
  • riscv32-none
  • riscv64-linux
  • riscv64-netbsd
  • riscv64-none
  • rx-none
  • s390-linux
  • s390-none
  • s390x-linux
  • s390x-none
  • vc4-none
  • wasm32-wasi
  • wasm64-wasi
  • x86_64-cygwin
  • x86_64-darwin
  • x86_64-freebsd
  • x86_64-genode
  • x86_64-linux
  • x86_64-netbsd
  • x86_64-none
  • x86_64-openbsd
  • x86_64-redox
  • x86_64-solaris
  • x86_64-windows