2021-05-29 03:01:07 +10:00
|
|
|
/* OpenTally: Open-source election vote counting
|
|
|
|
* Copyright © 2021 Lee Yingtong Li (RunasSudo)
|
|
|
|
*
|
|
|
|
* This program is free software: you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU Affero General Public License as published by
|
|
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU Affero General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Affero General Public License
|
|
|
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
|
2021-06-14 20:43:36 +10:00
|
|
|
use super::{Assign, Number};
|
2021-05-29 03:01:07 +10:00
|
|
|
|
2021-06-04 22:05:48 +10:00
|
|
|
use derive_more::Display;
|
2021-06-18 18:48:12 +10:00
|
|
|
use num_traits::{Num, One, ParseFloatError, Zero};
|
2021-05-29 03:01:07 +10:00
|
|
|
|
2021-05-30 02:28:52 +10:00
|
|
|
use std::cmp::{Ord, Ordering, PartialEq, PartialOrd};
|
2021-05-29 03:01:07 +10:00
|
|
|
use std::ops;
|
|
|
|
|
2021-05-29 17:51:45 +10:00
|
|
|
type ImplType = f64;
|
2021-05-29 03:01:07 +10:00
|
|
|
|
2021-06-14 20:43:36 +10:00
|
|
|
/// Native 64-bit floating-point number
|
2021-06-16 20:28:03 +10:00
|
|
|
#[derive(Clone, Debug, Display, PartialEq, PartialOrd)]
|
2021-05-29 17:51:45 +10:00
|
|
|
pub struct NativeFloat64(ImplType);
|
|
|
|
|
|
|
|
impl Number for NativeFloat64 {
|
2021-05-29 03:01:07 +10:00
|
|
|
fn new() -> Self { Self(0.0) }
|
|
|
|
|
2021-06-03 21:35:25 +10:00
|
|
|
fn describe() -> String { "--numbers float64".to_string() }
|
|
|
|
|
2021-06-01 21:20:38 +10:00
|
|
|
fn pow_assign(&mut self, exponent: i32) {
|
|
|
|
self.0 = self.0.powi(exponent);
|
|
|
|
}
|
2021-05-29 03:01:07 +10:00
|
|
|
|
2021-05-29 17:51:45 +10:00
|
|
|
fn floor_mut(&mut self, dps: usize) {
|
|
|
|
let factor = 10.0_f64.powi(dps as i32);
|
|
|
|
self.0 = (self.0 * factor).floor() / factor;
|
|
|
|
}
|
2021-06-02 18:07:05 +10:00
|
|
|
|
|
|
|
fn ceil_mut(&mut self, dps: usize) {
|
|
|
|
let factor = 10.0_f64.powi(dps as i32);
|
|
|
|
self.0 = (self.0 * factor).ceil() / factor;
|
|
|
|
}
|
2021-05-29 03:01:07 +10:00
|
|
|
}
|
|
|
|
|
2021-05-29 17:51:45 +10:00
|
|
|
impl Num for NativeFloat64 {
|
2021-06-18 18:48:12 +10:00
|
|
|
type FromStrRadixErr = ParseFloatError;
|
2021-05-29 03:01:07 +10:00
|
|
|
fn from_str_radix(str: &str, radix: u32) -> Result<Self, Self::FromStrRadixErr> {
|
2021-06-18 18:48:12 +10:00
|
|
|
match f64::from_str_radix(str, radix) {
|
2021-05-29 17:51:45 +10:00
|
|
|
Ok(value) => Ok(Self(value as ImplType)),
|
2021-05-29 03:01:07 +10:00
|
|
|
Err(err) => Err(err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-05-29 17:51:45 +10:00
|
|
|
impl Assign for NativeFloat64 {
|
2021-06-05 15:08:07 +10:00
|
|
|
fn assign(&mut self, src: Self) { self.0 = src.0; }
|
2021-05-29 03:01:07 +10:00
|
|
|
}
|
|
|
|
|
2021-05-29 17:51:45 +10:00
|
|
|
impl Assign<&NativeFloat64> for NativeFloat64 {
|
2021-06-05 15:08:07 +10:00
|
|
|
fn assign(&mut self, src: &NativeFloat64) { self.0 = src.0; }
|
2021-05-29 03:01:07 +10:00
|
|
|
}
|
|
|
|
|
2021-06-01 21:20:38 +10:00
|
|
|
impl From<usize> for NativeFloat64 {
|
|
|
|
fn from(n: usize) -> Self { Self(n as ImplType) }
|
|
|
|
}
|
|
|
|
|
2021-05-29 17:51:45 +10:00
|
|
|
impl One for NativeFloat64 {
|
2021-05-29 03:01:07 +10:00
|
|
|
fn one() -> Self { Self(1.0) }
|
|
|
|
}
|
|
|
|
|
2021-05-29 17:51:45 +10:00
|
|
|
impl Zero for NativeFloat64 {
|
2021-05-29 03:01:07 +10:00
|
|
|
fn zero() -> Self { Self::new() }
|
|
|
|
fn is_zero(&self) -> bool { self.0.is_zero() }
|
|
|
|
}
|
|
|
|
|
2021-05-30 02:28:52 +10:00
|
|
|
impl Eq for NativeFloat64 {}
|
|
|
|
impl Ord for NativeFloat64 {
|
|
|
|
fn cmp(&self, other: &Self) -> Ordering { self.0.partial_cmp(&other.0).unwrap() }
|
2021-05-29 03:01:07 +10:00
|
|
|
}
|
|
|
|
|
2021-05-29 17:51:45 +10:00
|
|
|
impl ops::Neg for NativeFloat64 {
|
|
|
|
type Output = NativeFloat64;
|
2021-05-29 03:01:07 +10:00
|
|
|
fn neg(self) -> Self::Output { Self(-self.0) }
|
|
|
|
}
|
|
|
|
|
2021-05-29 17:51:45 +10:00
|
|
|
impl ops::Add for NativeFloat64 {
|
|
|
|
type Output = NativeFloat64;
|
2021-06-16 13:00:54 +10:00
|
|
|
fn add(self, rhs: Self) -> Self::Output { Self(self.0 + rhs.0) }
|
2021-05-29 03:01:07 +10:00
|
|
|
}
|
|
|
|
|
2021-05-29 17:51:45 +10:00
|
|
|
impl ops::Sub for NativeFloat64 {
|
|
|
|
type Output = NativeFloat64;
|
2021-05-29 03:01:07 +10:00
|
|
|
fn sub(self, _rhs: Self) -> Self::Output {
|
|
|
|
todo!()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-05-29 17:51:45 +10:00
|
|
|
impl ops::Mul for NativeFloat64 {
|
|
|
|
type Output = NativeFloat64;
|
2021-05-29 03:01:07 +10:00
|
|
|
fn mul(self, _rhs: Self) -> Self::Output {
|
|
|
|
todo!()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-05-29 17:51:45 +10:00
|
|
|
impl ops::Div for NativeFloat64 {
|
|
|
|
type Output = NativeFloat64;
|
2021-06-16 13:00:54 +10:00
|
|
|
fn div(self, rhs: Self) -> Self::Output { Self(self.0 / rhs.0) }
|
2021-05-29 03:01:07 +10:00
|
|
|
}
|
|
|
|
|
2021-05-29 17:51:45 +10:00
|
|
|
impl ops::Rem for NativeFloat64 {
|
|
|
|
type Output = NativeFloat64;
|
2021-05-29 03:01:07 +10:00
|
|
|
fn rem(self, _rhs: Self) -> Self::Output {
|
|
|
|
todo!()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-05-29 17:51:45 +10:00
|
|
|
impl ops::Add<&NativeFloat64> for NativeFloat64 {
|
|
|
|
type Output = NativeFloat64;
|
|
|
|
fn add(self, rhs: &NativeFloat64) -> Self::Output { Self(self.0 + &rhs.0) }
|
2021-05-29 03:01:07 +10:00
|
|
|
}
|
|
|
|
|
2021-05-29 17:51:45 +10:00
|
|
|
impl ops::Sub<&NativeFloat64> for NativeFloat64 {
|
|
|
|
type Output = NativeFloat64;
|
2021-06-07 20:52:18 +10:00
|
|
|
fn sub(self, rhs: &NativeFloat64) -> Self::Output { Self(self.0 - &rhs.0) }
|
2021-05-29 03:01:07 +10:00
|
|
|
}
|
|
|
|
|
2021-05-29 17:51:45 +10:00
|
|
|
impl ops::Mul<&NativeFloat64> for NativeFloat64 {
|
|
|
|
type Output = NativeFloat64;
|
|
|
|
fn mul(self, rhs: &NativeFloat64) -> Self::Output { NativeFloat64(self.0 * &rhs.0) }
|
2021-05-29 03:01:07 +10:00
|
|
|
}
|
|
|
|
|
2021-05-29 17:51:45 +10:00
|
|
|
impl ops::Div<&NativeFloat64> for NativeFloat64 {
|
|
|
|
type Output = NativeFloat64;
|
|
|
|
fn div(self, rhs: &NativeFloat64) -> Self::Output { NativeFloat64(self.0 / &rhs.0) }
|
2021-05-29 03:01:07 +10:00
|
|
|
}
|
|
|
|
|
2021-05-29 17:51:45 +10:00
|
|
|
impl ops::Rem<&NativeFloat64> for NativeFloat64 {
|
|
|
|
type Output = NativeFloat64;
|
|
|
|
fn rem(self, _rhs: &NativeFloat64) -> Self::Output {
|
2021-05-29 03:01:07 +10:00
|
|
|
todo!()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-05-29 17:51:45 +10:00
|
|
|
impl ops::AddAssign for NativeFloat64 {
|
2021-06-05 15:08:07 +10:00
|
|
|
fn add_assign(&mut self, rhs: Self) { self.0 += rhs.0; }
|
2021-05-29 03:01:07 +10:00
|
|
|
}
|
|
|
|
|
2021-05-29 17:51:45 +10:00
|
|
|
impl ops::SubAssign for NativeFloat64 {
|
2021-06-05 15:08:07 +10:00
|
|
|
fn sub_assign(&mut self, rhs: Self) { self.0 -= rhs.0; }
|
2021-05-29 03:01:07 +10:00
|
|
|
}
|
|
|
|
|
2021-05-29 17:51:45 +10:00
|
|
|
impl ops::MulAssign for NativeFloat64 {
|
2021-06-05 15:08:07 +10:00
|
|
|
fn mul_assign(&mut self, rhs: Self) { self.0 *= rhs.0; }
|
2021-05-29 03:01:07 +10:00
|
|
|
}
|
|
|
|
|
2021-05-29 17:51:45 +10:00
|
|
|
impl ops::DivAssign for NativeFloat64 {
|
2021-06-05 15:08:07 +10:00
|
|
|
fn div_assign(&mut self, rhs: Self) { self.0 /= &rhs.0; }
|
2021-05-29 03:01:07 +10:00
|
|
|
}
|
|
|
|
|
2021-05-29 17:51:45 +10:00
|
|
|
impl ops::RemAssign for NativeFloat64 {
|
2021-05-29 03:01:07 +10:00
|
|
|
fn rem_assign(&mut self, _rhs: Self) {
|
|
|
|
todo!()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-05-29 17:51:45 +10:00
|
|
|
impl ops::AddAssign<&NativeFloat64> for NativeFloat64 {
|
2021-06-05 15:08:07 +10:00
|
|
|
fn add_assign(&mut self, rhs: &NativeFloat64) { self.0 += &rhs.0; }
|
2021-05-29 03:01:07 +10:00
|
|
|
}
|
|
|
|
|
2021-05-29 17:51:45 +10:00
|
|
|
impl ops::SubAssign<&NativeFloat64> for NativeFloat64 {
|
2021-06-05 15:08:07 +10:00
|
|
|
fn sub_assign(&mut self, rhs: &NativeFloat64) { self.0 -= &rhs.0; }
|
2021-05-29 03:01:07 +10:00
|
|
|
}
|
|
|
|
|
2021-05-29 17:51:45 +10:00
|
|
|
impl ops::MulAssign<&NativeFloat64> for NativeFloat64 {
|
2021-06-05 15:08:07 +10:00
|
|
|
fn mul_assign(&mut self, rhs: &NativeFloat64) { self.0 *= &rhs.0; }
|
2021-05-29 03:01:07 +10:00
|
|
|
}
|
|
|
|
|
2021-05-29 17:51:45 +10:00
|
|
|
impl ops::DivAssign<&NativeFloat64> for NativeFloat64 {
|
|
|
|
fn div_assign(&mut self, _rhs: &NativeFloat64) {
|
2021-05-29 03:01:07 +10:00
|
|
|
todo!()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-05-29 17:51:45 +10:00
|
|
|
impl ops::RemAssign<&NativeFloat64> for NativeFloat64 {
|
|
|
|
fn rem_assign(&mut self, _rhs: &NativeFloat64) {
|
2021-05-29 03:01:07 +10:00
|
|
|
todo!()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-05-29 17:51:45 +10:00
|
|
|
impl ops::Neg for &NativeFloat64 {
|
|
|
|
type Output = NativeFloat64;
|
|
|
|
fn neg(self) -> Self::Output { NativeFloat64(-&self.0) }
|
2021-05-29 03:01:07 +10:00
|
|
|
}
|
|
|
|
|
2021-06-09 20:09:20 +10:00
|
|
|
impl ops::Add<Self> for &NativeFloat64 {
|
2021-05-29 17:51:45 +10:00
|
|
|
type Output = NativeFloat64;
|
2021-06-09 20:09:20 +10:00
|
|
|
fn add(self, rhs: &NativeFloat64) -> Self::Output { NativeFloat64(&self.0 + &rhs.0) }
|
2021-05-29 03:01:07 +10:00
|
|
|
}
|
|
|
|
|
2021-06-09 20:09:20 +10:00
|
|
|
impl ops::Sub<Self> for &NativeFloat64 {
|
2021-05-29 17:51:45 +10:00
|
|
|
type Output = NativeFloat64;
|
|
|
|
fn sub(self, rhs: &NativeFloat64) -> Self::Output { NativeFloat64(&self.0 - &rhs.0) }
|
2021-05-29 03:01:07 +10:00
|
|
|
}
|
|
|
|
|
2021-06-09 20:09:20 +10:00
|
|
|
impl ops::Mul<Self> for &NativeFloat64 {
|
2021-05-29 17:51:45 +10:00
|
|
|
type Output = NativeFloat64;
|
2021-06-16 13:00:54 +10:00
|
|
|
fn mul(self, rhs: &NativeFloat64) -> Self::Output { NativeFloat64(&self.0 * &rhs.0) }
|
2021-05-29 03:01:07 +10:00
|
|
|
}
|
|
|
|
|
2021-06-09 20:09:20 +10:00
|
|
|
impl ops::Div<Self> for &NativeFloat64 {
|
2021-05-29 17:51:45 +10:00
|
|
|
type Output = NativeFloat64;
|
2021-05-30 02:28:52 +10:00
|
|
|
fn div(self, rhs: &NativeFloat64) -> Self::Output { NativeFloat64(&self.0 / &rhs.0) }
|
2021-05-29 03:01:07 +10:00
|
|
|
}
|
|
|
|
|
2021-06-09 20:09:20 +10:00
|
|
|
impl ops::Rem<Self> for &NativeFloat64 {
|
2021-05-29 17:51:45 +10:00
|
|
|
type Output = NativeFloat64;
|
|
|
|
fn rem(self, _rhs: &NativeFloat64) -> Self::Output {
|
2021-05-29 03:01:07 +10:00
|
|
|
todo!()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
impl ops::Add<&&NativeFloat> for &NativeFloat {
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
impl ops::Sub<&&NativeFloat> for &NativeFloat {
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
impl ops::Mul<&&NativeFloat> for &NativeFloat {
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
impl ops::Div<&&NativeFloat> for &NativeFloat {
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
impl ops::Rem<&&NativeFloat> for &NativeFloat {
|
|
|
|
|
|
|
|
}
|
|
|
|
*/
|