経緯
よく考えればもちろん作れるのだけれど,すぐ間違うのでメモをしておきます.
公式
$d \in \mathbb{Z}$,$t \in \mathbb{R}$ とする.
- $d \leq t \iff d \leq \lfloor t \rfloor$
- $d < t \iff d < \lceil t \rceil$
- $t \leq d \iff \lceil t \rceil \leq d$
- $t < d \iff \lfloor t \rfloor < d$
考え方
\begin{eqnarray*} d\leq t &\iff& t \in \{ t \mid d \leq t \} \\ &\iff& t \in \bigcup \{ [e, e+1) \mid e = d, d+1, \ldots \} \\ &\iff& \bigvee \{ t \in [e, e+1) \mid e = d, d+1, \ldots \} \\ &\iff& \bigvee \{ \lfloor t \rfloor = e \mid e = d, d+1, \ldots \} \\ &\iff& d \leq \lfloor t \rfloor \hspace{20em} \end{eqnarray*}
同様に,
\begin{eqnarray*} d<t &\iff& t \in \{ t \mid d < t \} \\ &\iff& \bigvee \{ t \in (e-1, e] \mid e = d+1, d+2, \ldots \} \\ &\iff& \bigvee \{ \lceil t \rceil = e \mid e = d+1, d+2, \ldots \} \\ &\iff& d < \lceil t \rceil \hspace{20em} \end{eqnarray*}
\begin{eqnarray*} t \leq d &\iff& \bigvee \{ t \in (e-1, e] \mid e = d, d - 1, \ldots \} \\ &\iff& \bigvee \{ \lceil t \rceil = e \mid e = d, d - 1, \ldots \} \\ &\iff& \lceil t \rceil \leq d \hspace{20em} \end{eqnarray*}
\begin{eqnarray*} t < d &\iff& \bigvee \{ t \in [e, e+1) \mid e = d - 1, d - 2, \ldots \} \\ &\iff& \bigvee \{ \lfloor t \rfloor = e \mid e = d - 1, d - 2, \ldots \} \\ &\iff& \lfloor t \rfloor < d \hspace{20em} \end{eqnarray*}
追記
(追記: 2023/03/23)
これを使う場面として良くあるのが,正の整数 $a$, $b$, $c$ について $ab \leq c$ などであるかどうかを判定したいが, $ab$ が long long に収まらないかもしれない, というとき. $ab \leq c \iff a \leq c/b \iff a \leq \lfloor c/b \rfloor$ などとして,判定すれば良い.
なお,この目的のためには,GCC の拡張 __builtin_smulll_overflow も使える (Signed - MULtiplication - Long Long). 形式は,
bool __builtin_smulll_overflow(long long a, long long b, long long* res)
で,a * b
が long long でオーバーフローする時は true が返る.
オーバーフローしない時には false が返り,*res
に積が設定される.
たとえば上記の判定は:
if (long long ab; not __builtin_smulll_overflow(a, b, &ab) and ab <= c) {
...
}
などと実現できる.