1 /* Invisible Vector Library
2 * coded by Ketmar // Invisible Vector <ketmar@ketmar.no-ip.org>
3 * Understanding is not required. Only obedience.
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, version 3 of the License ONLY.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 module iv
.follin
.ftrick
/*is aliced*/;
20 import iv
.follin
.cmacro
;
22 version = follin_use_float_trick
;
25 version(follin_use_float_trick
) {
26 //k8: actually, this is only marginally faster than using `lrintf()`, but...
27 align(1) union TrickyFloatUnion
{
32 enum declfcvar(string name
) = "TrickyFloatUnion "~name
~" = void;";
33 static assert(TrickyFloatUnion
.i
.sizeof
== 4 && TrickyFloatUnion
.f
.sizeof
== 4);
34 // add (1<<23) to convert to int, then divide by 2^SHIFT, then add 0.5/2^SHIFT to round
35 //#define check_endianness()
36 enum MAGIC(string SHIFT
) = q
{(1.5f*(1<<(23-${SHIFT
}))+0.5f/(1<<${SHIFT
}))}.cmacroFixVars
!("SHIFT")(SHIFT
);
37 enum ADDEND(string SHIFT
) = q
{(((150-${SHIFT
})<<23)+(1<<22))}.cmacroFixVars
!("SHIFT")(SHIFT
);
38 enum FAST_SCALED_FLOAT_TO_INT(string x
, string s
) = q
{temp
.f
= (${x
})+${MAGIC
}; int v
= temp
.i
-${ADDEND
};}
39 .cmacroFixVars
!("x", "s", "MAGIC", "ADDEND")(x
, s
, MAGIC
!(s
), ADDEND
!(s
));
41 enum declfcvar(string name
) = "{}";
42 template FAST_SCALED_FLOAT_TO_INT(string x
, string s
) {
43 static assert(s
== "15");
44 enum FAST_SCALED_FLOAT_TO_INT
= q
{import core
.stdc
.math
: lrintf
; int v
= lrintf((${x
})*32768.0f);}.cmacroFixVars
!"x"(x
);