8
14
* Math done on these numbers are done using standard integer operations, and
9
15
* not floating point math.
17
* The decimal part of the FastNumber has a maximum of 3 decimals.
12
public const long MUL_FACTOR = 1000;
14
public long raw_number { public get; private set; }
19
public struct FastNumber {
20
public const int MUL_FACTOR = 1000;
22
/** Precision used to output values */
23
public const int PRECISION_DIGITS = 2;
24
/** Precision factor used to evaluate output */
25
public const int PRECISION_FACTOR = 100;
27
public long raw_number;
16
29
public long number {
17
get {return raw_number / MUL_FACTOR;}
18
set {raw_number = number * MUL_FACTOR;}
21
public FastNumber (long val = 0) {
30
public get {return (this.raw_number / MUL_FACTOR);}
31
public set {this.raw_number = (MUL_FACTOR * value);}
35
public get {return mask_and_normalize_decimal (raw_number);}
36
public set {set_decimal_of_number (ref raw_number, value);}
39
public double float_rep {
40
public get {return double.parse (@"$number.$decimal");}
41
public set {this.raw_number = parse_raw_number (value.to_string ());}
45
* Initialises a FastNumber.
47
* @param number The number that are to be set as the none-decimal part of
48
* the number. Defaults to 0.
50
* @param decimal The decimal part of the number. Defaults to 0.
52
public FastNumber (long number = 0, int decimal = 0) {
54
this.decimal = decimal;
58
* Do a deep copy of a FastNumber.
25
60
public FastNumber.copy (FastNumber other) {
26
61
this.raw_number = other.raw_number;
65
* Initialises a FastNumber from a string.
67
* Can be a decimal representation.
29
69
public FastNumber.from_string (string str) {
30
70
this.raw_number = parse_raw_number (str);
33
private static long parse_raw_number (string str) {
74
* Initialises a FastNumber from a double floating point value.
76
* Due to how floatinng point numbers works this may not be the exact value
77
* you expect it to be.
79
public FastNumber.from_float (double f) {
80
this.raw_number = parse_raw_number (f.to_string ());
84
* Initialises a FastNumber with the internal representation of that number.
86
public FastNumber.raw (long raw) {
87
this.raw_number = raw;
91
* Sets the value of this FastNumber from a string,
93
public void set_from_string (string str) {
94
this.raw_number = parse_raw_number (str);
98
* Add this to an other FastNumber.
101
* var f1 = FastNumber (3); // f1 = 3
102
* var f2 = FastNumber (2); // f2 = 2
103
* var f3 = f1.add (f2); // f3 = 5
106
* @return a newly inisialised FastNumber.
108
* @param other The other fast number you want to add to this value.
110
public FastNumber add (FastNumber? other) {
112
return FastNumber.copy (this);
115
var v = FastNumber ();
116
v.raw_number = (this.raw_number + other.raw_number);
121
* Add this to an other FastNumber.
124
* var f1 = FastNumber (3); // f1 = 3
125
* var f2 = FastNumber (2); // f2 = 2
126
* var f3 = f1.subtract (f2); // f3 = 1
129
* @return a newly inisialised FastNumber.
131
* @param other The other fast number you want to subtract from this
134
public FastNumber subtract (FastNumber? other) {
136
return FastNumber.copy (this);
139
var v = FastNumber ();
140
v.raw_number = (this.raw_number - other.raw_number);
145
* Multiply this FastNumber with another FastNumber.
148
* var f1 = FastNumber (3); // f1 = 3
149
* var f2 = FastNumber (2); // f2 = 2
150
* var f3 = f1.multiply (f2); // f3 = 6
153
* @return a newly initalised FastNumber.
155
* @param other The value you want to multiply this value with.
157
public FastNumber multiply (FastNumber? other) {
158
if (other == null || other.raw_number == 0 || this.raw_number == 0) {
159
return FastNumber ();
162
var ret = FastNumber ();
163
ret.raw_number = ((this.raw_number * other.raw_number) / MUL_FACTOR);
168
* Divide this FastNumbers with anothr FastNumber.
171
* var f1 = FastNumber (6); // f1 = 6
172
* var f2 = FastNumber (2); // f2 = 2
173
* var f3 = f1.multiply (f2); // f3 = 3
176
* @return a newly initalised FastNumber.
178
* @param other The value you want to multiply this value with.
180
public FastNumber divide (FastNumber other) throws MathError {
181
if (other.raw_number == 0) {
182
throw new MathError.DIVIDE_BY_ZERO
183
("FantNumber - trying to divide by zero");
185
var ret = FastNumber ();
186
ret.raw_number = ((this.raw_number * MUL_FACTOR) / other.raw_number);
190
[CCode (cname = "vqdr_common_fast_number_compare")]
191
public long compare (FastNumber other) {
192
return this.raw_number - other.raw_number;
196
* Round up this FastNumber and retuns it.
198
* @return a rounded up FastNumber.
200
public FastNumber round_up () {
202
long decimal = raw_number % PRECISION_FACTOR;
204
ret = FastNumber.raw (raw_number + PRECISION_FACTOR - decimal);
206
ret = FastNumber.raw (raw_number - decimal);
212
* Round up this FastNumber and retuns it.
214
* @return a rounded down FastNumber.
216
public FastNumber round_down () {
218
long decimal = raw_number % PRECISION_FACTOR;
220
// Is this ever reached?
221
ret = FastNumber.raw (raw_number - PRECISION_FACTOR - decimal);
223
ret = FastNumber.raw (raw_number - decimal);
229
* FastNumber to string.
233
* @param decimal whether to return the decimal portion of the number in
234
* the string. Default = false.
236
public string to_string (bool decimal = false) {
238
return @"$number.$decimal";
240
return number.to_string ();
244
// ***** STATIC FUNCTIONS ****//
245
public static long parse_raw_number (string str) {
35
247
int i_of_dot = str.index_of_char ('.');
36
248
if (i_of_dot >= 0) {
250
debug (@"str: $str");
38
252
// Get the decimal number from the string, if such a thing exists.
39
253
if ((str.length - 1 > i_of_dot)) {
40
254
ret_val = long.parse ((str + "000").substring (i_of_dot + 1));
257
debug (@"i_of_dot: $i_of_dot, ret_val (decimal): $ret_val\n");
43
259
// Normalise the digits.
44
260
while (ret_val > MUL_FACTOR) {
45
261
ret_val = ret_val / 10;
264
debug (@"ret_val (normalised): $ret_val\n");
48
266
// Add intiger number
49
ret_val = ret_val + (long.parse ("0" + str.substring (0, i_of_dot))
267
ret_val = ret_val + (long.parse (str.substring (0, i_of_dot))
270
debug (@"ret_val (finised): $ret_val\n");
52
273
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);
278
public static long mask_and_normalize_decimal (long number) {
279
var mask = number / MUL_FACTOR;
280
mask = mask * MUL_FACTOR;
281
return number - mask;
284
public static void set_decimal_of_number (ref long number, long decimal) {
285
var masked = number / MUL_FACTOR;
286
masked = masked * MUL_FACTOR;
287
number = masked + decimal;
290
[CCode (cname = "vqdr_common_fast_number_compare")]
291
public static extern long static_compare (FastNumber a, FastNumber b);