8
15
* Math done on these numbers are done using standard integer operations, and
9
16
* not floating point math.
18
* The decimal part of the FastNumber has a maximum of 3 decimals.
20
* How the value is devided internally is as follows:
22
(base 10) [0 0 0 0 0 .... 0 | 0 0 0 ]
23
[non-decial part | decimal]
12
public const long MUL_FACTOR = 1000;
14
public long raw_number { public get; private set; }
26
public struct FastNumber {
27
/** Precision used to output values */
28
public const int PRECISION_DIGITS = 2;
30
/** Precision factor used to evaluate output */
31
public const int PRECISION_FACTOR = 100;
33
public const int MUL_FACTOR = PRECISION_FACTOR * 10;
37
public long raw_number;
16
39
public long number {
17
get {return raw_number / MUL_FACTOR;}
18
set {raw_number = number * MUL_FACTOR;}
21
public FastNumber (long val = 0) {
40
public get {return (this.raw_number / MUL_FACTOR);}
41
public set {this.raw_number = (MUL_FACTOR * value);}
45
public get {return mask_and_normalize_decimal (raw_number);}
46
public set {set_decimal_of_number (ref raw_number, value);}
49
public double float_rep {
51
long dec = this.decimal;
52
long nbr = this.number;
53
debug (@"(float_ret_get) Float str: $nbr.$dec");
54
return double.parse (@"$nbr.$dec");
56
debug (@"(float_ret_set) set float: $value");
57
this.raw_number = parse_raw_number (value.to_string ());
62
* Initialises a FastNumber.
64
* @param number The number that are to be set as the none-decimal part of
65
* the number. Defaults to 0.
67
* @param decimal The decimal part of the number. Defaults to 0.
69
public FastNumber (long number = 0, int decimal = 0) {
71
this.decimal = decimal;
75
* Do a deep copy of a FastNumber.
25
77
public FastNumber.copy (FastNumber other) {
26
78
this.raw_number = other.raw_number;
82
* Initialises a FastNumber from a string.
84
* Can be a decimal representation.
29
86
public FastNumber.from_string (string str) {
30
87
this.raw_number = parse_raw_number (str);
33
private static long parse_raw_number (string str) {
91
* Initialises a FastNumber from a double floating point value.
93
* Due to how floatinng point numbers works this may not be the exact value
94
* you expect it to be.
96
public FastNumber.from_float (double f) {
97
this.raw_number = parse_raw_number (f.to_string ());
101
* Initialises a FastNumber with the internal representation of that number.
103
public FastNumber.raw (long raw) {
104
this.raw_number = raw;
108
* Sets the value of this FastNumber from a string,
110
public void set_from_string (string str) {
111
this.raw_number = parse_raw_number (str);
115
* Add this to an other FastNumber.
118
* var f1 = FastNumber (3); // f1 = 3
119
* var f2 = FastNumber (2); // f2 = 2
120
* var f3 = f1.add (f2); // f3 = 5
123
* @return a newly inisialised FastNumber.
125
* @param other The other fast number you want to add to this value.
127
public FastNumber add (FastNumber? other) {
129
return FastNumber.copy (this);
132
var v = FastNumber ();
133
v.raw_number = (this.raw_number + other.raw_number);
138
* Add this to an other FastNumber.
141
* var f1 = FastNumber (3); // f1 = 3
142
* var f2 = FastNumber (2); // f2 = 2
143
* var f3 = f1.subtract (f2); // f3 = 1
146
* @return a newly inisialised FastNumber.
148
* @param other The other fast number you want to subtract from this
151
public FastNumber subtract (FastNumber? other) {
153
return FastNumber.copy (this);
156
var v = FastNumber ();
157
v.raw_number = (this.raw_number - other.raw_number);
162
* Multiply this FastNumber with another FastNumber.
165
* var f1 = FastNumber (3); // f1 = 3
166
* var f2 = FastNumber (2); // f2 = 2
167
* var f3 = f1.multiply (f2); // f3 = 6
170
* @return a newly initalised FastNumber.
172
* @param other The value you want to multiply this value with.
174
public FastNumber multiply (FastNumber? other) {
175
if (other == null || other.raw_number == 0 || this.raw_number == 0) {
176
return FastNumber ();
179
var ret = FastNumber ();
180
ret.raw_number = ((this.raw_number * other.raw_number) / MUL_FACTOR);
185
* Divide this FastNumbers with anothr FastNumber.
188
* var f1 = FastNumber (6); // f1 = 6
189
* var f2 = FastNumber (2); // f2 = 2
190
* var f3 = f1.multiply (f2); // f3 = 3
193
* @return a newly initalised FastNumber.
195
* @param other The value you want to multiply this value with.
197
public FastNumber divide (FastNumber other) throws MathError {
198
if (other.raw_number == 0) {
199
throw new MathError.DIVIDE_BY_ZERO ("trying to divide by zero");
201
var ret = FastNumber ();
202
ret.raw_number = ((this.raw_number * MUL_FACTOR) / other.raw_number);
206
[CCode (cname = "vqdr_common_fast_number_compare")]
207
public long compare (FastNumber other) {
208
return this.raw_number - other.raw_number;
212
* Round up this FastNumber and retuns it.
214
* @return a rounded up FastNumber.
216
public FastNumber round_up () {
218
long decimal = raw_number % PRECISION_FACTOR;
220
ret = FastNumber.raw (raw_number + PRECISION_FACTOR - decimal);
222
ret = FastNumber.raw (raw_number - decimal);
228
* Round up this FastNumber and retuns it.
230
* @return a rounded down FastNumber.
232
public FastNumber round_down () {
234
long decimal = raw_number % PRECISION_FACTOR;
236
// Is this ever reached?
237
ret = FastNumber.raw (raw_number - PRECISION_FACTOR - decimal);
239
ret = FastNumber.raw (raw_number - decimal);
245
* FastNumber to string.
249
* @param decimal whether to return the decimal portion of the number in
250
* the string. Default = false.
252
public string to_string (bool decimal = false) {
254
return @"$number.$decimal";
256
return number.to_string ();
261
* Check if two FastNumbers are equal.
263
* @return true if this is equal to the other.
264
* @return false if this is not equal to the other.
266
public bool equals (FastNumber other) {
267
return (this.raw_number == other.raw_number);
270
// ***** STATIC FUNCTIONS ****//
271
public static long parse_raw_number (string str) {
35
273
int i_of_dot = str.index_of_char ('.');
36
274
if (i_of_dot >= 0) {
276
debug (@"str: $str");
38
277
// Get the decimal number from the string, if such a thing exists.
39
278
if ((str.length - 1 > i_of_dot)) {
40
279
ret_val = long.parse ((str + "000").substring (i_of_dot + 1));
282
debug (@"(parse_raw_number) i_of_dot: $i_of_dot, ret_val (decimal): $ret_val\n");
43
284
// Normalise the digits.
44
285
while (ret_val > MUL_FACTOR) {
45
286
ret_val = ret_val / 10;
287
debug (@"(parse_raw_number) retval (loop): $ret_val");
49
ret_val = ret_val + (long.parse ("0" + str.substring (0, i_of_dot))
290
debug (@"ret_val (normalised): $ret_val\n");
292
// get intiger number
293
ret_val = ret_val + (long.parse (str.substring (0, i_of_dot))
296
debug (@"(parse_raw_number) ret_val (finised): $ret_val\n");
52
299
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);
304
public static long mask_and_normalize_decimal (long number) {
305
debug (@"(mask_and_normalize_decimal) number: $number");
306
long mask = number / MUL_FACTOR;
307
debug (@"(mask_and_normalize_decimal) mask(1): $mask");
308
mask = mask * MUL_FACTOR;
309
debug (@"(mask_and_normalize_decimal) mask(2): $mask");
310
long ret = number - mask;
312
// This is a rathor expensive operation.
314
while ((ret % 10) == 0) {
318
debug (@"(mask_and_normalize_decimal) ret: $ret");
322
public static void set_decimal_of_number (ref long number, long decimal) {
323
debug (@"(set_decimal_of_number) number(0): $number, decimal(0): $decimal");
324
long masked = number / MUL_FACTOR;
325
debug (@"(set_decimal_of_number) masked(1): $masked");
326
masked = masked * MUL_FACTOR;
327
debug (@"(set_decimal_of_number) masked(2): $masked");
331
while (decimal < PRECISION_FACTOR) {
332
decimal = decimal * 10;
333
debug (@"(set_decimal_of_number) loop, decimal: $decimal");
337
number = masked + decimal;
338
debug (@"(set_decimal_of_number) number(1): $number");
342
[CCode (cname = "vqdr_common_fast_number_compare")]
343
public static extern long static_compare (FastNumber a, FastNumber b);