Struct nekolib::math::ConstDiv

source ·
pub struct ConstDiv { /* private fields */ }
Expand description

定数除算。

除算命令は重いので、加減算や乗算で置き換えることを考える。 同じ値で何度も除算する際には、あらかじめ置き換える値を先に求めておくことで高速化できる。

以下、$d$ による除算を行うとする。$d = 2^s$ であれば $s$ bit 右シフトするだけなので、$2$ べきではないとする。magic number $M_d$ とシフト幅 $s$ を求めておき、次の式に基づいて計算する。 $$ \lfloor n/d\rfloor = \left\lfloor\frac{M_d\cdot n}{2^s}\right\rfloor. $$ $M_d$ は、ある $0\le r\lt d$ が存在して次の形になる。 $$ M_d = \frac{2^s+r}{d} = 1+\left\lfloor\frac{2^s-1}{d}\right\rfloor. $$

$M_d$ と $s$ が満たすべき性質について考える。$0\le n\lt 2^w$ に対して常に次の式が成り立ってほしい。$w$ はワードサイズで、ここでは $w=64$ とする。 $$ \lfloor n/d\rfloor = \left\lfloor\frac{2^s+r}{d}\cdot\frac{n}{2^s}\right\rfloor = \left\lfloor\frac{n\vphantom{2^s}}{d} + \frac{r\cdot n}{2^s}\right\rfloor. $$

有理数と床関数の性質から、$r\cdot n/2^s \lt 1/d$ が常に成り立てばよい。 このとき、$0\le M_d\lt 2^{w+1}$ をみたす $M_d$ が存在することを示す。 すなわち、$\lfloor M_d/2^w\rfloor\in\{0, 1\}$ となる。todo!()

さて、$M_d$ が見つかったとする。$0\le M_d\lt 2^w$ であれば上の式に基づいて、 直接計算できる。一方で、$2^w\le M_d\lt 2^{w+1}$ の場合はワードサイズに収まらないので、 少々工夫する必要がある。$M_d-2^w$ はワードサイズに収まるので、それを利用する。 todo!()

References

  • Warren, Henry S. Hacker’s delight. Pearson Education, 2013.

Implementations§

source§

impl ConstDiv

source

pub fn new(n: u64) -> Self

source

pub fn quot(&self, n: u64) -> u64

source

pub fn rem(&self, n: u64) -> u64

Trait Implementations§

source§

impl Clone for ConstDiv

source§

fn clone(&self) -> ConstDiv

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for ConstDiv

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl PartialEq<ConstDiv> for ConstDiv

source§

fn eq(&self, other: &ConstDiv) -> bool

This method tests for self and other values to be equal, and is used by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
source§

impl Copy for ConstDiv

source§

impl Eq for ConstDiv

source§

impl StructuralEq for ConstDiv

source§

impl StructuralPartialEq for ConstDiv

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for Twhere T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T, U> Into<U> for Twhere U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T> ToOwned for Twhere T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for Twhere U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for Twhere V: MultiLane<T>,

§

fn vzip(self) -> V