15
16
* not floating point math.
17
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]
19
26
public struct FastNumber {
20
public const int MUL_FACTOR = 1000;
22
27
/** Precision used to output values */
23
28
public const int PRECISION_DIGITS = 2;
24
30
/** Precision factor used to evaluate output */
25
31
public const int PRECISION_FACTOR = 100;
33
public const int MUL_FACTOR = PRECISION_FACTOR * 10;
27
37
public long raw_number;
29
39
public long number {
39
49
public double float_rep {
40
public get {return double.parse (@"$number.$decimal");}
41
public set {this.raw_number = parse_raw_number (value.to_string ());}
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 ());
180
197
public FastNumber divide (FastNumber other) throws MathError {
181
198
if (other.raw_number == 0) {
182
throw new MathError.DIVIDE_BY_ZERO
183
("FantNumber - trying to divide by zero");
199
throw new MathError.DIVIDE_BY_ZERO ("trying to divide by zero");
185
201
var ret = FastNumber ();
186
202
ret.raw_number = ((this.raw_number * MUL_FACTOR) / other.raw_number);
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);
244
270
// ***** STATIC FUNCTIONS ****//
245
271
public static long parse_raw_number (string str) {
246
272
long ret_val = 0;
248
274
if (i_of_dot >= 0) {
250
276
debug (@"str: $str");
252
277
// Get the decimal number from the string, if such a thing exists.
253
278
if ((str.length - 1 > i_of_dot)) {
254
279
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");
282
debug (@"(parse_raw_number) i_of_dot: $i_of_dot, ret_val (decimal): $ret_val\n");
259
284
// Normalise the digits.
260
285
while (ret_val > MUL_FACTOR) {
261
286
ret_val = ret_val / 10;
287
debug (@"(parse_raw_number) retval (loop): $ret_val");
264
290
debug (@"ret_val (normalised): $ret_val\n");
266
// Add intiger number
292
// get intiger number
267
293
ret_val = ret_val + (long.parse (str.substring (0, i_of_dot))
270
debug (@"ret_val (finised): $ret_val\n");
296
debug (@"(parse_raw_number) ret_val (finised): $ret_val\n");
273
299
ret_val = long.parse (str) * MUL_FACTOR;
278
304
public static long mask_and_normalize_decimal (long number) {
279
var mask = number / MUL_FACTOR;
305
debug (@"(mask_and_normalize_decimal) number: $number");
306
long mask = number / MUL_FACTOR;
307
debug (@"(mask_and_normalize_decimal) mask(1): $mask");
280
308
mask = mask * MUL_FACTOR;
281
return number - mask;
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");
284
322
public static void set_decimal_of_number (ref long number, long decimal) {
285
var masked = number / MUL_FACTOR;
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");
286
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");
287
337
number = masked + decimal;
338
debug (@"(set_decimal_of_number) number(1): $number");
290
342
[CCode (cname = "vqdr_common_fast_number_compare")]
291
343
public static extern long static_compare (FastNumber a, FastNumber b);