Skip to content

Instantly share code, notes, and snippets.

@ashiato45
Last active February 12, 2021 15:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ashiato45/af67682563bee6d72602cfded3bc5918 to your computer and use it in GitHub Desktop.
Save ashiato45/af67682563bee6d72602cfded3bc5918 to your computer and use it in GitHub Desktop.
mod inf_num{
use std::fmt;
use std::ops::*;
pub trait Base: Ord + std::fmt::Display + Add<Output=Self> + Neg<Output=Self> + Mul<Output=Self> + Sized + Clone + fmt::Debug {
fn zero() -> Self;
}
impl Base for i64{
fn zero() -> Self{
return 0;
}
}
#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Debug, Copy)]
pub enum InfNum<T: Base>{
NegInf,
Raw(T),
PosInf
}
impl<T: Base> std::ops::Add for InfNum<T>{
type Output = Self;
fn add(self, rhs: Self) -> Self {
match (&self, &rhs) {
(InfNum::Raw(l), InfNum::Raw(r)) => {
let res = l.clone() + r.clone();
InfNum::<T>::Raw(res)
},
(Self::Raw(l), Self::NegInf) => Self::NegInf,
(Self::NegInf, Self::Raw(r)) => Self::NegInf,
(Self::Raw(_), Self::PosInf) => Self::PosInf,
(Self::PosInf, Self::Raw(_)) => Self::PosInf,
_ => panic!("Adding {} and {}", self, rhs),
}
}
}
impl<T: Base> std::ops::AddAssign for InfNum<T> {
fn add_assign(&mut self, rhs: Self) {
*self = self.clone() + rhs;
}
}
impl<T: Base> Neg for InfNum<T> {
type Output = Self;
fn neg(self) -> Self::Output {
match &self {
Self::Raw(x) => Self::Raw({
let y = -(x.clone());
y
}),
Self::PosInf => Self::NegInf,
Self::NegInf => Self::PosInf
}
}
}
impl<T: Base> Sub for InfNum<T> {
type Output = Self;
fn sub(self, other: Self) -> Self::Output {
return self + (-other);
}
}
impl<T: Base> std::ops::SubAssign for InfNum<T> {
fn sub_assign(&mut self, rhs: Self) {
*self = self.clone() - rhs;
}
}
impl<T: Base> std::ops::Mul for InfNum<T>{
type Output = Self;
fn mul(self, rhs: Self) -> Self::Output {
match (&self, &rhs) {
(InfNum::Raw(l), InfNum::Raw(r)) => Self::Raw(l.clone() * r.clone()),
(Self::Raw(l), Self::NegInf) => {
if *l > T::zero(){
Self::NegInf
}else if *l < T::zero(){
Self::PosInf
}else{
Self::Raw(T::zero())
}
},
(Self::NegInf, Self::Raw(_)) => Self::mul(rhs, self),
(Self::Raw(l), Self::PosInf) => {
if *l > T::zero(){
Self::PosInf
}else if *l < T::zero(){
Self::NegInf
}else{
Self::Raw(T::zero())
}
},
(Self::PosInf, Self::Raw(_)) => Self::mul(rhs, self),
(Self::PosInf, Self::PosInf) => Self::PosInf,
(Self::PosInf, Self::NegInf) => Self::NegInf,
(Self::NegInf, Self::PosInf) => Self::NegInf,
(Self::NegInf, Self::NegInf) => Self::PosInf
}
}
}
impl<T: Base> std::ops::MulAssign for InfNum<T> {
fn mul_assign(&mut self, rhs: Self) {
*self = self.clone() * rhs;
}
}
impl<T: Base> fmt::Display for InfNum<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
InfNum::<T>::Raw(v) => write!(f, "{}", v),
InfNum::<T>::NegInf => write!(f, "-∞"),
InfNum::<T>::PosInf => write!(f, "+∞")
}
}
}
#[test]
fn test_infnum(){
assert!(InfNum::PosInf > InfNum::Raw(4));
assert_eq!(InfNum::Raw(13) + InfNum::NegInf , InfNum::NegInf);
assert_eq!(InfNum::Raw(13) - InfNum::PosInf , InfNum::NegInf);
}
}
use inf_num::InfNum;
type INF64 = InfNum<i64>;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment