Stability | experimental |
---|---|

Safe Haskell | None |

Language | Haskell98 |

- data SciRatio a b
- type SciRational = SciRatio Rational Integer
- (.^) :: (Fractional a, Real a, Integral b) => a -> b -> SciRatio a b
- fracSignificand :: SciRatio a b -> a
- base10Exponent :: SciRatio a b -> b
- (^!) :: (Real a, Integral b, Integral c) => SciRatio a b -> c -> SciRatio a b
- (^^!) :: (Fractional a, Real a, Integral b, Integral c) => SciRatio a b -> c -> SciRatio a b
- fromSciRatio :: (Real a, Integral b, Fractional c) => SciRatio a b -> c
- factorizeBase :: (Integral a, Integral b) => a -> a -> (a, b)
- ilogBase :: (Integral a, Integral b) => a -> a -> b
- intLog :: (Integral a, Integral b) => a -> a -> (a, b)

# The `SciRatio`

type

Represents a fractional number stored in scientific notation: a product of a fractional significand and an integral power of 10.

- The significand has type
`a`

and should be both

and`Fractional`

. Although this could be a floating-point type, it is not recommended as floating-points use inexact arithmetic and strange bugs will occur as a result.`Real`

- The exponent has type
`b`

and should be

.`Integral`

behaves in the same way as an ordinary `SciRatio`

and supports the same operations. The main property is that it is more
efficient than `Ratio`

when the exponent is large:`Ratio`

`>>>`

`5 .^ 99999999 :: SciRational -- works fine`

`>>>`

`5e99999999 :: Rational -- takes forever`

Specialized functions are provided in cases where they can be implemented more efficiently than the default implementation.

The number is always stored in a unique, canonical form: the significand shall never contain factors of 2 and 5 simultaneously, and their multiplicities shall always be nonnegative. (The significand is treated as a rational number factorized into a product of prime numbers with integral exponents that are not necessarily positive.)

**Note**: If inputs differ greatly in magnitude, `(`

and `+`

)`(`

can
be quite slow: complexity is linear with the absolute
difference of the exponents. Furthermore, the complexity of
`-`

)

is linear with the magnitude of the exponent.
These also apply to any functions that indirectly use these
operations (including all operations in `toRational`

and
`RealFrac`

).`Enum`

(Fractional a, Real a, Integral b) => Enum (SciRatio a b) | |

(Eq a, Eq b) => Eq (SciRatio a b) | |

(Fractional a, Real a, Integral b) => Fractional (SciRatio a b) | |

(Fractional a, Real a, Integral b) => Num (SciRatio a b) | |

(Real a, Integral b, Ord a) => Ord (SciRatio a b) | |

(Fractional a, Real a, Integral b, Read a, Read b) => Read (SciRatio a b) | |

(Fractional a, Real a, Integral b) => Real (SciRatio a b) | |

(Fractional a, Real a, Integral b) => RealFrac (SciRatio a b) | |

(Show a, Show b) => Show (SciRatio a b) | |

(Hashable a, Hashable b) => Hashable (SciRatio a b) |

:: (Fractional a, Real a, Integral b) | |

=> a | significand |

-> b | exponent |

-> SciRatio a b |

Construct a number such that
`significand .^ exponent == significand * 10 ^^ exponent`

.

fracSignificand :: SciRatio a b -> a Source

Extract the fractional significand.

base10Exponent :: SciRatio a b -> b Source

Extract the base-10 exponent.

# Specialized functions

(^!) :: (Real a, Integral b, Integral c) => SciRatio a b -> c -> SciRatio a b infixr 8 Source

Specialized, more efficient version of `(`

.`^`

)

(^^!) :: (Fractional a, Real a, Integral b, Integral c) => SciRatio a b -> c -> SciRatio a b infixr 8 Source

Specialized, more efficient version of `(`

.`^^`

)

fromSciRatio :: (Real a, Integral b, Fractional c) => SciRatio a b -> c Source

Convert into a `Fractional`

number.

This is similar to `realToFrac`

but much more efficient for large
exponents.

# Miscellaneous utilities

Factorize a nonzero integer into a significand and a power of the base such that the exponent is maximized:

inputInteger = significand * base ^ exponent

That is, the significand shall not divisible by the base. The base must be greater than one.

Calculate the floored logarithm of a positive integer. The base must be greater than one.

# Deprecated

intLog :: (Integral a, Integral b) => a -> a -> (a, b) Source

Deprecated: use

instead.`factorizeBase`

Alias of

.`factorizeBase`

Note: Despite what the name suggests, the function does *not* compute the
floored logarithm.