Class: FixedPt

Inherits:
Object
  • Object
show all
Defined in:
lib/fixedpt/fixedpt.rb,
ext/fixedpt.c

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(val, total_bits = nil, binpt = nil, overflow_handler = :saturate) ⇒ FixedPt

Returns a new instance of FixedPt.



108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
# File 'lib/fixedpt/fixedpt.rb', line 108

def initialize(val,total_bits=nil,binpt=nil,overflow_handler=:saturate)
  #TODO: what if total_bits and binpt are nil?
  #raise "binpt should be less than total_bits!" if binpt > total_bits
  @overflow = false
  @overflow_handler = overflow_handler
  @max_int_value = 0
  case val
  when Fixnum
    construct_from_fixnum(val,total_bits,binpt)
  when Float
    construct_from_float(val,total_bits,binpt)
  when FixedPt #essentially a copy constructor
    #was:@ival = val.ival
    @ival = check_for_overflow(val.ival)
    @bits = total_bits || val.bits #so you can override total # of bits
    @binpt= val.binpt #but binpt should remain at same position(for now)
    @sign = val.sign
    @frac_width = @binpt
    @int_width  = @bits - @binpt

  when RawFixedPt
    #construct a FixedPt with a RawFixedPt
    @ival = val.rawval
    @bits = val.bits
    @binpt= val.binpt
    @sign = val.sign
    @frac_width = @binpt
    @int_width  = @bits - @binpt
  else
  end
end

Instance Attribute Details

#binptObject

Returns the value of attribute binpt.



121
122
123
# File 'ext/fixedpt.c', line 121

def binpt
  @binpt
end

#bitsObject

Returns the value of attribute bits.



106
107
108
# File 'ext/fixedpt.c', line 106

def bits
  @bits
end

#frac_widthObject

Returns the value of attribute frac_width.



106
107
108
# File 'lib/fixedpt/fixedpt.rb', line 106

def frac_width
  @frac_width
end

#int_widthObject

Returns the value of attribute int_width.



106
107
108
# File 'lib/fixedpt/fixedpt.rb', line 106

def int_width
  @int_width
end

#ivalObject

Returns the value of attribute ival.



101
102
103
# File 'ext/fixedpt.c', line 101

def ival
  @ival
end

#max_int_valueObject (readonly)

Returns the value of attribute max_int_value.



107
108
109
# File 'lib/fixedpt/fixedpt.rb', line 107

def max_int_value
  @max_int_value
end

#maxintObject

Returns the value of attribute maxint.



131
132
133
# File 'ext/fixedpt.c', line 131

def maxint
  @maxint
end

#minintObject

Returns the value of attribute minint.



106
107
108
# File 'lib/fixedpt/fixedpt.rb', line 106

def minint
  @minint
end

#overflowObject (readonly)

Returns the value of attribute overflow.



107
108
109
# File 'lib/fixedpt/fixedpt.rb', line 107

def overflow
  @overflow
end

#signObject

Returns the value of attribute sign.



126
127
128
# File 'ext/fixedpt.c', line 126

def sign
  @sign
end

Instance Method Details

#*(other) ⇒ Object



265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
# File 'lib/fixedpt/fixedpt.rb', line 265

def *(other)
  if Fixnum === other || Float === other
    other = FixedPt.new(other,@bits,@binpt) 
  end
  if sizes_differ?(other)
    
    int_width,frac_width = adjust_sizes(other) 
    a = FixedPt.new(self.to_f,(int_width+frac_width),frac_width)
    b = FixedPt.new(other.to_f,(int_width+frac_width),frac_width)
    return (a * b)
  else
    result = ((self.value) * (other.value))  
    return FixedPt.new(RawFixedPt.new(result,(2*@bits),2*@binpt),nil,nil)
  end
  #end
end

#+(other) ⇒ Object

assume result size is self size



308
309
310
311
312
313
314
315
316
317
318
319
320
321
# File 'lib/fixedpt/fixedpt.rb', line 308

def +(other) #assume result size is self size
    if Fixnum === other || Float === other
      other = FixedPt.new(other,@bits,@binpt) 
    end
    if sizes_differ?(other)
      int_width,frac_width = adjust_sizes(other) 
	a = FixedPt.new(self.to_f,(int_width+frac_width),frac_width)
	b = FixedPt.new(other.to_f,(int_width+frac_width),frac_width)
      return (a + b)
    else
      result = (self.value ) + (other.value ) 
      return FixedPt.new(RawFixedPt.new(result, @bits, @binpt),nil,nil )#,sign))
    end
end

#-(other) ⇒ Object

assume result size is self size



331
332
333
334
335
336
337
338
339
340
341
342
343
344
# File 'lib/fixedpt/fixedpt.rb', line 331

def -(other) #assume result size is self size
  if Fixnum === other || Float === other
    other = FixedPt.new(other,@bits,@binpt) 
  end
  if sizes_differ?(other)
    int_width,frac_width = adjust_sizes(other) 
    a = FixedPt.new(self.to_f,(int_width+frac_width),frac_width)
    b = FixedPt.new(other.to_f,(int_width+frac_width),frac_width)
    return (a - b)
  else
    result = (self.value ) - (other.value ) 
    return FixedPt.new(RawFixedPt.new(result, @bits, @binpt),nil,nil )#,sign))
  end
end

#/(other) ⇒ Object



259
260
261
262
263
# File 'lib/fixedpt/fixedpt.rb', line 259

def /(other)
  #pass the buck: implement in terms of multiplication
  result = ((self) * (FixedPt.new((1.0/other.to_f),@bits,@binpt)))  
  return result
end

#<<(num) ⇒ Object



300
301
302
# File 'lib/fixedpt/fixedpt.rb', line 300

def <<(num)
  result = FixedPt.new(RawFixedPt.new(((self.raw)<<num),@bits,@binpt),@bits,@binpt)
end

#adjust_sizes(other) ⇒ Object

static VALUE fp_sizes_differ(VALUE self, VALUE other) {

VALUE ret_bool = T_FALSE;
int selfbits     = FIX2INT(fp_bits(self));
int otherbits    = FIX2INT(fp_bits(other));
int selfbinpt    = FIX2INT(fp_binpt(self));
int otherbinpt   = FIX2INT(fp_binpt(other));

//if( (FIX2INT(fp_bits(self)) != FIX2INT(fp_bits(other))) || (FIX2INT(fp_binpt(self)) != FIX2INT(fp_binpt(other)))  )
if((selfbits != otherbits) || (selfbinpt != otherbinpt))
{

  printf("  self size is: %d  other size is: %d\n", selfbits,otherbits);
  printf("  self binpt is: %d  other binpt is: %d\n", selfbinpt,otherbinpt);
  ret_bool = T_TRUE;
}
return  ret_bool;

}



216
217
218
219
220
221
222
223
224
225
226
227
228
# File 'ext/fixedpt.c', line 216

static VALUE fp_adjust_sizes(VALUE self, VALUE other)
{
  //make array to return:
  VALUE ret_array = rb_ary_new();
  int self_width  = FIX2INT(fp_int_width(self));
  int other_width = FIX2INT(fp_int_width(other));
  int self_frac_width  = FIX2INT(fp_frac_width(self));
  int other_frac_width = FIX2INT(fp_frac_width(other));
  rb_ary_push(ret_array, INT2FIX(max(self_width,other_width)));
  rb_ary_push(ret_array, INT2FIX(max(self_frac_width,other_frac_width)));
  
  return ret_array;
}

#assign(val) ⇒ Object



177
178
179
180
181
182
183
184
185
186
187
188
189
190
# File 'lib/fixedpt/fixedpt.rb', line 177

def assign(val)
  case val
  when Float
    #was:@ival = from_float(val)
    from_float(val)
    check_sign(val)
  when Fixnum
    @ival = (val << @binpt )
    check_sign(val)
  when FixedPt
    from_FixedPt(val)
  else
  end
end

#calc_min_maxObject

static VALUE fp_check_sizes(VALUE self, VALUE other) {

int this_binpt  = FIX2INT(fp_binpt(self));
int other_binpt = FIX2INT(fp_binpt(other));
if(this_binpt != other_binpt ){
  rb_raise(rb_eRuntimeError, "binary points don't match: ( %d != %d)\n",this_binpt, other_binpt);
}
return self;

}



184
185
186
187
188
189
190
191
192
193
# File 'ext/fixedpt.c', line 184

static VALUE fp_calc_min_max(VALUE self)
{
  int bits    = FIX2INT(fp_bits(self));
  int binpt   = FIX2INT(fp_binpt(self)); 
  int intbits = bits - binpt;
  long maxint  = pow(2,intbits)-1;
  rb_iv_set( self,"@maxint", LONG2FIX(maxint) ) ;
  rb_iv_set( self,"@minint", LONG2FIX(-1*maxint) ) ;
  return self;
}

#check_binptObject



140
141
142
# File 'lib/fixedpt/fixedpt.rb', line 140

def check_binpt
  raise "binpt should be less than total_bits!" if @binpt >= @total_bits
end

#check_for_overflow(result) ⇒ Object

rb_define_method(cFixedPt,“multiply”,fp_value,1);



147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
# File 'ext/fixedpt.c', line 147

static VALUE fp_check_for_overflow(VALUE self, VALUE result)
{
  
  long val   = FIX2LONG(result);
  int binpt  = FIX2INT(fp_binpt(self));
  int bits   = FIX2INT(fp_bits(self));
  long maxint= FIX2LONG(fp_maxint(self));
  long tmpval;
  if(binpt == bits) return result;
  if((tmpval = val >> binpt)  > maxint ){
    //printf("OVERFLOW\n"); 
    //result = LONG2FIX(pow(2,(bits-1)));
   
    result = rb_funcall(self,rb_intern("send"),2,rb_iv_get(self,"@overflow_handler"),result);
    if(tmpval > FIX2LONG(rb_iv_get(self,"@max_int_value")))
      rb_iv_set(self,"@max_int_value",LONG2NUM(tmpval));
  }
  return result;
}

#check_sign(val) ⇒ Object

rb_define_method(cFixedPt,“initialize”,fp_init,3);



28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# File 'ext/fixedpt.c', line 28

static VALUE fp_check_sign(VALUE self, VALUE val)
{
  double i = NUM2DBL(val);
  //printf("i is: %f\n",i);

  if(i < 0.0) {
   // retval = -1;
   rb_iv_set(self,"@sign",minus_one);
  }else {
   // retval = 1;
   rb_iv_set(self,"@sign",positive_one);
  }
  //return INT2FIX(retval);
  return self;
}

#coerce(other) ⇒ Object



323
324
325
326
327
328
329
# File 'lib/fixedpt/fixedpt.rb', line 323

def coerce(other)
  if Integer === other
    [other, self.value]
  else
    [other.to_f,self.to_f]
  end
end

#construct_from_fixnum(val, total_bits, binpt) ⇒ Object



147
148
149
150
151
152
153
154
155
156
157
# File 'lib/fixedpt/fixedpt.rb', line 147

def construct_from_fixnum(val,total_bits,binpt)
  @bits = total_bits
  @binpt= binpt
  calc_min_max
  check_sign(val)
  #was:@ival = (val.abs << binpt)  
  @ival = check_for_overflow(val.abs << binpt)  
  @frac_width = @binpt
  @int_width  = @bits - @binpt
  puts "@ival is: #{@ival}" if $DEBUG
end

#construct_from_float(val, total_bits, binpt) ⇒ Object



159
160
161
162
163
164
165
166
167
168
169
170
# File 'lib/fixedpt/fixedpt.rb', line 159

def construct_from_float(val,total_bits,binpt)
  @bits = total_bits
  @binpt= binpt
  @frac_width = binpt
  @int_width  = total_bits - binpt
  calc_min_max
  check_sign(val)
  #was:@ival = (val*(2**@binpt)).round.abs #NOTE:do we want to round or not?
  #then:@ival = check_for_overflow(val*(2**@binpt)).round.abs #NOTE:do we want to round or not?
  #now:
  from_float(val)
end

#from_FixedPt(other) ⇒ Object



192
193
194
195
196
197
198
# File 'lib/fixedpt/fixedpt.rb', line 192

def from_FixedPt(other)
  if sizes_differ?(other)
    other = FixedPt.new(other.to_f,@bits,@binpt)  
  end
  @ival = check_for_overflow(other.raw)
  @sign = other.sign
end

#from_float(val) ⇒ Object



172
173
174
175
# File 'lib/fixedpt/fixedpt.rb', line 172

def from_float(val)
  #was: (val*(2**@binpt)).round.abs #NOTE:do we want to round or not?
  @ival = check_for_overflow((val*(2**@binpt)).round.abs) #NOTE:do we want to round or not?
end

#ranged_int_partObject



304
305
306
# File 'lib/fixedpt/fixedpt.rb', line 304

def ranged_int_part
  @ival = (@ival & 2**@bits-1)
end

#rawObject



200
201
202
# File 'lib/fixedpt/fixedpt.rb', line 200

def raw
  @ival
end

#rawvalObject



97
98
99
100
# File 'ext/fixedpt.c', line 97

static VALUE fp_rawval(VALUE self)
{
  return rb_iv_get(self,"@ival");
}

#saturate(result) ⇒ Object



167
168
169
170
# File 'ext/fixedpt.c', line 167

static VALUE fp_saturate(VALUE self, VALUE result)
{
  return ( LONG2FIX( pow(2,(FIX2INT(fp_bits(self))))-1 ) );
}

#shift_left(num) ⇒ Object

perhaps this could be called ‘increase_resolution’ effect: it preserves the integer portion of the number and increases the number of positions to the right of the binary point this increasing resolution



286
287
288
289
# File 'lib/fixedpt/fixedpt.rb', line 286

def shift_left(num) #for conversion purposes
  #maintain same integer range, add fractional bits
  result = FixedPt.new(RawFixedPt.new(((self.raw) << num),(@bits+num),(@binpt+num)),nil,nil)
end

#shift_right(num) ⇒ Object

for conversion purposes, integer portion should



291
292
293
294
295
296
297
# File 'lib/fixedpt/fixedpt.rb', line 291

def shift_right(num) #for conversion purposes, integer portion should
              #be preserved
  if num > @binpt
    raise "can't shift right #{num} positions: only #{@binpt} positions"
  end
  return FixedPt.new(RawFixedPt.new((self.raw>>num),(@bits-num),(@binpt-num)),nil,nil) 
end

#sizes_differ?(other) ⇒ Boolean

Returns:

  • (Boolean)


255
256
257
# File 'lib/fixedpt/fixedpt.rb', line 255

def sizes_differ? (other)
  return ( self.binpt != other.binpt || self.bits != other.bits )
end

#to_binObject



204
205
206
207
208
209
210
211
212
# File 'lib/fixedpt/fixedpt.rb', line 204

def to_bin
  #str = sprintf("%0#{@bits}b",@ival)
  str = if @sign < 0
    sprintf("%0#{@bits}b",2**@bits-@ival)
  else
    sprintf("%0#{@bits}b",@ival)
  end
  return str
end

#to_binaryObject



214
215
216
217
218
219
# File 'lib/fixedpt/fixedpt.rb', line 214

def to_binary
  str = self.to_bin
  values = str.split('')
  values.insert(@bits-@binpt,".")
  values.join('')
end

#to_fObject

convert our limited representation back to float



234
235
236
237
238
239
240
241
242
243
244
245
246
247
# File 'lib/fixedpt/fixedpt.rb', line 234

def to_f
  f = self.to_int.to_f
  puts " Initial f is: #{f}" if $DEBUG
  puts " self.raw is: #{self.raw}" if $DEBUG
  x = self.raw
  (0 .. (@binpt -1)).each {|i|
     puts "... is is: #{i} " if $DEBUG
     delta = x[i]*(1.0/(2**(@binpt-i)))
     puts "... delta is: #{delta} x[#{i}] is #{x[i]}" if $DEBUG
     f += delta
  }
  puts "@sign is #{@sign}" if $DEBUG
  f *@sign
end

#to_fp(wid = @bits, binpt = @binpt) ⇒ Object



250
251
252
# File 'lib/fixedpt/fixedpt.rb', line 250

def to_fp(wid=@bits,binpt=@binpt)
  self
end

#to_iObject



225
226
227
# File 'lib/fixedpt/fixedpt.rb', line 225

def to_i
  to_int
end

#to_intObject



221
222
223
# File 'lib/fixedpt/fixedpt.rb', line 221

def to_int
  (@ival >> @binpt)
end

#to_sObject



229
230
231
# File 'lib/fixedpt/fixedpt.rb', line 229

def to_s
  to_int.to_s 
end

#valueObject

rb_define_method(cFixedPt,“check_sizes”,fp_check_sizes,1);



136
137
138
# File 'ext/fixedpt.c', line 136

def value
  @ival*@sign
end