#![allow(unknown_lints)]
#![cfg_attr(not(test), no_std)]
#![deny(warnings)]
#[cfg(test)]
extern crate core;
#[cfg(test)]
#[macro_use]
extern crate quickcheck;
use core::mem;
use core::{f32, f64};
#[cfg(test)]
mod m;
#[cfg(test)]
#[macro_use]
mod qc;
mod ll;
pub trait Float {
fn abs(self) -> Self;
fn atan(self) -> Self;
fn atan2(self, Self) -> Self;
fn is_infinite(self) -> bool;
fn is_nan(self) -> bool;
fn sqrt(self) -> Self;
}
macro_rules! float {
($ty:ident,
atan = $atan:ident,
atan2 = $atan2:ident,
fabs = $fabs:ident,
sqrt = $sqrt:ident) => {
impl Float for $ty {
fn abs(self) -> Self {
ll::$fabs(self)
}
fn atan(self) -> Self {
ll::$atan(self)
}
fn atan2(self, other: Self) -> Self {
ll::$atan2(self, other)
}
fn is_infinite(self) -> bool {
self == $ty::INFINITY || self == $ty::NEG_INFINITY
}
fn is_nan(self) -> bool {
#![allow(eq_op)]
self != self
}
fn sqrt(self) -> Self {
ll::$sqrt(self)
}
}
}
}
float!(f32,
atan = atanf,
atan2 = atan2f,
fabs = fabsf,
sqrt = sqrtf);
float!(f64, atan = atan, atan2 = atan2, fabs = fabs, sqrt = sqrt);
trait FloatExt {
type Int;
fn bits() -> u32;
#[cfg(test)]
fn eq_repr(self, Self) -> bool;
fn exponent(self) -> i16;
fn exponent_bias() -> u32;
fn exponent_bits() -> u32;
fn exponent_mask() -> Self::Int;
fn from_parts(sign: Sign,
exponent: Self::Int,
significand: Self::Int)
-> Self;
fn from_repr(Self::Int) -> Self;
fn repr(self) -> Self::Int;
fn sign(self) -> Sign;
fn sign_mask() -> Self::Int;
fn significand_bits() -> u32;
fn significand_mask() -> Self::Int;
}
macro_rules! float_ext {
($float_ty:ident,
repr_ty = $repr_ty:ident,
exponent_bits = $exponent_bits:expr,
significand_bits = $significand_bits:expr) => {
impl FloatExt for $float_ty {
type Int = $repr_ty;
fn bits() -> u32 {
1 + Self::exponent_bits() + Self::significand_bits()
}
#[cfg(test)]
fn eq_repr(self, rhs: Self) -> bool {
if self.is_nan() && rhs.is_nan() {
true
} else {
let (lhs, rhs) = (self.repr(), rhs.repr());
lhs == rhs || (lhs > rhs && lhs - rhs == 1) ||
(rhs > lhs && rhs - lhs == 1)
}
}
fn exponent(self) -> i16 {
((self.repr() & Self::exponent_mask()) >>
Self::significand_bits()) as i16 -
Self::exponent_bias() as i16
}
fn exponent_bias() -> u32 {
(1 << (Self::exponent_bits() - 1)) - 1
}
fn exponent_bits() -> u32 {
$exponent_bits
}
fn exponent_mask() -> Self::Int {
((1 << Self::exponent_bits()) - 1) << Self::significand_bits()
}
fn from_parts(sign: Sign,
exponent: Self::Int,
significand: Self::Int) -> Self {
Self::from_repr(sign.$repr_ty() |
exponent & Self::exponent_mask() |
significand & Self::significand_mask())
}
fn from_repr(x: Self::Int) -> Self {
unsafe { mem::transmute(x) }
}
fn repr(self) -> Self::Int {
unsafe { mem::transmute(self) }
}
fn sign(self) -> Sign {
if self.repr() >> (Self::bits() - 1) == 0 {
Sign::Positive
} else {
Sign::Negative
}
}
fn sign_mask() -> Self::Int {
(1 << (Self::bits() - 1)) - 1
}
fn significand_bits() -> u32 {
$significand_bits
}
fn significand_mask() -> Self::Int {
(1 << Self::significand_bits()) - 1
}
}
}
}
float_ext!(f32, repr_ty = u32, exponent_bits = 8, significand_bits = 23);
float_ext!(f64,
repr_ty = u64,
exponent_bits = 11,
significand_bits = 52);
#[derive(Eq, PartialEq)]
enum Sign {
Negative,
Positive,
}
impl Sign {
#[cfg(test)]
fn from_bool(x: bool) -> Self {
if x { Sign::Negative } else { Sign::Positive }
}
fn u32(self) -> u32 {
match self {
Sign::Positive => 0,
Sign::Negative => 1 << 31,
}
}
fn u64(self) -> u64 {
match self {
Sign::Positive => 0,
Sign::Negative => 1 << 63,
}
}
}