8
14
* Math done on these numbers are done using standard integer operations, and
9
15
* not floating point math.
17
public struct FastNumber {
12
18
public const long MUL_FACTOR = 1000;
14
public long raw_number { public get; private set; }
20
/** Precision used to output values */
21
public const int PRECISION_DIGITS = 2;
22
/** Precision factor used to evaluate output */
23
public const int PRECISION_FACTOR = 100;
25
public long raw_number;
16
27
public long number {
17
get {return raw_number / MUL_FACTOR;}
18
set {raw_number = number * MUL_FACTOR;}
28
public get {return (this.raw_number / MUL_FACTOR);}
29
public set {this.raw_number = (MUL_FACTOR * value);}
33
public get {return mask_and_normalize_decimal (raw_number);}
34
public set {set_decimal_of_number (ref raw_number, value);}
37
public double float_rep {
38
public get {return double.parse (@"$number" + "." + @"$decimal");}
39
public set {this.raw_number = parse_raw_number (value.to_string ());}
21
42
public FastNumber (long val = 0) {
30
51
this.raw_number = parse_raw_number (str);
33
private static long parse_raw_number (string str) {
54
public FastNumber.from_float (double f) {
55
this.raw_number = parse_raw_number (f.to_string ());
58
public FastNumber.raw (long raw) {
59
this.raw_number = raw;
62
public void set_from_string (string str) {
63
this.raw_number = parse_raw_number (str);
66
public FastNumber add (FastNumber? other) {
68
return FastNumber.copy (this);
71
var v = FastNumber ();
72
v.raw_number = (this.raw_number + other.raw_number);
76
public FastNumber subtract (FastNumber? other) {
78
return FastNumber.copy (this);
81
var v = FastNumber ();
82
v.raw_number = (this.raw_number - other.raw_number);
86
public FastNumber multiply (FastNumber? other) {
87
if (other == null || other.raw_number == 0) {
91
var ret = FastNumber ();
92
ret.raw_number = ((this.raw_number * other.raw_number) / MUL_FACTOR);
96
public FastNumber divide (FastNumber other) throws MathError {
97
if (other.raw_number == 0) {
98
throw new MathError.DIVIDE_BY_ZERO
99
("FantNumber - trying to divide by zero");
101
var ret = FastNumber ();
102
ret.raw_number = ((this.raw_number * MUL_FACTOR) / other.raw_number);
106
[CCode (cname = "vqdr_common_fast_number_compare")]
107
public long compare (FastNumber other) {
108
return this.raw_number - other.raw_number;
111
public FastNumber round_up () {
113
long decimal = raw_number % PRECISION_FACTOR;
115
ret = FastNumber.raw (raw_number + PRECISION_FACTOR - decimal);
117
ret = FastNumber.raw (raw_number - decimal);
122
public FastNumber round_down () {
124
long decimal = raw_number % PRECISION_FACTOR;
126
// Is this ever reached?
127
ret = FastNumber.raw (raw_number - PRECISION_FACTOR - decimal);
129
ret = FastNumber.raw (raw_number - decimal);
134
public string to_string (bool decimal = false) {
136
return number.to_string () + "." + decimal.to_string ();
138
return number.to_string ();
142
// ***** STATIC FUNCTIONS ****//
143
public static long parse_raw_number (string str) {
35
145
int i_of_dot = str.index_of_char ('.');
36
146
if (i_of_dot >= 0) {
148
debug (@"str: $str");
38
150
// Get the decimal number from the string, if such a thing exists.
39
151
if ((str.length - 1 > i_of_dot)) {
40
152
ret_val = long.parse ((str + "000").substring (i_of_dot + 1));
155
debug (@"i_of_dot: $i_of_dot, ret_val (decimal): $ret_val\n");
43
157
// Normalise the digits.
44
158
while (ret_val > MUL_FACTOR) {
45
159
ret_val = ret_val / 10;
162
debug (@"ret_val (normalised): $ret_val\n");
48
164
// Add intiger number
49
ret_val = ret_val + (long.parse ("0" + str.substring (0, i_of_dot))
165
ret_val = ret_val + (long.parse (str.substring (0, i_of_dot))
168
debug (@"ret_val (finised): $ret_val\n");
52
171
ret_val = long.parse (str) * MUL_FACTOR;
58
public FastNumber add (FastNumber? other) {
60
return new FastNumber.copy (this);
63
var v = new FastNumber (this.raw_number + other.raw_number);
68
public FastNumber subtract (FastNumber? other) {
70
return new FastNumber.copy (this);
73
var v = new FastNumber (this.raw_number - other.raw_number);
78
public FastNumber multiply (FastNumber? other) {
79
if (other == null || other.raw_value == 0) {
80
return new FastNumber ();
83
return new FastNumber ((this.raw_number * other.raw_number) / MUL_FACTOR);
86
public FastNumber divide (FastNumber? other) throws MathError {
87
if (other.raw_number == 0) {
88
throw new MathError.DIVIDE_BY_ZERO
89
("FantNumber - trying to divide by zero");
92
return new FastNumber ((this.raw_number * MUL_FACTOR) / other.raw_number);
176
public static long mask_and_normalize_decimal (long number) {
177
var mask = number / MUL_FACTOR;
178
mask = mask * MUL_FACTOR;
179
return number - mask;
182
public static void set_decimal_of_number (ref long number, long decimal) {
183
var masked = number / MUL_FACTOR;
184
masked = masked * MUL_FACTOR;
185
number = masked + decimal;
188
[CCode (cname = "vqdr_common_fast_number_compare")]
189
public static extern long static_compare (FastNumber a, FastNumber b);