/vqdr/trunk

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/vqdr/trunk

« back to all changes in this revision

Viewing changes to src/common/fast_number.vala

  • Committer: Gustav Hartvigsson
  • Date: 2021-09-15 17:10:52 UTC
  • Revision ID: gustav.hartvigsson@gmail.com-20210915171052-yhdw16iyipyj5a5l
* Fixed Fastnumber's normalisation problem with the getters/setters

Show diffs side-by-side

added added

removed removed

Lines of Context:
3
3
 *
4
4
 * Created by Gustav Hartivgsson.
5
5
 */
 
6
using GLib;
6
7
 
7
8
namespace VQDR.Common {
8
9
  
15
16
   * not floating point math.
16
17
   * 
17
18
   * The decimal part of the FastNumber has a maximum of 3 decimals.
 
19
   * 
 
20
   * How the value is devided internally is as follows:
 
21
   * {{{
 
22
     (base 10) [0 0 0 0 0 .... 0 | 0 0 0  ]
 
23
             [non-decial part  | decimal]
 
24
   * }}}
18
25
   */
19
26
  public struct FastNumber {
20
 
    public const int MUL_FACTOR = 1000;
21
 
    
22
27
    /** Precision used to output values */
23
28
    public const int PRECISION_DIGITS = 2;
 
29
    
24
30
    /** Precision factor used to evaluate output */
25
31
    public const int PRECISION_FACTOR = 100;
26
32
    
 
33
    public const int MUL_FACTOR = PRECISION_FACTOR * 10;
 
34
    
 
35
 
 
36
    
27
37
    public long raw_number;
28
38
    
29
39
    public long number {
37
47
    }
38
48
    
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 ());}
 
50
      public get {
 
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");
 
55
      } public set {
 
56
        debug (@"(float_ret_set) set float: $value");
 
57
        this.raw_number = parse_raw_number (value.to_string ());
 
58
      }
42
59
    }
43
60
    
44
61
    /**
179
196
     */
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");
184
200
      }
185
201
      var ret =  FastNumber ();
186
202
      ret.raw_number = ((this.raw_number * MUL_FACTOR) / other.raw_number);
241
257
      }
242
258
    } 
243
259
    
 
260
    /**
 
261
     * Check if two FastNumbers are equal.
 
262
     * 
 
263
     * @return true if this is equal to the other.
 
264
     * @return false if this is not equal to the other.
 
265
     */
 
266
    public bool equals (FastNumber other) {
 
267
      return (this.raw_number == other.raw_number);
 
268
    }
 
269
    
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) {
249
275
        
250
276
        debug (@"str: $str");
251
 
        
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));
255
280
        }
256
281
        
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");
258
283
        
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");
262
288
        }
263
289
        
264
290
        debug (@"ret_val (normalised): $ret_val\n");
265
291
        
266
 
        // Add intiger number
 
292
        // get intiger number
267
293
        ret_val = ret_val + (long.parse (str.substring (0, i_of_dot))
268
294
                            * MUL_FACTOR);
269
295
        
270
 
        debug (@"ret_val (finised): $ret_val\n");
 
296
        debug (@"(parse_raw_number) ret_val (finised): $ret_val\n");
271
297
        
272
298
      } else {
273
299
        ret_val = long.parse (str) * MUL_FACTOR;
276
302
    }
277
303
    
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;
 
311
      // normalise
 
312
      // This is a rathor expensive operation.
 
313
      if (ret != 0) {
 
314
        while ((ret % 10) == 0) {
 
315
          ret = ret / 10;
 
316
        }
 
317
      }
 
318
      debug (@"(mask_and_normalize_decimal) ret: $ret");
 
319
      return ret;
282
320
    }
283
321
    
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");
 
328
      
 
329
      // Normalise didgits
 
330
      if (decimal != 0) {
 
331
        while (decimal < PRECISION_FACTOR) {
 
332
          decimal = decimal * 10;
 
333
          debug (@"(set_decimal_of_number) loop, decimal: $decimal");
 
334
        }
 
335
      }
 
336
      
287
337
      number = masked + decimal;
 
338
      debug (@"(set_decimal_of_number) number(1): $number");
 
339
      
288
340
    }
289
 
    
 
341
      
290
342
    [CCode (cname = "vqdr_common_fast_number_compare")]
291
343
    public static extern long static_compare (FastNumber a, FastNumber b);
292
344
  }