Created
April 18, 2013 14:37
-
-
Save deltaluca/5413225 to your computer and use it in GitHub Desktop.
16.16 Fixed point numbers in Haxe 3
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
abstract Fixed16(Int) { | |
inline function new(x:Int) this = x; | |
inline function raw() return this; | |
inline static function RAW(x:Int) return new Fixed16(x); | |
public static var MAX_VALUE:Fixed16 = RAW(0x7fffffff); | |
public static var MIN_VALUE:Fixed16 = RAW(1); | |
@:from public static inline function fromf(x:Float) { | |
#if debug | |
if (x >= 32768.0 || x < -32768.0) throw "Conversion to Fixed16 will overflow"; | |
#end | |
return RAW(Std.int(x*65536.0)); | |
} | |
@:from public static inline function fromi(x:Int) { | |
#if debug | |
if (x >= 1<<15 || x < -(1<<15)) throw "Conversion to Fixed16 will overflow"; | |
#end | |
return RAW(x<<16); | |
} | |
inline public function float():Float return this*0.0000152587890625; | |
inline public function int():Int return this>>16; | |
@:to public inline function tof():Float return float(this); | |
@:to public inline function toi():Int return int(this); | |
@:op(A+B) public inline static function add(f:Fixed16, g:Fixed16) { | |
#if debug | |
var fr:Float = f.raw(); | |
var gr:Float = g.raw(); | |
if (fr+gr >= 2147483648.0 || fr+gr < -2147483648.0) throw "Addition of Fixed16 values will overflow"; | |
#end | |
return RAW(f.raw()+g.raw()); | |
} | |
@:commutative @:op(A+B) public inline static function addf(f:Fixed16, g:Float) | |
return add(f, fromf(g)); | |
@:commutative @:op(A+B) public inline static function addi(f:Fixed16, g:Int) | |
return add(f, fromi(g)); | |
@:op(A-B) public inline static function sub(f:Fixed16, g:Fixed16) { | |
#if debug | |
var fr:Float = f.raw(); | |
var gr:Float = g.raw(); | |
if (fr-gr >= 2147483648.0 || fr-gr < -2147483648.0) throw "Subtraction of Fixed16 values will overflow"; | |
#end | |
return RAW(f.raw()-g.raw()); | |
} | |
@:op(A-B) public inline static function subf(f:Fixed16, g:Float) | |
return sub(f, fromf(g)); | |
@:op(A-B) public inline static function subi(f:Fixed16, g:Int) | |
return sub(f, fromi(g)); | |
@:op(A-B) public inline static function fsub(f:Float, g:Fixed16) | |
return sub(fromf(f), g); | |
@:op(A-B) public inline static function isub(f:Int, g:Fixed16) | |
return sub(fromi(f), g); | |
@:op(-A) public inline static function neg(f:Fixed16) { | |
#if debug | |
if (f.raw() == 0x80000000) throw "Negation of Fixed16 will overflow"; | |
#end | |
return RAW(-f.raw()); | |
} | |
@:op(A*B) public inline static function mul(f:Fixed16, g:Fixed16) { | |
#if debug | |
var fr:Float = f.raw(); | |
var gr:Float = g.raw(); | |
var res:Float = fr*gr*0.0000152587890625; | |
if (res >= 2147483648.0 || res < -2147483648.0) throw "Multiplication of Fixed16 values will overflow"; | |
#end | |
var ff = f&0xffff; var fi = f>>16; | |
var gf = g&0xffff; var gi = g>>16; | |
return RAW(((fi*gi)<<16) + fi*gf + ff*gi); | |
} | |
@:commutative @:op(A*B) public inline static function mulf(f:Fixed16, g:Float) | |
return mul(f, fromf(g)); | |
@:commutative @:op(A*B) public inline static function muli(f:Fixed16, g:Int) | |
return mul(f, fromi(g)); | |
@:op(A/B) public inline static function div(f:Fixed16, g:Fixed16) { | |
#if debug | |
var fr:Float = f.raw(); | |
var gr:Float = g.raw(); | |
var res:Float = fr/gr*65536.0; | |
if (res >= 2147483648.0 || res < -2147483648.0) throw "Division of Fixed16 values will overflow"; | |
#end | |
return RAW(Std.int((f.raw()/g.raw())*65536.0)); | |
} | |
@:op(A/B) public inline static function divf(f:Fixed16, g:Float) | |
return div(f, fromf(g)); | |
@:op(A/B) public inline static function divi(f:Fixed16, g:Int) | |
return div(f, fromi(g)); | |
@:op(A/B) public inline static function fdiv(f:Float, g:Fixed16) | |
return div(fromf(f), g); | |
@:op(A/B) public inline static function idiv(f:Int, g:Fixed16) | |
return div(fromi(f), g); | |
@:op(A==B) public inline static function eq(f:Fixed16, g:Fixed16) | |
return f.raw() == g.raw(); | |
@:commutative @:op(A==B) public inline static function eqf(f:Fixed16, g:Float) | |
return eq(f, fromf(g)); | |
@:commutative @:op(A==B) public inline static function eqi(f:Fixed16, g:Int) | |
return eq(f, fromi(g)); | |
@:op(A!=B) public inline static function neq(f:Fixed16, g:Fixed16) | |
return f.raw() != g.raw(); | |
@:commutative @:op(A!=B) public inline static function neqf(f:Fixed16, g:Float) | |
return neq(f, fromf(g)); | |
@:commutative @:op(A!=B) public inline static function neqi(f:Fixed16, g:Int) | |
return neq(f, fromi(g)); | |
@:op(A>B) public inline static function ngt(f:Fixed16, g:Fixed16) | |
return f.raw() > g.raw(); | |
@:commutative @:op(A>B) public inline static function ngtf(f:Fixed16, g:Float) | |
return ngt(f, fromf(g)); | |
@:commutative @:op(A>B) public inline static function ngti(f:Fixed16, g:Int) | |
return ngt(f, fromi(g)); | |
@:op(A<B) public inline static function nlt(f:Fixed16, g:Fixed16) | |
return f.raw() < g.raw(); | |
@:commutative @:op(A<B) public inline static function nltf(f:Fixed16, g:Float) | |
return nlt(f, fromf(g)); | |
@:commutative @:op(A<B) public inline static function nlti(f:Fixed16, g:Int) | |
return nlt(f, fromi(g)); | |
@:op(A>=B) public inline static function nge(f:Fixed16, g:Fixed16) | |
return f.raw() >= g.raw(); | |
@:commutative @:op(A>=B) public inline static function ngef(f:Fixed16, g:Float) | |
return nge(f, fromf(g)); | |
@:commutative @:op(A>=B) public inline static function ngei(f:Fixed16, g:Int) | |
return nge(f, fromi(g)); | |
@:op(A<=B) public inline static function nle(f:Fixed16, g:Fixed16) | |
return f.raw() <= g.raw(); | |
@:commutative @:op(A<=B) public inline static function nlef(f:Fixed16, g:Float) | |
return nle(f, fromf(g)); | |
@:commutative @:op(A<=B) public inline static function nlei(f:Fixed16, g:Int) | |
return nle(f, fromi(g)); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment