Class: FixedPt
- Inherits:
-
Object
- Object
- FixedPt
- Defined in:
- lib/fixedpt/fixedpt.rb,
ext/fixedpt.c
Instance Attribute Summary collapse
-
#binpt ⇒ Object
Returns the value of attribute binpt.
-
#bits ⇒ Object
Returns the value of attribute bits.
-
#frac_width ⇒ Object
Returns the value of attribute frac_width.
-
#int_width ⇒ Object
Returns the value of attribute int_width.
-
#ival ⇒ Object
Returns the value of attribute ival.
-
#max_int_value ⇒ Object
readonly
Returns the value of attribute max_int_value.
-
#maxint ⇒ Object
Returns the value of attribute maxint.
-
#minint ⇒ Object
Returns the value of attribute minint.
-
#overflow ⇒ Object
readonly
Returns the value of attribute overflow.
-
#sign ⇒ Object
Returns the value of attribute sign.
Instance Method Summary collapse
- #*(other) ⇒ Object
-
#+(other) ⇒ Object
assume result size is self size.
-
#-(other) ⇒ Object
assume result size is self size.
- #/(other) ⇒ Object
- #<<(num) ⇒ Object
-
#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));.
- #assign(val) ⇒ Object
-
#calc_min_max ⇒ Object
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; }.
- #check_binpt ⇒ Object
-
#check_for_overflow(result) ⇒ Object
rb_define_method(cFixedPt,“multiply”,fp_value,1);.
-
#check_sign(val) ⇒ Object
rb_define_method(cFixedPt,“initialize”,fp_init,3);.
- #coerce(other) ⇒ Object
- #construct_from_fixnum(val, total_bits, binpt) ⇒ Object
- #construct_from_float(val, total_bits, binpt) ⇒ Object
- #from_FixedPt(other) ⇒ Object
- #from_float(val) ⇒ Object
-
#initialize(val, total_bits = nil, binpt = nil, overflow_handler = :saturate) ⇒ FixedPt
constructor
A new instance of FixedPt.
- #ranged_int_part ⇒ Object
- #raw ⇒ Object
- #rawval ⇒ Object
- #saturate(result) ⇒ Object
-
#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.
-
#shift_right(num) ⇒ Object
for conversion purposes, integer portion should.
- #sizes_differ?(other) ⇒ Boolean
- #to_bin ⇒ Object
- #to_binary ⇒ Object
-
#to_f ⇒ Object
convert our limited representation back to float.
- #to_fp(wid = @bits, binpt = @binpt) ⇒ Object
- #to_i ⇒ Object
- #to_int ⇒ Object
- #to_s ⇒ Object
-
#value ⇒ Object
rb_define_method(cFixedPt,“check_sizes”,fp_check_sizes,1);.
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
#binpt ⇒ Object
Returns the value of attribute binpt.
121 122 123 |
# File 'ext/fixedpt.c', line 121 def binpt @binpt end |
#bits ⇒ Object
Returns the value of attribute bits.
106 107 108 |
# File 'ext/fixedpt.c', line 106 def bits @bits end |
#frac_width ⇒ Object
Returns the value of attribute frac_width.
106 107 108 |
# File 'lib/fixedpt/fixedpt.rb', line 106 def frac_width @frac_width end |
#int_width ⇒ Object
Returns the value of attribute int_width.
106 107 108 |
# File 'lib/fixedpt/fixedpt.rb', line 106 def int_width @int_width end |
#ival ⇒ Object
Returns the value of attribute ival.
101 102 103 |
# File 'ext/fixedpt.c', line 101 def ival @ival end |
#max_int_value ⇒ Object (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 |
#maxint ⇒ Object
Returns the value of attribute maxint.
131 132 133 |
# File 'ext/fixedpt.c', line 131 def maxint @maxint end |
#minint ⇒ Object
Returns the value of attribute minint.
106 107 108 |
# File 'lib/fixedpt/fixedpt.rb', line 106 def minint @minint end |
#overflow ⇒ Object (readonly)
Returns the value of attribute overflow.
107 108 109 |
# File 'lib/fixedpt/fixedpt.rb', line 107 def overflow @overflow end |
#sign ⇒ Object
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_max ⇒ Object
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_binpt ⇒ Object
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_part ⇒ Object
304 305 306 |
# File 'lib/fixedpt/fixedpt.rb', line 304 def ranged_int_part @ival = (@ival & 2**@bits-1) end |
#raw ⇒ Object
200 201 202 |
# File 'lib/fixedpt/fixedpt.rb', line 200 def raw @ival end |
#rawval ⇒ Object
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
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_bin ⇒ Object
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_binary ⇒ Object
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_f ⇒ Object
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_i ⇒ Object
225 226 227 |
# File 'lib/fixedpt/fixedpt.rb', line 225 def to_i to_int end |
#to_int ⇒ Object
221 222 223 |
# File 'lib/fixedpt/fixedpt.rb', line 221 def to_int (@ival >> @binpt) end |
#to_s ⇒ Object
229 230 231 |
# File 'lib/fixedpt/fixedpt.rb', line 229 def to_s to_int.to_s end |
#value ⇒ Object
rb_define_method(cFixedPt,“check_sizes”,fp_check_sizes,1);
136 137 138 |
# File 'ext/fixedpt.c', line 136 def value @ival*@sign end |