diff --git a/html/worker.js b/html/worker.js index 9123168..3b603de 100644 --- a/html/worker.js +++ b/html/worker.js @@ -12,16 +12,18 @@ var numbers, election, opts, state, stageNum; onmessage = function(evt) { if (evt.data.type === 'countElection') { + numbers = 'DynNum'; + if (evt.data.numbers === 'fixed') { - numbers = 'Fixed'; + wasm.dynnum_set_kind(wasm.NumKind.Fixed); wasm.fixed_set_dps(evt.data.decimals); } else if (evt.data.numbers === 'gfixed') { - numbers = 'GuardedFixed'; + wasm.dynnum_set_kind(wasm.NumKind.GuardedFixed); wasm.gfixed_set_dps(evt.data.decimals); } else if (evt.data.numbers === 'float64') { - numbers = 'NativeFloat64'; + wasm.dynnum_set_kind(wasm.NumKind.NativeFloat64); } else if (evt.data.numbers === 'rational') { - numbers = 'Rational'; + wasm.dynnum_set_kind(wasm.NumKind.Rational); } else { throw 'Unknown --numbers'; } diff --git a/src/main.rs b/src/main.rs index 8757afc..9449308 100644 --- a/src/main.rs +++ b/src/main.rs @@ -17,7 +17,7 @@ use opentally::constraints::Constraints; use opentally::election::{Candidate, CandidateState, CountCard, CountState, Election}; -use opentally::numbers::{Fixed, GuardedFixed, NativeFloat64, Number, Rational}; +use opentally::numbers::{DynNum, Fixed, GuardedFixed, NativeFloat64, Number, NumKind, Rational}; use opentally::stv; use clap::{AppSettings, Clap}; @@ -61,6 +61,10 @@ struct STV { #[clap(help_heading=Some("NUMBERS"), long, default_value="5", value_name="dps")] decimals: usize, + /// Use dynamic dispatch for numbers + //#[clap(help_heading=Some("NUMBERS"), long)] + //dynnum: bool, + /// Convert ballots with value >1 to multiple ballots of value 1 #[clap(help_heading=Some("NUMBERS"), long)] normalise_ballots: bool, @@ -195,27 +199,21 @@ fn main() { // Create and count election according to --numbers if cmd_opts.numbers == "rational" { - let mut election: Election = Election::from_blt(lines.map(|r| r.expect("IO Error").to_string()).into_iter()); - maybe_load_constraints(&mut election, &cmd_opts.constraints); - - // Must specify :: here and in a few other places because ndarray causes E0275 otherwise - count_election::(election, cmd_opts); + DynNum::set_kind(NumKind::Rational); } else if cmd_opts.numbers == "float64" { - let mut election: Election = Election::from_blt(lines.map(|r| r.expect("IO Error").to_string()).into_iter()); - maybe_load_constraints(&mut election, &cmd_opts.constraints); - count_election::(election, cmd_opts); + DynNum::set_kind(NumKind::NativeFloat64); } else if cmd_opts.numbers == "fixed" { Fixed::set_dps(cmd_opts.decimals); - let mut election: Election = Election::from_blt(lines.map(|r| r.expect("IO Error").to_string()).into_iter()); - maybe_load_constraints(&mut election, &cmd_opts.constraints); - count_election::(election, cmd_opts); + DynNum::set_kind(NumKind::Fixed); } else if cmd_opts.numbers == "gfixed" { GuardedFixed::set_dps(cmd_opts.decimals); - - let mut election: Election = Election::from_blt(lines.map(|r| r.expect("IO Error").to_string()).into_iter()); - maybe_load_constraints(&mut election, &cmd_opts.constraints); - count_election::(election, cmd_opts); + DynNum::set_kind(NumKind::GuardedFixed); } + + let mut election: Election = Election::from_blt(lines.map(|r| r.expect("IO Error").to_string()).into_iter()); + maybe_load_constraints(&mut election, &cmd_opts.constraints); + + count_election::(election, cmd_opts); } fn maybe_load_constraints(election: &mut Election, constraints: &Option) { diff --git a/src/numbers/dynnum.rs b/src/numbers/dynnum.rs new file mode 100644 index 0000000..cb67908 --- /dev/null +++ b/src/numbers/dynnum.rs @@ -0,0 +1,503 @@ +/* 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 . + */ + +use super::{Assign, Fixed, GuardedFixed, NativeFloat64, Number, Rational}; + +use num_traits::{Num, One, Zero}; +use wasm_bindgen::prelude::wasm_bindgen; + +use std::cmp::{Ord, Ordering}; +use std::fmt; +use std::mem::ManuallyDrop; +use std::ops::{self, Deref, DerefMut}; + +#[wasm_bindgen] +pub enum NumKind { + Fixed, + GuardedFixed, + NativeFloat64, + Rational, +} + +static mut KIND: NumKind = NumKind::Fixed; + +#[inline] +fn get_kind() -> &'static NumKind { + unsafe { + return &KIND; + } +} + +pub union DynNum { + fixed: ManuallyDrop, + gfixed: ManuallyDrop, + float64: NativeFloat64, + rational: ManuallyDrop, +} + +impl DynNum { + pub fn set_kind(kind: NumKind) { + unsafe { + KIND = kind; + } + } +} + +macro_rules! impl_1arg_nowrap { + ($self:expr, $arg:expr, $func:ident) => { + // Safety: Access only correct union field + unsafe { + match get_kind() { + NumKind::Fixed => { + $self.fixed.$func($arg) + } + NumKind::GuardedFixed => { + $self.gfixed.$func($arg) + } + NumKind::NativeFloat64 => { + $self.float64.$func($arg) + } + NumKind::Rational => { + $self.rational.$func($arg) + } + } + } + } +} + +macro_rules! impl_assoc_nowrap { + ($func:ident) => { + match get_kind() { + NumKind::Fixed => { + Fixed::$func() + } + NumKind::GuardedFixed => { + GuardedFixed::$func() + } + NumKind::NativeFloat64 => { + NativeFloat64::$func() + } + NumKind::Rational => { + Rational::$func() + } + } + } +} + +impl Number for DynNum { + fn new() -> Self { + match get_kind() { + NumKind::Fixed => { + DynNum { fixed: ManuallyDrop::new(Fixed::new()) } + } + NumKind::GuardedFixed => { + DynNum { gfixed: ManuallyDrop::new(GuardedFixed::new()) } + } + NumKind::NativeFloat64 => { + DynNum { float64: NativeFloat64::new() } + } + NumKind::Rational => { + DynNum { rational: ManuallyDrop::new(Rational::new()) } + } + } + } + + fn describe() -> String { impl_assoc_nowrap!(describe) } + fn pow_assign(&mut self, exponent: i32) { impl_1arg_nowrap!(self, exponent, pow_assign) } + fn floor_mut(&mut self, dps: usize) { impl_1arg_nowrap!(self, dps, floor_mut) } + fn ceil_mut(&mut self, dps: usize) { impl_1arg_nowrap!(self, dps, ceil_mut) } +} + +impl Drop for DynNum { + fn drop(&mut self) { + // Safety: Access only correct union field + unsafe { + match get_kind() { + NumKind::Fixed => { + ManuallyDrop::drop(&mut self.fixed); + } + NumKind::GuardedFixed => { + ManuallyDrop::drop(&mut self.gfixed); + } + NumKind::NativeFloat64 => {} + NumKind::Rational => { + ManuallyDrop::drop(&mut self.rational); + } + } + } + } +} + +macro_rules! impl_0arg_wrap { + ($self:expr, $func:ident) => { + // Safety: Access only correct union field + unsafe { + match get_kind() { + NumKind::Fixed => { + DynNum { fixed: ManuallyDrop::new($self.fixed.deref().$func()) } + } + NumKind::GuardedFixed => { + DynNum { gfixed: ManuallyDrop::new($self.gfixed.deref().$func()) } + } + NumKind::NativeFloat64 => { + DynNum { float64: $self.float64.$func() } + } + NumKind::Rational => { + DynNum { rational: ManuallyDrop::new($self.rational.deref().$func()) } + } + } + } + } +} + +impl Clone for DynNum { + fn clone(&self) -> Self { impl_0arg_wrap!(self, clone) } +} + +impl Num for DynNum { + type FromStrRadixErr = Self; // TODO + + fn from_str_radix(str: &str, radix: u32) -> Result { + match get_kind() { + NumKind::Fixed => { + Ok(DynNum { fixed: ManuallyDrop::new(Fixed::from_str_radix(str, radix).unwrap()) }) + } + NumKind::GuardedFixed => { + Ok(DynNum { gfixed: ManuallyDrop::new(GuardedFixed::from_str_radix(str, radix).unwrap()) }) + } + NumKind::NativeFloat64 => { + Ok(DynNum { float64: NativeFloat64::from_str_radix(str, radix).unwrap() }) + } + NumKind::Rational => { + Ok(DynNum { rational: ManuallyDrop::new(Rational::from_str_radix(str, radix).unwrap()) }) + } + } + } +} + +macro_rules! impl_1other_nowrap { + ($self:expr, $rhs:expr, $func:ident) => { + // Safety: Access only correct union field + unsafe { + match get_kind() { + NumKind::Fixed => { + $self.fixed.deref().$func($rhs.fixed.deref()) + } + NumKind::GuardedFixed => { + $self.gfixed.deref().$func($rhs.gfixed.deref()) + } + NumKind::NativeFloat64 => { + $self.float64.$func(&$rhs.float64) + } + NumKind::Rational => { + $self.rational.deref().$func($rhs.rational.deref()) + } + } + } + } +} + +macro_rules! impl_1other_nowrap_mut { + ($self:expr, $rhs:expr, $func:ident) => { + // Safety: Access only correct union field + unsafe { + match get_kind() { + NumKind::Fixed => { + $self.fixed.deref_mut().$func($rhs.fixed.deref()) + } + NumKind::GuardedFixed => { + $self.gfixed.deref_mut().$func($rhs.gfixed.deref()) + } + NumKind::NativeFloat64 => { + $self.float64.$func(&$rhs.float64) + } + NumKind::Rational => { + $self.rational.deref_mut().$func($rhs.rational.deref()) + } + } + } + } +} + +impl Assign for DynNum { + fn assign(&mut self, src: Self) { impl_1other_nowrap_mut!(self, src, assign) } +} + +impl Assign<&Self> for DynNum { + fn assign(&mut self, src: &Self) { impl_1other_nowrap_mut!(self, src, assign) } +} + +impl From for DynNum { + fn from(n: usize) -> Self { + match get_kind() { + NumKind::Fixed => { + DynNum { fixed: ManuallyDrop::new(Fixed::from(n)) } + } + NumKind::GuardedFixed => { + DynNum { gfixed: ManuallyDrop::new(GuardedFixed::from(n)) } + } + NumKind::NativeFloat64 => { + DynNum { float64: NativeFloat64::from(n) } + } + NumKind::Rational => { + DynNum { rational: ManuallyDrop::new(Rational::from(n)) } + } + } + } +} + +impl fmt::Display for DynNum { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { impl_1arg_nowrap!(self, f, fmt) } +} + +impl fmt::Debug for DynNum { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { impl_1arg_nowrap!(self, f, fmt) } +} + +impl PartialEq for DynNum { + fn eq(&self, other: &Self) -> bool { impl_1other_nowrap!(self, other, eq) } +} + +impl Eq for DynNum {} + +impl PartialOrd for DynNum { + fn partial_cmp(&self, other: &Self) -> Option { impl_1other_nowrap!(self, other, partial_cmp) } +} + +impl Ord for DynNum { + fn cmp(&self, other: &Self) -> Ordering { impl_1other_nowrap!(self, other, cmp) } +} + +macro_rules! impl_assoc_wrap { + ($func:ident) => { + match get_kind() { + NumKind::Fixed => { + DynNum { fixed: ManuallyDrop::new(Fixed::$func()) } + } + NumKind::GuardedFixed => { + DynNum { gfixed: ManuallyDrop::new(GuardedFixed::$func()) } + } + NumKind::NativeFloat64 => { + DynNum { float64: NativeFloat64::$func() } + } + NumKind::Rational => { + DynNum { rational: ManuallyDrop::new(Rational::$func()) } + } + } + } +} + +impl One for DynNum { + fn one() -> Self { impl_assoc_wrap!(one) } +} + +macro_rules! impl_0arg_nowrap { + ($self:expr, $func:ident) => { + // Safety: Access only correct union field + unsafe { + match get_kind() { + NumKind::Fixed => { + $self.fixed.deref().$func() + } + NumKind::GuardedFixed => { + $self.gfixed.deref().$func() + } + NumKind::NativeFloat64 => { + $self.float64.$func() + } + NumKind::Rational => { + $self.rational.deref().$func() + } + } + } + } +} + +impl Zero for DynNum { + fn zero() -> Self { impl_assoc_wrap!(zero) } + + fn is_zero(&self) -> bool { impl_0arg_nowrap!(self, is_zero) } +} + +impl ops::Neg for DynNum { + type Output = Self; + fn neg(self) -> Self::Output { impl_0arg_wrap!(self, neg) } +} + +macro_rules! impl_1other_wrap { + ($self:expr, $rhs:expr, $func:ident) => { + // Safety: Access only correct union field + unsafe { + match get_kind() { + NumKind::Fixed => { + DynNum { fixed: ManuallyDrop::new($self.fixed.deref().$func($rhs.fixed.deref())) } + } + NumKind::GuardedFixed => { + DynNum { gfixed: ManuallyDrop::new($self.gfixed.deref().$func($rhs.gfixed.deref())) } + } + NumKind::NativeFloat64 => { + DynNum { float64: $self.float64.$func($rhs.float64) } + } + NumKind::Rational => { + DynNum { rational: ManuallyDrop::new($self.rational.deref().$func($rhs.rational.deref())) } + } + } + } + } +} + +impl ops::Add for DynNum { + type Output = Self; + fn add(self, rhs: Self) -> Self::Output { impl_1other_wrap!(self, rhs, add) } +} + +impl ops::Sub for DynNum { + type Output = Self; + fn sub(self, rhs: Self) -> Self::Output { impl_1other_wrap!(self, rhs, sub) } +} + +impl ops::Mul for DynNum { + type Output = Self; + fn mul(self, rhs: Self) -> Self::Output { impl_1other_wrap!(self, rhs, mul) } +} + +impl ops::Div for DynNum { + type Output = Self; + fn div(self, rhs: Self) -> Self::Output { impl_1other_wrap!(self, rhs, div) } +} + +impl ops::Rem for DynNum { + type Output = Self; + fn rem(self, rhs: Self) -> Self::Output { impl_1other_wrap!(self, rhs, rem) } +} + +impl ops::Add<&Self> for DynNum { + type Output = Self; + fn add(self, rhs: &Self) -> Self::Output { impl_1other_wrap!(self, rhs, add) } +} + +impl ops::Sub<&Self> for DynNum { + type Output = Self; + fn sub(self, rhs: &Self) -> Self::Output { impl_1other_wrap!(self, rhs, sub) } +} + +impl ops::Mul<&Self> for DynNum { + type Output = Self; + fn mul(self, rhs: &Self) -> Self::Output { impl_1other_wrap!(self, rhs, mul) } +} + +impl ops::Div<&Self> for DynNum { + type Output = Self; + fn div(self, rhs: &Self) -> Self::Output { impl_1other_wrap!(self, rhs, div) } +} + +impl ops::Rem<&Self> for DynNum { + type Output = Self; + fn rem(self, rhs: &Self) -> Self::Output { impl_1other_wrap!(self, rhs, rem) } +} + +impl ops::AddAssign for DynNum { + fn add_assign(&mut self, rhs: Self) { impl_1other_nowrap_mut!(self, rhs, add_assign) } +} + +impl ops::SubAssign for DynNum { + fn sub_assign(&mut self, rhs: Self) { impl_1other_nowrap_mut!(self, rhs, sub_assign) } +} + +impl ops::MulAssign for DynNum { + fn mul_assign(&mut self, rhs: Self) { impl_1other_nowrap_mut!(self, rhs, mul_assign) } +} + +impl ops::DivAssign for DynNum { + fn div_assign(&mut self, rhs: Self) { impl_1other_nowrap_mut!(self, rhs, div_assign) } +} + +impl ops::RemAssign for DynNum { + fn rem_assign(&mut self, rhs: Self) { impl_1other_nowrap_mut!(self, rhs, rem_assign) } +} + +impl ops::AddAssign<&Self> for DynNum { + fn add_assign(&mut self, rhs: &Self) { impl_1other_nowrap_mut!(self, rhs, add_assign) } +} + +impl ops::SubAssign<&Self> for DynNum { + fn sub_assign(&mut self, rhs: &Self) { impl_1other_nowrap_mut!(self, rhs, sub_assign) } +} + +impl ops::MulAssign<&Self> for DynNum { + fn mul_assign(&mut self, rhs: &Self) { impl_1other_nowrap_mut!(self, rhs, mul_assign) } +} + +impl ops::DivAssign<&Self> for DynNum { + fn div_assign(&mut self, rhs: &Self) { impl_1other_nowrap_mut!(self, rhs, div_assign) } +} + +impl ops::RemAssign<&Self> for DynNum { + fn rem_assign(&mut self, rhs: &Self) { impl_1other_nowrap_mut!(self, rhs, rem_assign) } +} + +impl ops::Neg for &DynNum { + type Output = DynNum; + fn neg(self) -> Self::Output { impl_0arg_wrap!(self, neg) } +} + +impl ops::Add for &DynNum { + type Output = DynNum; + fn add(self, rhs: Self) -> Self::Output { impl_1other_wrap!(self, rhs, add) } +} + +impl ops::Sub for &DynNum { + type Output = DynNum; + fn sub(self, rhs: Self) -> Self::Output { impl_1other_wrap!(self, rhs, sub) } +} + +impl ops::Mul for &DynNum { + type Output = DynNum; + fn mul(self, rhs: Self) -> Self::Output { impl_1other_wrap!(self, rhs, mul) } +} + +impl ops::Div for &DynNum { + type Output = DynNum; + fn div(self, rhs: Self) -> Self::Output { impl_1other_wrap!(self, rhs, div) } +} + +impl ops::Rem for &DynNum { + type Output = DynNum; + fn rem(self, rhs: Self) -> Self::Output { impl_1other_wrap!(self, rhs, rem) } +} + +/* +impl ops::Add<&&Rational> for &Rational { + +} + +impl ops::Sub<&&Rational> for &Rational { + +} + +impl ops::Mul<&&Rational> for &Rational { + +} + +impl ops::Div<&&Rational> for &Rational { + +} + +impl ops::Rem<&&Rational> for &Rational { + +} +*/ diff --git a/src/numbers/fixed.rs b/src/numbers/fixed.rs index f9d696c..3d6186e 100644 --- a/src/numbers/fixed.rs +++ b/src/numbers/fixed.rs @@ -281,8 +281,9 @@ impl ops::MulAssign<&Self> for Fixed { } impl ops::DivAssign<&Self> for Fixed { - fn div_assign(&mut self, _rhs: &Self) { - todo!() + fn div_assign(&mut self, rhs: &Self) { + self.0 *= get_factor(); + self.0 /= &rhs.0; } } diff --git a/src/numbers/gfixed.rs b/src/numbers/gfixed.rs index ef849a1..d9d33b8 100644 --- a/src/numbers/gfixed.rs +++ b/src/numbers/gfixed.rs @@ -122,7 +122,7 @@ impl Num for GuardedFixed { } impl PartialEq for GuardedFixed { - fn eq(&self, other: &GuardedFixed) -> bool { + fn eq(&self, other: &Self) -> bool { if &(&self.0 - &other.0).abs() < get_factor_cmp() { return true; } else { @@ -132,13 +132,13 @@ impl PartialEq for GuardedFixed { } impl PartialOrd for GuardedFixed { - fn partial_cmp(&self, other: &GuardedFixed) -> Option { + fn partial_cmp(&self, other: &Self) -> Option { return Some(self.cmp(other)); } } impl Ord for GuardedFixed { - fn cmp(&self, other: &GuardedFixed) -> Ordering { + fn cmp(&self, other: &Self) -> Ordering { if self.eq(other) { return Ordering::Equal; } else { @@ -313,8 +313,9 @@ impl ops::MulAssign<&Self> for GuardedFixed { } impl ops::DivAssign<&Self> for GuardedFixed { - fn div_assign(&mut self, _rhs: &Self) { - todo!() + fn div_assign(&mut self, rhs: &Self) { + self.0 *= get_factor(); + self.0 /= &rhs.0; } } diff --git a/src/numbers/mod.rs b/src/numbers/mod.rs index 1a67d78..bd4b191 100644 --- a/src/numbers/mod.rs +++ b/src/numbers/mod.rs @@ -30,6 +30,9 @@ mod rational_rug; //#[cfg(target_arch = "wasm32")] mod rational_num; +//#[cfg(target_arch = "wasm32")] +mod dynnum; + use num_traits::{NumAssignRef, NumRef}; use std::cmp::Ord; @@ -74,6 +77,9 @@ where } } +pub use self::dynnum::NumKind; +pub use self::dynnum::DynNum; + pub use self::fixed::Fixed; pub use self::gfixed::GuardedFixed; pub use self::native::NativeFloat64; diff --git a/src/numbers/native.rs b/src/numbers/native.rs index 5f85bf1..0dc1379 100644 --- a/src/numbers/native.rs +++ b/src/numbers/native.rs @@ -26,7 +26,7 @@ use std::ops; type ImplType = f64; /// Native 64-bit floating-point number -#[derive(Clone, Debug, Display, PartialEq, PartialOrd)] +#[derive(Copy, Clone, Debug, Display, PartialEq, PartialOrd)] pub struct NativeFloat64(ImplType); impl Number for NativeFloat64 { @@ -183,9 +183,7 @@ impl ops::MulAssign<&NativeFloat64> for NativeFloat64 { } impl ops::DivAssign<&NativeFloat64> for NativeFloat64 { - fn div_assign(&mut self, _rhs: &NativeFloat64) { - todo!() - } + fn div_assign(&mut self, rhs: &NativeFloat64) { self.0 /= &rhs.0; } } impl ops::RemAssign<&NativeFloat64> for NativeFloat64 { diff --git a/src/numbers/rational_num.rs b/src/numbers/rational_num.rs index 852472f..723a0cb 100644 --- a/src/numbers/rational_num.rs +++ b/src/numbers/rational_num.rs @@ -251,9 +251,7 @@ impl ops::MulAssign<&Rational> for Rational { } impl ops::DivAssign<&Rational> for Rational { - fn div_assign(&mut self, _rhs: &Rational) { - todo!() - } + fn div_assign(&mut self, rhs: &Rational) { self.0 /= &rhs.0; } } impl ops::RemAssign<&Rational> for Rational { diff --git a/src/numbers/rational_rug.rs b/src/numbers/rational_rug.rs index 37ef765..6a42f03 100644 --- a/src/numbers/rational_rug.rs +++ b/src/numbers/rational_rug.rs @@ -250,9 +250,7 @@ impl ops::MulAssign<&Self> for Rational { } impl ops::DivAssign<&Self> for Rational { - fn div_assign(&mut self, _rhs: &Self) { - todo!() - } + fn div_assign(&mut self, rhs: &Self) { self.0 /= &rhs.0; } } impl ops::RemAssign<&Self> for Rational { diff --git a/src/stv/wasm.rs b/src/stv/wasm.rs index 13a972c..af606ab 100644 --- a/src/stv/wasm.rs +++ b/src/stv/wasm.rs @@ -19,7 +19,7 @@ use crate::constraints::Constraints; use crate::election::{CandidateState, CountState, Election}; -use crate::numbers::{Fixed, GuardedFixed, NativeFloat64, Number, Rational}; +use crate::numbers::{DynNum, Fixed, GuardedFixed, NumKind, Number}; use crate::stv; extern crate console_error_panic_hook; @@ -31,6 +31,12 @@ use std::cmp::max; // Init +/// Wrapper for [DynNum::set_kind] +#[wasm_bindgen] +pub fn dynnum_set_kind(kind: NumKind) { + DynNum::set_kind(kind); +} + /// Wrapper for [Fixed::set_dps] #[wasm_bindgen] pub fn fixed_set_dps(dps: usize) { @@ -180,10 +186,12 @@ macro_rules! impl_type { }} } -impl_type!(Fixed); -impl_type!(GuardedFixed); -impl_type!(NativeFloat64); -impl_type!(Rational); +//impl_type!(Fixed); +//impl_type!(GuardedFixed); +//impl_type!(NativeFloat64); +//impl_type!(Rational); + +impl_type!(DynNum); /// Wrapper for [stv::STVOptions] #[wasm_bindgen]