public
Created

16.16 Fixed point numbers in Haxe 3

  • Download Gist
gistfile1.hx
Haxe
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139
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));
}

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.