rust/fpnum/src/lib.rs
author nemo
Tue, 30 Apr 2019 09:36:13 -0400
changeset 14859 8d65728c4ed0
parent 14701 5e2c892b0222
child 15211 924f7e38815e
permissions -rw-r--r--
Backed out changeset 13589d529899 So, we only disabled this on the release branch in r29d614a5c9eb due to having discovered it JUST before release. We should fix it properly in default...
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
14627
2e2b31cf0871 make stuff const
alfadur
parents: 14207
diff changeset
     1
use std::{cmp, ops, ops::Shl};
13882
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
     2
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
     3
#[derive(Clone, Debug, Copy)]
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
     4
pub struct FPNum {
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
     5
    is_negative: bool,
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
     6
    value: u64,
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
     7
}
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
     8
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
     9
impl FPNum {
13927
cf28d7a2b7fe add scalar operations
alfadur
parents: 13926
diff changeset
    10
    #[inline]
13928
5fdc41cd0841 make methods public
alfadur
parents: 13927
diff changeset
    11
    pub fn new(numerator: i32, denominator: u32) -> Self {
13882
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
    12
        FPNum::from(numerator) / denominator
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
    13
    }
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
    14
13885
cd39e87d7a80 inline more operators in fpnum
unc0rr
parents: 13884
diff changeset
    15
    #[inline]
13928
5fdc41cd0841 make methods public
alfadur
parents: 13927
diff changeset
    16
    pub fn signum(&self) -> i8 {
13882
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
    17
        if self.is_negative {
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
    18
            -1
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
    19
        } else {
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
    20
            1
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
    21
        }
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
    22
    }
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
    23
13885
cd39e87d7a80 inline more operators in fpnum
unc0rr
parents: 13884
diff changeset
    24
    #[inline]
14627
2e2b31cf0871 make stuff const
alfadur
parents: 14207
diff changeset
    25
    pub const fn is_negative(&self) -> bool {
13882
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
    26
        self.is_negative
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
    27
    }
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
    28
13885
cd39e87d7a80 inline more operators in fpnum
unc0rr
parents: 13884
diff changeset
    29
    #[inline]
14627
2e2b31cf0871 make stuff const
alfadur
parents: 14207
diff changeset
    30
    pub const fn is_positive(&self) -> bool {
13882
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
    31
        !self.is_negative
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
    32
    }
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
    33
13885
cd39e87d7a80 inline more operators in fpnum
unc0rr
parents: 13884
diff changeset
    34
    #[inline]
14627
2e2b31cf0871 make stuff const
alfadur
parents: 14207
diff changeset
    35
    pub const fn is_zero(&self) -> bool {
13882
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
    36
        self.value == 0
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
    37
    }
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
    38
13885
cd39e87d7a80 inline more operators in fpnum
unc0rr
parents: 13884
diff changeset
    39
    #[inline]
14627
2e2b31cf0871 make stuff const
alfadur
parents: 14207
diff changeset
    40
    pub const fn abs(&self) -> Self {
13882
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
    41
        Self {
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
    42
            is_negative: false,
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
    43
            value: self.value,
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
    44
        }
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
    45
    }
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
    46
13885
cd39e87d7a80 inline more operators in fpnum
unc0rr
parents: 13884
diff changeset
    47
    #[inline]
14139
37c99587825d Implement BeizerCurveSegments, no tests
unc0rr
parents: 14122
diff changeset
    48
    pub fn round(&self) -> i32 {
13882
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
    49
        if self.is_negative {
14139
37c99587825d Implement BeizerCurveSegments, no tests
unc0rr
parents: 14122
diff changeset
    50
            -((self.value >> 32) as i32)
13882
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
    51
        } else {
14139
37c99587825d Implement BeizerCurveSegments, no tests
unc0rr
parents: 14122
diff changeset
    52
            (self.value >> 32) as i32
13882
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
    53
        }
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
    54
    }
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
    55
13885
cd39e87d7a80 inline more operators in fpnum
unc0rr
parents: 13884
diff changeset
    56
    #[inline]
14627
2e2b31cf0871 make stuff const
alfadur
parents: 14207
diff changeset
    57
    pub const fn abs_round(&self) -> u32 {
14081
5d42204ac35e Start convertion of FindPoint()
unC0Rr
parents: 13939
diff changeset
    58
        (self.value >> 32) as u32
5d42204ac35e Start convertion of FindPoint()
unC0Rr
parents: 13939
diff changeset
    59
    }
5d42204ac35e Start convertion of FindPoint()
unC0Rr
parents: 13939
diff changeset
    60
5d42204ac35e Start convertion of FindPoint()
unC0Rr
parents: 13939
diff changeset
    61
    #[inline]
13928
5fdc41cd0841 make methods public
alfadur
parents: 13927
diff changeset
    62
    pub fn sqr(&self) -> Self {
13882
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
    63
        Self {
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
    64
            is_negative: false,
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
    65
            value: ((self.value as u128).pow(2) >> 32) as u64,
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
    66
        }
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
    67
    }
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
    68
13928
5fdc41cd0841 make methods public
alfadur
parents: 13927
diff changeset
    69
    pub fn sqrt(&self) -> Self {
13882
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
    70
        debug_assert!(!self.is_negative);
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
    71
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
    72
        let mut t: u64 = 0x4000000000000000;
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
    73
        let mut r: u64 = 0;
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
    74
        let mut q = self.value;
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
    75
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
    76
        for _ in 0..32 {
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
    77
            let s = r + t;
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
    78
            r >>= 1;
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
    79
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
    80
            if s <= q {
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
    81
                q -= s;
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
    82
                r += t;
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
    83
            }
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
    84
            t >>= 2;
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
    85
        }
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
    86
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
    87
        Self {
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
    88
            is_negative: false,
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
    89
            value: r << 16,
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
    90
        }
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
    91
    }
13925
2ee07e751171 add more fpnum functions
alfadur
parents: 13905
diff changeset
    92
13927
cf28d7a2b7fe add scalar operations
alfadur
parents: 13926
diff changeset
    93
    #[inline]
14627
2e2b31cf0871 make stuff const
alfadur
parents: 14207
diff changeset
    94
    pub const fn with_sign(&self, is_negative: bool) -> FPNum {
14122
c27461e6a9eb Implement non-overflowing calculations for high values
unc0rr
parents: 14081
diff changeset
    95
        FPNum {
c27461e6a9eb Implement non-overflowing calculations for high values
unc0rr
parents: 14081
diff changeset
    96
            is_negative,
c27461e6a9eb Implement non-overflowing calculations for high values
unc0rr
parents: 14081
diff changeset
    97
            ..*self
c27461e6a9eb Implement non-overflowing calculations for high values
unc0rr
parents: 14081
diff changeset
    98
        }
13925
2ee07e751171 add more fpnum functions
alfadur
parents: 13905
diff changeset
    99
    }
2ee07e751171 add more fpnum functions
alfadur
parents: 13905
diff changeset
   100
2ee07e751171 add more fpnum functions
alfadur
parents: 13905
diff changeset
   101
    #[inline]
14627
2e2b31cf0871 make stuff const
alfadur
parents: 14207
diff changeset
   102
    pub const fn with_sign_as(self, other: FPNum) -> FPNum {
13925
2ee07e751171 add more fpnum functions
alfadur
parents: 13905
diff changeset
   103
        self.with_sign(other.is_negative)
2ee07e751171 add more fpnum functions
alfadur
parents: 13905
diff changeset
   104
    }
13927
cf28d7a2b7fe add scalar operations
alfadur
parents: 13926
diff changeset
   105
cf28d7a2b7fe add scalar operations
alfadur
parents: 13926
diff changeset
   106
    #[inline]
14627
2e2b31cf0871 make stuff const
alfadur
parents: 14207
diff changeset
   107
    pub const fn point(self) -> FPPoint {
13927
cf28d7a2b7fe add scalar operations
alfadur
parents: 13926
diff changeset
   108
        FPPoint::new(self, self)
cf28d7a2b7fe add scalar operations
alfadur
parents: 13926
diff changeset
   109
    }
13882
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   110
}
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   111
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   112
impl From<i32> for FPNum {
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   113
    #[inline]
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   114
    fn from(n: i32) -> Self {
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   115
        FPNum {
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   116
            is_negative: n < 0,
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   117
            value: (n.abs() as u64) << 32,
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   118
        }
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   119
    }
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   120
}
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   121
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   122
impl From<u32> for FPNum {
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   123
    #[inline]
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   124
    fn from(n: u32) -> Self {
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   125
        Self {
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   126
            is_negative: false,
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   127
            value: (n as u64) << 32,
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   128
        }
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   129
    }
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   130
}
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   131
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   132
impl From<FPNum> for f64 {
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   133
    #[inline]
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   134
    fn from(n: FPNum) -> Self {
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   135
        if n.is_negative {
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   136
            n.value as f64 / (-0x10000000 as f64)
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   137
        } else {
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   138
            n.value as f64 / 0x10000000 as f64
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   139
        }
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   140
    }
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   141
}
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   142
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   143
impl PartialEq for FPNum {
13885
cd39e87d7a80 inline more operators in fpnum
unc0rr
parents: 13884
diff changeset
   144
    #[inline]
13882
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   145
    fn eq(&self, other: &Self) -> bool {
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   146
        self.value == other.value && (self.is_negative == other.is_negative || self.value == 0)
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   147
    }
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   148
}
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   149
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   150
impl Eq for FPNum {}
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   151
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   152
impl PartialOrd for FPNum {
13885
cd39e87d7a80 inline more operators in fpnum
unc0rr
parents: 13884
diff changeset
   153
    #[inline]
13882
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   154
    fn partial_cmp(&self, rhs: &Self) -> std::option::Option<std::cmp::Ordering> {
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   155
        Some(self.cmp(rhs))
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   156
    }
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   157
}
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   158
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   159
impl Ord for FPNum {
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   160
    #[inline]
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   161
    fn cmp(&self, rhs: &Self) -> cmp::Ordering {
13884
fbbb4fcd6a75 delegate cmp to rustlib
alfadur
parents: 13883
diff changeset
   162
        #[inline]
fbbb4fcd6a75 delegate cmp to rustlib
alfadur
parents: 13883
diff changeset
   163
        fn extend(n: &FPNum) -> i128 {
fbbb4fcd6a75 delegate cmp to rustlib
alfadur
parents: 13883
diff changeset
   164
            if n.is_negative {
fbbb4fcd6a75 delegate cmp to rustlib
alfadur
parents: 13883
diff changeset
   165
                -(n.value as i128)
13882
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   166
            } else {
13884
fbbb4fcd6a75 delegate cmp to rustlib
alfadur
parents: 13883
diff changeset
   167
                n.value as i128
13882
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   168
            }
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   169
        }
13884
fbbb4fcd6a75 delegate cmp to rustlib
alfadur
parents: 13883
diff changeset
   170
        extend(self).cmp(&(extend(rhs)))
13882
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   171
    }
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   172
}
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   173
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   174
impl ops::Add for FPNum {
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   175
    type Output = Self;
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   176
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   177
    #[inline]
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   178
    fn add(self, rhs: Self) -> Self {
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   179
        if self.is_negative == rhs.is_negative {
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   180
            Self {
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   181
                is_negative: self.is_negative,
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   182
                value: self.value + rhs.value,
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   183
            }
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   184
        } else if self.value > rhs.value {
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   185
            Self {
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   186
                is_negative: self.is_negative,
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   187
                value: self.value - rhs.value,
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   188
            }
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   189
        } else {
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   190
            Self {
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   191
                is_negative: rhs.is_negative,
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   192
                value: rhs.value - self.value,
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   193
            }
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   194
        }
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   195
    }
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   196
}
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   197
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   198
impl ops::Sub for FPNum {
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   199
    type Output = Self;
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   200
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   201
    #[inline]
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   202
    fn sub(self, rhs: Self) -> Self {
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   203
        if self.is_negative == rhs.is_negative {
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   204
            if self.value > rhs.value {
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   205
                Self {
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   206
                    is_negative: self.is_negative,
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   207
                    value: self.value - rhs.value,
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   208
                }
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   209
            } else {
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   210
                Self {
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   211
                    is_negative: !rhs.is_negative,
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   212
                    value: rhs.value - self.value,
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   213
                }
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   214
            }
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   215
        } else {
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   216
            Self {
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   217
                is_negative: self.is_negative,
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   218
                value: self.value + rhs.value,
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   219
            }
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   220
        }
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   221
    }
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   222
}
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   223
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   224
impl ops::Neg for FPNum {
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   225
    type Output = Self;
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   226
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   227
    #[inline]
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   228
    fn neg(self) -> Self {
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   229
        Self {
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   230
            is_negative: !self.is_negative,
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   231
            value: self.value,
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   232
        }
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   233
    }
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   234
}
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   235
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   236
impl ops::Mul for FPNum {
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   237
    type Output = Self;
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   238
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   239
    #[inline]
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   240
    fn mul(self, rhs: Self) -> Self {
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   241
        Self {
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   242
            is_negative: self.is_negative ^ rhs.is_negative,
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   243
            value: ((self.value as u128 * rhs.value as u128) >> 32) as u64,
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   244
        }
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   245
    }
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   246
}
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   247
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   248
impl ops::Mul<i32> for FPNum {
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   249
    type Output = Self;
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   250
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   251
    #[inline]
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   252
    fn mul(self, rhs: i32) -> Self {
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   253
        Self {
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   254
            is_negative: self.is_negative ^ (rhs < 0),
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   255
            value: self.value * rhs.abs() as u64,
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   256
        }
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   257
    }
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   258
}
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   259
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   260
impl ops::Div for FPNum {
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   261
    type Output = Self;
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   262
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   263
    #[inline]
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   264
    fn div(self, rhs: Self) -> Self {
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   265
        Self {
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   266
            is_negative: self.is_negative ^ rhs.is_negative,
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   267
            value: (((self.value as u128) << 32) / rhs.value as u128) as u64,
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   268
        }
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   269
    }
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   270
}
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   271
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   272
impl ops::Div<i32> for FPNum {
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   273
    type Output = Self;
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   274
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   275
    #[inline]
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   276
    fn div(self, rhs: i32) -> Self {
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   277
        Self {
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   278
            is_negative: self.is_negative ^ (rhs < 0),
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   279
            value: self.value / rhs.abs() as u64,
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   280
        }
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   281
    }
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   282
}
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   283
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   284
impl ops::Div<u32> for FPNum {
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   285
    type Output = Self;
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   286
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   287
    #[inline]
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   288
    fn div(self, rhs: u32) -> Self {
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   289
        Self {
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   290
            is_negative: self.is_negative,
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   291
            value: self.value / rhs as u64,
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   292
        }
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   293
    }
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   294
}
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   295
13928
5fdc41cd0841 make methods public
alfadur
parents: 13927
diff changeset
   296
#[macro_export]
13891
9ae1184886db add fpnum literal macro
alfadur
parents: 13885
diff changeset
   297
macro_rules! fp {
14701
5e2c892b0222 allow fp! take denominator tokens
alfadur
parents: 14667
diff changeset
   298
    ($n: literal / $d: tt) => {
14122
c27461e6a9eb Implement non-overflowing calculations for high values
unc0rr
parents: 14081
diff changeset
   299
        FPNum::new($n, $d)
c27461e6a9eb Implement non-overflowing calculations for high values
unc0rr
parents: 14081
diff changeset
   300
    };
14664
def1b9870078 match literals in fp macro
alfadur
parents: 14627
diff changeset
   301
    ($n: literal) => {
14122
c27461e6a9eb Implement non-overflowing calculations for high values
unc0rr
parents: 14081
diff changeset
   302
        FPNum::from($n)
c27461e6a9eb Implement non-overflowing calculations for high values
unc0rr
parents: 14081
diff changeset
   303
    };
13891
9ae1184886db add fpnum literal macro
alfadur
parents: 13885
diff changeset
   304
}
9ae1184886db add fpnum literal macro
alfadur
parents: 13885
diff changeset
   305
13925
2ee07e751171 add more fpnum functions
alfadur
parents: 13905
diff changeset
   306
const LINEARIZE_TRESHOLD: u64 = 0x1_0000;
2ee07e751171 add more fpnum functions
alfadur
parents: 13905
diff changeset
   307
2ee07e751171 add more fpnum functions
alfadur
parents: 13905
diff changeset
   308
#[derive(Clone, Copy, Debug)]
13928
5fdc41cd0841 make methods public
alfadur
parents: 13927
diff changeset
   309
pub struct FPPoint {
13925
2ee07e751171 add more fpnum functions
alfadur
parents: 13905
diff changeset
   310
    x_is_negative: bool,
2ee07e751171 add more fpnum functions
alfadur
parents: 13905
diff changeset
   311
    y_is_negative: bool,
2ee07e751171 add more fpnum functions
alfadur
parents: 13905
diff changeset
   312
    x_value: u64,
2ee07e751171 add more fpnum functions
alfadur
parents: 13905
diff changeset
   313
    y_value: u64,
2ee07e751171 add more fpnum functions
alfadur
parents: 13905
diff changeset
   314
}
2ee07e751171 add more fpnum functions
alfadur
parents: 13905
diff changeset
   315
2ee07e751171 add more fpnum functions
alfadur
parents: 13905
diff changeset
   316
impl FPPoint {
2ee07e751171 add more fpnum functions
alfadur
parents: 13905
diff changeset
   317
    #[inline]
14627
2e2b31cf0871 make stuff const
alfadur
parents: 14207
diff changeset
   318
    pub const fn new(x: FPNum, y: FPNum) -> Self {
13925
2ee07e751171 add more fpnum functions
alfadur
parents: 13905
diff changeset
   319
        Self {
2ee07e751171 add more fpnum functions
alfadur
parents: 13905
diff changeset
   320
            x_is_negative: x.is_negative,
2ee07e751171 add more fpnum functions
alfadur
parents: 13905
diff changeset
   321
            y_is_negative: y.is_negative,
2ee07e751171 add more fpnum functions
alfadur
parents: 13905
diff changeset
   322
            x_value: x.value,
14122
c27461e6a9eb Implement non-overflowing calculations for high values
unc0rr
parents: 14081
diff changeset
   323
            y_value: y.value,
13925
2ee07e751171 add more fpnum functions
alfadur
parents: 13905
diff changeset
   324
        }
2ee07e751171 add more fpnum functions
alfadur
parents: 13905
diff changeset
   325
    }
2ee07e751171 add more fpnum functions
alfadur
parents: 13905
diff changeset
   326
2ee07e751171 add more fpnum functions
alfadur
parents: 13905
diff changeset
   327
    #[inline]
14122
c27461e6a9eb Implement non-overflowing calculations for high values
unc0rr
parents: 14081
diff changeset
   328
    pub fn zero() -> FPPoint {
c27461e6a9eb Implement non-overflowing calculations for high values
unc0rr
parents: 14081
diff changeset
   329
        FPPoint::new(fp!(0), fp!(0))
c27461e6a9eb Implement non-overflowing calculations for high values
unc0rr
parents: 14081
diff changeset
   330
    }
13925
2ee07e751171 add more fpnum functions
alfadur
parents: 13905
diff changeset
   331
2ee07e751171 add more fpnum functions
alfadur
parents: 13905
diff changeset
   332
    #[inline]
14122
c27461e6a9eb Implement non-overflowing calculations for high values
unc0rr
parents: 14081
diff changeset
   333
    pub fn unit_x() -> FPPoint {
c27461e6a9eb Implement non-overflowing calculations for high values
unc0rr
parents: 14081
diff changeset
   334
        FPPoint::new(fp!(1), fp!(0))
c27461e6a9eb Implement non-overflowing calculations for high values
unc0rr
parents: 14081
diff changeset
   335
    }
13925
2ee07e751171 add more fpnum functions
alfadur
parents: 13905
diff changeset
   336
2ee07e751171 add more fpnum functions
alfadur
parents: 13905
diff changeset
   337
    #[inline]
14122
c27461e6a9eb Implement non-overflowing calculations for high values
unc0rr
parents: 14081
diff changeset
   338
    pub fn unit_y() -> FPPoint {
c27461e6a9eb Implement non-overflowing calculations for high values
unc0rr
parents: 14081
diff changeset
   339
        FPPoint::new(fp!(0), fp!(1))
c27461e6a9eb Implement non-overflowing calculations for high values
unc0rr
parents: 14081
diff changeset
   340
    }
13925
2ee07e751171 add more fpnum functions
alfadur
parents: 13905
diff changeset
   341
2ee07e751171 add more fpnum functions
alfadur
parents: 13905
diff changeset
   342
    #[inline]
14627
2e2b31cf0871 make stuff const
alfadur
parents: 14207
diff changeset
   343
    pub const fn x(&self) -> FPNum {
13925
2ee07e751171 add more fpnum functions
alfadur
parents: 13905
diff changeset
   344
        FPNum {
2ee07e751171 add more fpnum functions
alfadur
parents: 13905
diff changeset
   345
            is_negative: self.x_is_negative,
14122
c27461e6a9eb Implement non-overflowing calculations for high values
unc0rr
parents: 14081
diff changeset
   346
            value: self.x_value,
13925
2ee07e751171 add more fpnum functions
alfadur
parents: 13905
diff changeset
   347
        }
2ee07e751171 add more fpnum functions
alfadur
parents: 13905
diff changeset
   348
    }
2ee07e751171 add more fpnum functions
alfadur
parents: 13905
diff changeset
   349
2ee07e751171 add more fpnum functions
alfadur
parents: 13905
diff changeset
   350
    #[inline]
14627
2e2b31cf0871 make stuff const
alfadur
parents: 14207
diff changeset
   351
    pub const fn y(&self) -> FPNum {
13925
2ee07e751171 add more fpnum functions
alfadur
parents: 13905
diff changeset
   352
        FPNum {
2ee07e751171 add more fpnum functions
alfadur
parents: 13905
diff changeset
   353
            is_negative: self.y_is_negative,
14122
c27461e6a9eb Implement non-overflowing calculations for high values
unc0rr
parents: 14081
diff changeset
   354
            value: self.y_value,
13925
2ee07e751171 add more fpnum functions
alfadur
parents: 13905
diff changeset
   355
        }
2ee07e751171 add more fpnum functions
alfadur
parents: 13905
diff changeset
   356
    }
2ee07e751171 add more fpnum functions
alfadur
parents: 13905
diff changeset
   357
2ee07e751171 add more fpnum functions
alfadur
parents: 13905
diff changeset
   358
    #[inline]
14178
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents: 14140
diff changeset
   359
    pub fn is_zero(&self) -> bool {
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents: 14140
diff changeset
   360
        self.x().is_zero() && self.y().is_zero()
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents: 14140
diff changeset
   361
    }
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents: 14140
diff changeset
   362
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents: 14140
diff changeset
   363
    #[inline]
13928
5fdc41cd0841 make methods public
alfadur
parents: 13927
diff changeset
   364
    pub fn max_norm(&self) -> FPNum {
13939
665b4c6612ee fix fppoint.max_norm
alfadur
parents: 13932
diff changeset
   365
        std::cmp::max(self.x().abs(), self.y().abs())
13928
5fdc41cd0841 make methods public
alfadur
parents: 13927
diff changeset
   366
    }
5fdc41cd0841 make methods public
alfadur
parents: 13927
diff changeset
   367
5fdc41cd0841 make methods public
alfadur
parents: 13927
diff changeset
   368
    #[inline]
5fdc41cd0841 make methods public
alfadur
parents: 13927
diff changeset
   369
    pub fn sqr_distance(&self) -> FPNum {
13925
2ee07e751171 add more fpnum functions
alfadur
parents: 13905
diff changeset
   370
        self.x().sqr() + self.y().sqr()
2ee07e751171 add more fpnum functions
alfadur
parents: 13905
diff changeset
   371
    }
2ee07e751171 add more fpnum functions
alfadur
parents: 13905
diff changeset
   372
2ee07e751171 add more fpnum functions
alfadur
parents: 13905
diff changeset
   373
    #[inline]
13928
5fdc41cd0841 make methods public
alfadur
parents: 13927
diff changeset
   374
    pub fn distance(&self) -> FPNum {
13925
2ee07e751171 add more fpnum functions
alfadur
parents: 13905
diff changeset
   375
        let r = self.x_value | self.y_value;
2ee07e751171 add more fpnum functions
alfadur
parents: 13905
diff changeset
   376
        if r < LINEARIZE_TRESHOLD {
2ee07e751171 add more fpnum functions
alfadur
parents: 13905
diff changeset
   377
            FPNum::from(r as u32)
2ee07e751171 add more fpnum functions
alfadur
parents: 13905
diff changeset
   378
        } else {
14122
c27461e6a9eb Implement non-overflowing calculations for high values
unc0rr
parents: 14081
diff changeset
   379
            let mut sqr: u128 = (self.x_value as u128).pow(2) + (self.y_value as u128).pow(2);
c27461e6a9eb Implement non-overflowing calculations for high values
unc0rr
parents: 14081
diff changeset
   380
c27461e6a9eb Implement non-overflowing calculations for high values
unc0rr
parents: 14081
diff changeset
   381
            let mut t: u128 = 0x40000000_00000000_00000000_00000000;
c27461e6a9eb Implement non-overflowing calculations for high values
unc0rr
parents: 14081
diff changeset
   382
            let mut r: u128 = 0;
c27461e6a9eb Implement non-overflowing calculations for high values
unc0rr
parents: 14081
diff changeset
   383
c27461e6a9eb Implement non-overflowing calculations for high values
unc0rr
parents: 14081
diff changeset
   384
            for _ in 0..64 {
c27461e6a9eb Implement non-overflowing calculations for high values
unc0rr
parents: 14081
diff changeset
   385
                let s = r + t;
c27461e6a9eb Implement non-overflowing calculations for high values
unc0rr
parents: 14081
diff changeset
   386
                r >>= 1;
c27461e6a9eb Implement non-overflowing calculations for high values
unc0rr
parents: 14081
diff changeset
   387
c27461e6a9eb Implement non-overflowing calculations for high values
unc0rr
parents: 14081
diff changeset
   388
                if s <= sqr {
c27461e6a9eb Implement non-overflowing calculations for high values
unc0rr
parents: 14081
diff changeset
   389
                    sqr -= s;
c27461e6a9eb Implement non-overflowing calculations for high values
unc0rr
parents: 14081
diff changeset
   390
                    r += t;
c27461e6a9eb Implement non-overflowing calculations for high values
unc0rr
parents: 14081
diff changeset
   391
                }
c27461e6a9eb Implement non-overflowing calculations for high values
unc0rr
parents: 14081
diff changeset
   392
                t >>= 2;
c27461e6a9eb Implement non-overflowing calculations for high values
unc0rr
parents: 14081
diff changeset
   393
            }
c27461e6a9eb Implement non-overflowing calculations for high values
unc0rr
parents: 14081
diff changeset
   394
c27461e6a9eb Implement non-overflowing calculations for high values
unc0rr
parents: 14081
diff changeset
   395
            FPNum {
c27461e6a9eb Implement non-overflowing calculations for high values
unc0rr
parents: 14081
diff changeset
   396
                is_negative: false,
c27461e6a9eb Implement non-overflowing calculations for high values
unc0rr
parents: 14081
diff changeset
   397
                value: r as u64,
c27461e6a9eb Implement non-overflowing calculations for high values
unc0rr
parents: 14081
diff changeset
   398
            }
13925
2ee07e751171 add more fpnum functions
alfadur
parents: 13905
diff changeset
   399
        }
2ee07e751171 add more fpnum functions
alfadur
parents: 13905
diff changeset
   400
    }
2ee07e751171 add more fpnum functions
alfadur
parents: 13905
diff changeset
   401
2ee07e751171 add more fpnum functions
alfadur
parents: 13905
diff changeset
   402
    #[inline]
13928
5fdc41cd0841 make methods public
alfadur
parents: 13927
diff changeset
   403
    pub fn is_in_range(&self, radius: FPNum) -> bool {
5fdc41cd0841 make methods public
alfadur
parents: 13927
diff changeset
   404
        self.max_norm() < radius && self.sqr_distance() < radius.sqr()
13925
2ee07e751171 add more fpnum functions
alfadur
parents: 13905
diff changeset
   405
    }
2ee07e751171 add more fpnum functions
alfadur
parents: 13905
diff changeset
   406
2ee07e751171 add more fpnum functions
alfadur
parents: 13905
diff changeset
   407
    #[inline]
13928
5fdc41cd0841 make methods public
alfadur
parents: 13927
diff changeset
   408
    pub fn dot(&self, other: &FPPoint) -> FPNum {
13925
2ee07e751171 add more fpnum functions
alfadur
parents: 13905
diff changeset
   409
        self.x() * other.x() + self.y() * other.y()
2ee07e751171 add more fpnum functions
alfadur
parents: 13905
diff changeset
   410
    }
2ee07e751171 add more fpnum functions
alfadur
parents: 13905
diff changeset
   411
}
2ee07e751171 add more fpnum functions
alfadur
parents: 13905
diff changeset
   412
2ee07e751171 add more fpnum functions
alfadur
parents: 13905
diff changeset
   413
impl PartialEq for FPPoint {
2ee07e751171 add more fpnum functions
alfadur
parents: 13905
diff changeset
   414
    #[inline]
2ee07e751171 add more fpnum functions
alfadur
parents: 13905
diff changeset
   415
    fn eq(&self, other: &Self) -> bool {
2ee07e751171 add more fpnum functions
alfadur
parents: 13905
diff changeset
   416
        self.x() == other.x() && self.y() == other.y()
2ee07e751171 add more fpnum functions
alfadur
parents: 13905
diff changeset
   417
    }
2ee07e751171 add more fpnum functions
alfadur
parents: 13905
diff changeset
   418
}
2ee07e751171 add more fpnum functions
alfadur
parents: 13905
diff changeset
   419
2ee07e751171 add more fpnum functions
alfadur
parents: 13905
diff changeset
   420
impl Eq for FPPoint {}
2ee07e751171 add more fpnum functions
alfadur
parents: 13905
diff changeset
   421
2ee07e751171 add more fpnum functions
alfadur
parents: 13905
diff changeset
   422
impl ops::Neg for FPPoint {
2ee07e751171 add more fpnum functions
alfadur
parents: 13905
diff changeset
   423
    type Output = Self;
2ee07e751171 add more fpnum functions
alfadur
parents: 13905
diff changeset
   424
2ee07e751171 add more fpnum functions
alfadur
parents: 13905
diff changeset
   425
    #[inline]
2ee07e751171 add more fpnum functions
alfadur
parents: 13905
diff changeset
   426
    fn neg(self) -> Self {
2ee07e751171 add more fpnum functions
alfadur
parents: 13905
diff changeset
   427
        Self::new(-self.x(), -self.y())
2ee07e751171 add more fpnum functions
alfadur
parents: 13905
diff changeset
   428
    }
2ee07e751171 add more fpnum functions
alfadur
parents: 13905
diff changeset
   429
}
2ee07e751171 add more fpnum functions
alfadur
parents: 13905
diff changeset
   430
2ee07e751171 add more fpnum functions
alfadur
parents: 13905
diff changeset
   431
macro_rules! bin_op_impl {
13927
cf28d7a2b7fe add scalar operations
alfadur
parents: 13926
diff changeset
   432
    ($op: ty, $name: tt) => {
13925
2ee07e751171 add more fpnum functions
alfadur
parents: 13905
diff changeset
   433
        impl $op for FPPoint {
2ee07e751171 add more fpnum functions
alfadur
parents: 13905
diff changeset
   434
            type Output = Self;
2ee07e751171 add more fpnum functions
alfadur
parents: 13905
diff changeset
   435
2ee07e751171 add more fpnum functions
alfadur
parents: 13905
diff changeset
   436
            #[inline]
2ee07e751171 add more fpnum functions
alfadur
parents: 13905
diff changeset
   437
            fn $name(self, rhs: Self) -> Self {
14122
c27461e6a9eb Implement non-overflowing calculations for high values
unc0rr
parents: 14081
diff changeset
   438
                Self::new(self.x().$name(rhs.x()), self.y().$name(rhs.y()))
13925
2ee07e751171 add more fpnum functions
alfadur
parents: 13905
diff changeset
   439
            }
2ee07e751171 add more fpnum functions
alfadur
parents: 13905
diff changeset
   440
        }
14122
c27461e6a9eb Implement non-overflowing calculations for high values
unc0rr
parents: 14081
diff changeset
   441
    };
13925
2ee07e751171 add more fpnum functions
alfadur
parents: 13905
diff changeset
   442
}
2ee07e751171 add more fpnum functions
alfadur
parents: 13905
diff changeset
   443
13932
7bb60596c27e add left scalar operations to fpnum
alfadur
parents: 13929
diff changeset
   444
macro_rules! right_scalar_bin_op_impl {
7bb60596c27e add left scalar operations to fpnum
alfadur
parents: 13929
diff changeset
   445
    ($($op: tt)::+, $name: tt) => {
7bb60596c27e add left scalar operations to fpnum
alfadur
parents: 13929
diff changeset
   446
        impl $($op)::+<FPNum> for FPPoint {
13927
cf28d7a2b7fe add scalar operations
alfadur
parents: 13926
diff changeset
   447
            type Output = Self;
cf28d7a2b7fe add scalar operations
alfadur
parents: 13926
diff changeset
   448
cf28d7a2b7fe add scalar operations
alfadur
parents: 13926
diff changeset
   449
            #[inline]
cf28d7a2b7fe add scalar operations
alfadur
parents: 13926
diff changeset
   450
            fn $name(self, rhs: FPNum) -> Self {
cf28d7a2b7fe add scalar operations
alfadur
parents: 13926
diff changeset
   451
                Self::new(self.x().$name(rhs),
cf28d7a2b7fe add scalar operations
alfadur
parents: 13926
diff changeset
   452
                          self.y().$name(rhs))
cf28d7a2b7fe add scalar operations
alfadur
parents: 13926
diff changeset
   453
            }
cf28d7a2b7fe add scalar operations
alfadur
parents: 13926
diff changeset
   454
        }
14140
3078123e84ea Bezierize land outline
unc0rr
parents: 14139
diff changeset
   455
    };
3078123e84ea Bezierize land outline
unc0rr
parents: 14139
diff changeset
   456
    ($($op: tt)::+<$arg: tt>, $name: tt) => {
3078123e84ea Bezierize land outline
unc0rr
parents: 14139
diff changeset
   457
        impl $($op)::+<$arg> for FPPoint {
3078123e84ea Bezierize land outline
unc0rr
parents: 14139
diff changeset
   458
            type Output = Self;
3078123e84ea Bezierize land outline
unc0rr
parents: 14139
diff changeset
   459
3078123e84ea Bezierize land outline
unc0rr
parents: 14139
diff changeset
   460
            #[inline]
3078123e84ea Bezierize land outline
unc0rr
parents: 14139
diff changeset
   461
            fn $name(self, rhs: $arg) -> Self {
3078123e84ea Bezierize land outline
unc0rr
parents: 14139
diff changeset
   462
                Self::new(self.x().$name(rhs),
3078123e84ea Bezierize land outline
unc0rr
parents: 14139
diff changeset
   463
                          self.y().$name(rhs))
3078123e84ea Bezierize land outline
unc0rr
parents: 14139
diff changeset
   464
            }
3078123e84ea Bezierize land outline
unc0rr
parents: 14139
diff changeset
   465
        }
13927
cf28d7a2b7fe add scalar operations
alfadur
parents: 13926
diff changeset
   466
    }
cf28d7a2b7fe add scalar operations
alfadur
parents: 13926
diff changeset
   467
}
cf28d7a2b7fe add scalar operations
alfadur
parents: 13926
diff changeset
   468
13932
7bb60596c27e add left scalar operations to fpnum
alfadur
parents: 13929
diff changeset
   469
macro_rules! left_scalar_bin_op_impl {
7bb60596c27e add left scalar operations to fpnum
alfadur
parents: 13929
diff changeset
   470
    ($($op: tt)::+, $name: tt) => {
7bb60596c27e add left scalar operations to fpnum
alfadur
parents: 13929
diff changeset
   471
        impl $($op)::+<FPPoint> for FPNum {
7bb60596c27e add left scalar operations to fpnum
alfadur
parents: 13929
diff changeset
   472
            type Output = FPPoint;
7bb60596c27e add left scalar operations to fpnum
alfadur
parents: 13929
diff changeset
   473
7bb60596c27e add left scalar operations to fpnum
alfadur
parents: 13929
diff changeset
   474
            #[inline]
7bb60596c27e add left scalar operations to fpnum
alfadur
parents: 13929
diff changeset
   475
            fn $name(self, rhs: FPPoint) -> Self::Output {
7bb60596c27e add left scalar operations to fpnum
alfadur
parents: 13929
diff changeset
   476
                Self::Output::new(self.$name(rhs.x()),
7bb60596c27e add left scalar operations to fpnum
alfadur
parents: 13929
diff changeset
   477
                                  self.$name(rhs.y()))
7bb60596c27e add left scalar operations to fpnum
alfadur
parents: 13929
diff changeset
   478
            }
7bb60596c27e add left scalar operations to fpnum
alfadur
parents: 13929
diff changeset
   479
        }
7bb60596c27e add left scalar operations to fpnum
alfadur
parents: 13929
diff changeset
   480
    }
7bb60596c27e add left scalar operations to fpnum
alfadur
parents: 13929
diff changeset
   481
}
7bb60596c27e add left scalar operations to fpnum
alfadur
parents: 13929
diff changeset
   482
13925
2ee07e751171 add more fpnum functions
alfadur
parents: 13905
diff changeset
   483
bin_op_impl!(ops::Add, add);
2ee07e751171 add more fpnum functions
alfadur
parents: 13905
diff changeset
   484
bin_op_impl!(ops::Sub, sub);
2ee07e751171 add more fpnum functions
alfadur
parents: 13905
diff changeset
   485
bin_op_impl!(ops::Mul, mul);
13929
ff77c9920007 add opassign implementations
alfadur
parents: 13928
diff changeset
   486
bin_op_impl!(ops::Div, div);
13932
7bb60596c27e add left scalar operations to fpnum
alfadur
parents: 13929
diff changeset
   487
right_scalar_bin_op_impl!(ops::Add, add);
7bb60596c27e add left scalar operations to fpnum
alfadur
parents: 13929
diff changeset
   488
right_scalar_bin_op_impl!(ops::Mul, mul);
7bb60596c27e add left scalar operations to fpnum
alfadur
parents: 13929
diff changeset
   489
right_scalar_bin_op_impl!(ops::Sub, sub);
7bb60596c27e add left scalar operations to fpnum
alfadur
parents: 13929
diff changeset
   490
right_scalar_bin_op_impl!(ops::Div, div);
14140
3078123e84ea Bezierize land outline
unc0rr
parents: 14139
diff changeset
   491
right_scalar_bin_op_impl!(ops::Div<u32>, div);
13932
7bb60596c27e add left scalar operations to fpnum
alfadur
parents: 13929
diff changeset
   492
left_scalar_bin_op_impl!(ops::Mul, mul);
13925
2ee07e751171 add more fpnum functions
alfadur
parents: 13905
diff changeset
   493
13929
ff77c9920007 add opassign implementations
alfadur
parents: 13928
diff changeset
   494
macro_rules! bin_assign_op_impl {
ff77c9920007 add opassign implementations
alfadur
parents: 13928
diff changeset
   495
    ($typ: tt, $($op: tt)::+, $name: tt, $delegate: tt) => {
ff77c9920007 add opassign implementations
alfadur
parents: 13928
diff changeset
   496
        bin_assign_op_impl!($typ, $($op)::+<$typ>, $name, $delegate);
ff77c9920007 add opassign implementations
alfadur
parents: 13928
diff changeset
   497
    };
ff77c9920007 add opassign implementations
alfadur
parents: 13928
diff changeset
   498
    ($typ: tt, $($op: tt)::+<$arg: tt>, $name: tt, $delegate: tt) => {
ff77c9920007 add opassign implementations
alfadur
parents: 13928
diff changeset
   499
        impl $($op)::+<$arg> for $typ {
ff77c9920007 add opassign implementations
alfadur
parents: 13928
diff changeset
   500
            #[inline]
ff77c9920007 add opassign implementations
alfadur
parents: 13928
diff changeset
   501
            fn $name(&mut self, rhs: $arg) {
ff77c9920007 add opassign implementations
alfadur
parents: 13928
diff changeset
   502
                *self = *self $delegate rhs;
ff77c9920007 add opassign implementations
alfadur
parents: 13928
diff changeset
   503
            }
ff77c9920007 add opassign implementations
alfadur
parents: 13928
diff changeset
   504
        }
ff77c9920007 add opassign implementations
alfadur
parents: 13928
diff changeset
   505
    }
ff77c9920007 add opassign implementations
alfadur
parents: 13928
diff changeset
   506
}
ff77c9920007 add opassign implementations
alfadur
parents: 13928
diff changeset
   507
ff77c9920007 add opassign implementations
alfadur
parents: 13928
diff changeset
   508
bin_assign_op_impl!(FPNum, ops::AddAssign, add_assign, +);
ff77c9920007 add opassign implementations
alfadur
parents: 13928
diff changeset
   509
bin_assign_op_impl!(FPNum, ops::SubAssign, sub_assign, -);
ff77c9920007 add opassign implementations
alfadur
parents: 13928
diff changeset
   510
bin_assign_op_impl!(FPNum, ops::MulAssign, mul_assign, *);
ff77c9920007 add opassign implementations
alfadur
parents: 13928
diff changeset
   511
bin_assign_op_impl!(FPNum, ops::DivAssign, div_assign, /);
ff77c9920007 add opassign implementations
alfadur
parents: 13928
diff changeset
   512
bin_assign_op_impl!(FPNum, ops::MulAssign<i32>, mul_assign, *);
ff77c9920007 add opassign implementations
alfadur
parents: 13928
diff changeset
   513
bin_assign_op_impl!(FPNum, ops::DivAssign<i32>, div_assign, /);
ff77c9920007 add opassign implementations
alfadur
parents: 13928
diff changeset
   514
bin_assign_op_impl!(FPNum, ops::DivAssign<u32>, div_assign, /);
ff77c9920007 add opassign implementations
alfadur
parents: 13928
diff changeset
   515
ff77c9920007 add opassign implementations
alfadur
parents: 13928
diff changeset
   516
bin_assign_op_impl!(FPPoint, ops::AddAssign, add_assign, +);
ff77c9920007 add opassign implementations
alfadur
parents: 13928
diff changeset
   517
bin_assign_op_impl!(FPPoint, ops::SubAssign, sub_assign, -);
ff77c9920007 add opassign implementations
alfadur
parents: 13928
diff changeset
   518
bin_assign_op_impl!(FPPoint, ops::MulAssign, mul_assign, *);
ff77c9920007 add opassign implementations
alfadur
parents: 13928
diff changeset
   519
bin_assign_op_impl!(FPPoint, ops::DivAssign, div_assign, /);
ff77c9920007 add opassign implementations
alfadur
parents: 13928
diff changeset
   520
bin_assign_op_impl!(FPPoint, ops::AddAssign<FPNum>, add_assign, +);
ff77c9920007 add opassign implementations
alfadur
parents: 13928
diff changeset
   521
bin_assign_op_impl!(FPPoint, ops::SubAssign<FPNum>, sub_assign, -);
ff77c9920007 add opassign implementations
alfadur
parents: 13928
diff changeset
   522
bin_assign_op_impl!(FPPoint, ops::MulAssign<FPNum>, mul_assign, *);
ff77c9920007 add opassign implementations
alfadur
parents: 13928
diff changeset
   523
bin_assign_op_impl!(FPPoint, ops::DivAssign<FPNum>, div_assign, /);
ff77c9920007 add opassign implementations
alfadur
parents: 13928
diff changeset
   524
13928
5fdc41cd0841 make methods public
alfadur
parents: 13927
diff changeset
   525
pub fn distance<T>(x: T, y: T) -> FPNum
14122
c27461e6a9eb Implement non-overflowing calculations for high values
unc0rr
parents: 14081
diff changeset
   526
where
c27461e6a9eb Implement non-overflowing calculations for high values
unc0rr
parents: 14081
diff changeset
   527
    T: Into<i64> + std::fmt::Debug,
13925
2ee07e751171 add more fpnum functions
alfadur
parents: 13905
diff changeset
   528
{
14122
c27461e6a9eb Implement non-overflowing calculations for high values
unc0rr
parents: 14081
diff changeset
   529
    let mut sqr: u128 = (x.into().pow(2) as u128).shl(64) + (y.into().pow(2) as u128).shl(64);
c27461e6a9eb Implement non-overflowing calculations for high values
unc0rr
parents: 14081
diff changeset
   530
c27461e6a9eb Implement non-overflowing calculations for high values
unc0rr
parents: 14081
diff changeset
   531
    let mut t: u128 = 0x40000000_00000000_00000000_00000000;
c27461e6a9eb Implement non-overflowing calculations for high values
unc0rr
parents: 14081
diff changeset
   532
    let mut r: u128 = 0;
c27461e6a9eb Implement non-overflowing calculations for high values
unc0rr
parents: 14081
diff changeset
   533
c27461e6a9eb Implement non-overflowing calculations for high values
unc0rr
parents: 14081
diff changeset
   534
    for _ in 0..64 {
c27461e6a9eb Implement non-overflowing calculations for high values
unc0rr
parents: 14081
diff changeset
   535
        let s = r + t;
c27461e6a9eb Implement non-overflowing calculations for high values
unc0rr
parents: 14081
diff changeset
   536
        r >>= 1;
c27461e6a9eb Implement non-overflowing calculations for high values
unc0rr
parents: 14081
diff changeset
   537
c27461e6a9eb Implement non-overflowing calculations for high values
unc0rr
parents: 14081
diff changeset
   538
        if s <= sqr {
c27461e6a9eb Implement non-overflowing calculations for high values
unc0rr
parents: 14081
diff changeset
   539
            sqr -= s;
c27461e6a9eb Implement non-overflowing calculations for high values
unc0rr
parents: 14081
diff changeset
   540
            r += t;
c27461e6a9eb Implement non-overflowing calculations for high values
unc0rr
parents: 14081
diff changeset
   541
        }
c27461e6a9eb Implement non-overflowing calculations for high values
unc0rr
parents: 14081
diff changeset
   542
        t >>= 2;
c27461e6a9eb Implement non-overflowing calculations for high values
unc0rr
parents: 14081
diff changeset
   543
    }
c27461e6a9eb Implement non-overflowing calculations for high values
unc0rr
parents: 14081
diff changeset
   544
c27461e6a9eb Implement non-overflowing calculations for high values
unc0rr
parents: 14081
diff changeset
   545
    FPNum {
c27461e6a9eb Implement non-overflowing calculations for high values
unc0rr
parents: 14081
diff changeset
   546
        is_negative: false,
c27461e6a9eb Implement non-overflowing calculations for high values
unc0rr
parents: 14081
diff changeset
   547
        value: r as u64,
c27461e6a9eb Implement non-overflowing calculations for high values
unc0rr
parents: 14081
diff changeset
   548
    }
13925
2ee07e751171 add more fpnum functions
alfadur
parents: 13905
diff changeset
   549
}
2ee07e751171 add more fpnum functions
alfadur
parents: 13905
diff changeset
   550
13882
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   551
/* TODO:
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   552
 AngleSin
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   553
 AngleCos
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   554
*/
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   555
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   556
#[cfg(test)]
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   557
#[test]
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   558
fn basics() {
14122
c27461e6a9eb Implement non-overflowing calculations for high values
unc0rr
parents: 14081
diff changeset
   559
    let n = fp!(15 / 2);
13882
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   560
    assert!(n.is_positive());
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   561
    assert!(!n.is_negative());
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   562
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   563
    assert!(!(-n).is_positive());
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   564
    assert!((-n).is_negative());
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   565
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   566
    assert_eq!(-(-n), n);
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   567
    assert_eq!((-n).abs(), n);
14122
c27461e6a9eb Implement non-overflowing calculations for high values
unc0rr
parents: 14081
diff changeset
   568
    assert_eq!(-n, fp!(-15 / 2));
13882
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   569
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   570
    assert_eq!(n.round(), 7);
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   571
    assert_eq!((-n).round(), -7);
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   572
}
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   573
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   574
#[test]
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   575
fn zero() {
13891
9ae1184886db add fpnum literal macro
alfadur
parents: 13885
diff changeset
   576
    let z = fp!(0);
14122
c27461e6a9eb Implement non-overflowing calculations for high values
unc0rr
parents: 14081
diff changeset
   577
    let n = fp!(15 / 2);
13882
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   578
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   579
    assert!(z.is_zero());
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   580
    assert!(z.is_positive());
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   581
    assert!((-z).is_negative);
13883
2bfd7472ef1d Add some more tests
unc0rr
parents: 13882
diff changeset
   582
    assert_eq!(n - n, z);
2bfd7472ef1d Add some more tests
unc0rr
parents: 13882
diff changeset
   583
    assert_eq!(-n + n, z);
13926
2717a5289d88 fix test
alfadur
parents: 13925
diff changeset
   584
    assert_eq!(n.with_sign_as(-n), -n);
13882
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   585
}
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   586
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   587
#[test]
13884
fbbb4fcd6a75 delegate cmp to rustlib
alfadur
parents: 13883
diff changeset
   588
fn ord() {
13891
9ae1184886db add fpnum literal macro
alfadur
parents: 13885
diff changeset
   589
    let z = fp!(0);
14122
c27461e6a9eb Implement non-overflowing calculations for high values
unc0rr
parents: 14081
diff changeset
   590
    let n1_5 = fp!(3 / 2);
c27461e6a9eb Implement non-overflowing calculations for high values
unc0rr
parents: 14081
diff changeset
   591
    let n2_25 = fp!(9 / 4);
13884
fbbb4fcd6a75 delegate cmp to rustlib
alfadur
parents: 13883
diff changeset
   592
fbbb4fcd6a75 delegate cmp to rustlib
alfadur
parents: 13883
diff changeset
   593
    assert!(!(z > z));
fbbb4fcd6a75 delegate cmp to rustlib
alfadur
parents: 13883
diff changeset
   594
    assert!(!(z < z));
fbbb4fcd6a75 delegate cmp to rustlib
alfadur
parents: 13883
diff changeset
   595
    assert!(n2_25 > n1_5);
fbbb4fcd6a75 delegate cmp to rustlib
alfadur
parents: 13883
diff changeset
   596
    assert!(-n2_25 < n1_5);
fbbb4fcd6a75 delegate cmp to rustlib
alfadur
parents: 13883
diff changeset
   597
    assert!(-n2_25 < -n1_5);
fbbb4fcd6a75 delegate cmp to rustlib
alfadur
parents: 13883
diff changeset
   598
}
fbbb4fcd6a75 delegate cmp to rustlib
alfadur
parents: 13883
diff changeset
   599
fbbb4fcd6a75 delegate cmp to rustlib
alfadur
parents: 13883
diff changeset
   600
#[test]
13882
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   601
fn arith() {
14122
c27461e6a9eb Implement non-overflowing calculations for high values
unc0rr
parents: 14081
diff changeset
   602
    let n1_5 = fp!(3 / 2);
c27461e6a9eb Implement non-overflowing calculations for high values
unc0rr
parents: 14081
diff changeset
   603
    let n2_25 = fp!(9 / 4);
c27461e6a9eb Implement non-overflowing calculations for high values
unc0rr
parents: 14081
diff changeset
   604
    let n_0_15 = fp!(-15 / 100);
13882
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   605
13891
9ae1184886db add fpnum literal macro
alfadur
parents: 13885
diff changeset
   606
    assert_eq!(n1_5 + n1_5, fp!(3));
9ae1184886db add fpnum literal macro
alfadur
parents: 13885
diff changeset
   607
    assert_eq!(-n1_5 - n1_5, fp!(-3));
13882
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   608
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   609
    assert_eq!(n1_5 * n1_5, n2_25);
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   610
    assert_eq!(-n1_5 * -n1_5, n2_25);
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   611
    assert_eq!(n1_5 * -n1_5, -n2_25);
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   612
    assert_eq!(-n1_5 * n1_5, -n2_25);
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   613
13883
2bfd7472ef1d Add some more tests
unc0rr
parents: 13882
diff changeset
   614
    assert_eq!(-n2_25 / -n1_5, n1_5);
2bfd7472ef1d Add some more tests
unc0rr
parents: 13882
diff changeset
   615
    assert_eq!(n1_5 / -10, n_0_15);
2bfd7472ef1d Add some more tests
unc0rr
parents: 13882
diff changeset
   616
13882
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   617
    assert_eq!(n1_5.sqr(), n2_25);
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   618
    assert_eq!((-n1_5).sqr(), n2_25);
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   619
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   620
    assert_eq!(n2_25.sqrt(), n1_5);
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   621
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   622
    assert_eq!((n1_5 * n1_5 * n1_5.sqr()).sqrt(), n2_25);
13929
ff77c9920007 add opassign implementations
alfadur
parents: 13928
diff changeset
   623
ff77c9920007 add opassign implementations
alfadur
parents: 13928
diff changeset
   624
    let mut m = fp!(1);
ff77c9920007 add opassign implementations
alfadur
parents: 13928
diff changeset
   625
    m += n1_5;
14122
c27461e6a9eb Implement non-overflowing calculations for high values
unc0rr
parents: 14081
diff changeset
   626
    assert_eq!(m, fp!(5 / 2));
c27461e6a9eb Implement non-overflowing calculations for high values
unc0rr
parents: 14081
diff changeset
   627
}
c27461e6a9eb Implement non-overflowing calculations for high values
unc0rr
parents: 14081
diff changeset
   628
c27461e6a9eb Implement non-overflowing calculations for high values
unc0rr
parents: 14081
diff changeset
   629
#[test]
c27461e6a9eb Implement non-overflowing calculations for high values
unc0rr
parents: 14081
diff changeset
   630
fn test_distance_high_values() {
c27461e6a9eb Implement non-overflowing calculations for high values
unc0rr
parents: 14081
diff changeset
   631
    assert_eq!(distance(1_000_000i32, 0), fp!(1_000_000));
c27461e6a9eb Implement non-overflowing calculations for high values
unc0rr
parents: 14081
diff changeset
   632
    assert_eq!(
c27461e6a9eb Implement non-overflowing calculations for high values
unc0rr
parents: 14081
diff changeset
   633
        FPPoint::new(fp!(1_000_000), fp!(0)).distance(),
c27461e6a9eb Implement non-overflowing calculations for high values
unc0rr
parents: 14081
diff changeset
   634
        fp!(1_000_000)
c27461e6a9eb Implement non-overflowing calculations for high values
unc0rr
parents: 14081
diff changeset
   635
    );
13882
b172a5d40eee Reimplement hwFloat library in rust for future use
unc0rr
parents:
diff changeset
   636
}
13925
2ee07e751171 add more fpnum functions
alfadur
parents: 13905
diff changeset
   637
2ee07e751171 add more fpnum functions
alfadur
parents: 13905
diff changeset
   638
#[test]
2ee07e751171 add more fpnum functions
alfadur
parents: 13905
diff changeset
   639
fn point() {
2ee07e751171 add more fpnum functions
alfadur
parents: 13905
diff changeset
   640
    let z = FPPoint::zero();
14122
c27461e6a9eb Implement non-overflowing calculations for high values
unc0rr
parents: 14081
diff changeset
   641
    let n = fp!(16 / 9);
13925
2ee07e751171 add more fpnum functions
alfadur
parents: 13905
diff changeset
   642
    let p = FPPoint::new(fp!(1), fp!(-2));
2ee07e751171 add more fpnum functions
alfadur
parents: 13905
diff changeset
   643
2ee07e751171 add more fpnum functions
alfadur
parents: 13905
diff changeset
   644
    assert_eq!(p.sqr_distance(), fp!(5));
2ee07e751171 add more fpnum functions
alfadur
parents: 13905
diff changeset
   645
    assert_eq!(p + -p, FPPoint::zero());
2ee07e751171 add more fpnum functions
alfadur
parents: 13905
diff changeset
   646
    assert_eq!(p * z, z);
2ee07e751171 add more fpnum functions
alfadur
parents: 13905
diff changeset
   647
    assert_eq!(p.dot(&z), fp!(0));
13932
7bb60596c27e add left scalar operations to fpnum
alfadur
parents: 13929
diff changeset
   648
    assert_eq!(n * p, p * n);
13925
2ee07e751171 add more fpnum functions
alfadur
parents: 13905
diff changeset
   649
    assert_eq!(distance(4, 3), fp!(5));
13927
cf28d7a2b7fe add scalar operations
alfadur
parents: 13926
diff changeset
   650
    assert_eq!(p * fp!(-3), FPPoint::new(fp!(-3), fp!(6)));
13939
665b4c6612ee fix fppoint.max_norm
alfadur
parents: 13932
diff changeset
   651
    assert_eq!(p.max_norm(), fp!(2));
14122
c27461e6a9eb Implement non-overflowing calculations for high values
unc0rr
parents: 14081
diff changeset
   652
}