FixedPt 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,140 @@
1
+
2
+ SHELL = /bin/sh
3
+
4
+ #### Start of system configuration section. ####
5
+
6
+ srcdir = .
7
+ topdir = /usr/lib/ruby/1.8/i386-linux
8
+ hdrdir = $(topdir)
9
+ VPATH = $(srcdir):$(topdir):$(hdrdir)
10
+ prefix = $(DESTDIR)/usr
11
+ exec_prefix = $(prefix)
12
+ sitedir = $(DESTDIR)/usr/local/lib/site_ruby
13
+ rubylibdir = $(libdir)/ruby/$(ruby_version)
14
+ archdir = $(rubylibdir)/$(arch)
15
+ sbindir = $(exec_prefix)/sbin
16
+ datadir = $(prefix)/share
17
+ includedir = $(prefix)/include
18
+ infodir = $(prefix)/info
19
+ sysconfdir = $(DESTDIR)/etc
20
+ mandir = $(datadir)/man
21
+ libdir = $(exec_prefix)/lib
22
+ sharedstatedir = $(prefix)/com
23
+ oldincludedir = $(DESTDIR)/usr/include
24
+ sitearchdir = $(sitelibdir)/$(sitearch)
25
+ bindir = $(exec_prefix)/bin
26
+ localstatedir = $(DESTDIR)/var
27
+ sitelibdir = $(sitedir)/$(ruby_version)
28
+ libexecdir = $(exec_prefix)/libexec
29
+
30
+ CC = gcc
31
+ LIBRUBY = $(LIBRUBY_SO)
32
+ LIBRUBY_A = lib$(RUBY_SO_NAME)-static.a
33
+ LIBRUBYARG_SHARED = -l$(RUBY_SO_NAME)
34
+ LIBRUBYARG_STATIC = -l$(RUBY_SO_NAME)-static
35
+
36
+ CFLAGS = -fPIC -Wall -g -O2 -fPIC
37
+ CPPFLAGS = -I. -I$(topdir) -I$(hdrdir) -I$(srcdir)
38
+ CXXFLAGS = $(CFLAGS)
39
+ DLDFLAGS =
40
+ LDSHARED = $(CC) -shared
41
+ AR = ar
42
+ EXEEXT =
43
+
44
+ RUBY_INSTALL_NAME = ruby1.8
45
+ RUBY_SO_NAME = ruby1.8
46
+ arch = i386-linux
47
+ sitearch = i386-linux
48
+ ruby_version = 1.8
49
+ ruby = /usr/bin/ruby1.8
50
+ RUBY = $(ruby)
51
+ RM = rm -f
52
+ MAKEDIRS = mkdir -p
53
+ INSTALL = install -p
54
+ INSTALL_PROG = $(INSTALL) -m 0755
55
+ INSTALL_DATA = $(INSTALL) -m 0644
56
+ COPY = cp
57
+
58
+ #### End of system configuration section. ####
59
+
60
+ preload =
61
+
62
+ libpath = $(libdir)
63
+ LIBPATH = -L"$(libdir)"
64
+ DEFFILE =
65
+
66
+ CLEANFILES =
67
+ DISTCLEANFILES =
68
+
69
+ extout =
70
+ extout_prefix =
71
+ target_prefix =
72
+ LOCAL_LIBS =
73
+ LIBS = $(LIBRUBYARG_SHARED) -lpthread -ldl -lcrypt -lm -lc
74
+ SRCS = fixedpt.c
75
+ OBJS = fixedpt.o
76
+ TARGET = fixedpt
77
+ DLLIB = $(TARGET).so
78
+ STATIC_LIB =
79
+
80
+ RUBYCOMMONDIR = $(sitedir)$(target_prefix)
81
+ RUBYLIBDIR = $(sitelibdir)$(target_prefix)
82
+ RUBYARCHDIR = $(sitearchdir)$(target_prefix)
83
+
84
+ TARGET_SO = $(DLLIB)
85
+ CLEANLIBS = $(TARGET).so $(TARGET).il? $(TARGET).tds $(TARGET).map
86
+ CLEANOBJS = *.o *.a *.s[ol] *.pdb *.exp *.bak
87
+
88
+ all: $(DLLIB)
89
+ static: $(STATIC_LIB)
90
+
91
+ clean:
92
+ @-$(RM) $(CLEANLIBS) $(CLEANOBJS) $(CLEANFILES)
93
+
94
+ distclean: clean
95
+ @-$(RM) Makefile extconf.h conftest.* mkmf.log
96
+ @-$(RM) core ruby$(EXEEXT) *~ $(DISTCLEANFILES)
97
+
98
+ realclean: distclean
99
+ install: install-so install-rb
100
+
101
+ install-so: $(RUBYARCHDIR)
102
+ install-so: $(RUBYARCHDIR)/$(DLLIB)
103
+ $(RUBYARCHDIR)/$(DLLIB): $(DLLIB)
104
+ $(INSTALL_PROG) $(DLLIB) $(RUBYARCHDIR)
105
+ install-rb: pre-install-rb install-rb-default
106
+ install-rb-default: pre-install-rb-default
107
+ pre-install-rb pre-install-rb-default: $(RUBYLIBDIR)
108
+ $(RUBYARCHDIR):
109
+ $(MAKEDIRS) $@
110
+ $(RUBYLIBDIR):
111
+ $(MAKEDIRS) $@
112
+
113
+ site-install: site-install-so site-install-rb
114
+ site-install-so: install-so
115
+ site-install-rb: install-rb
116
+
117
+ .SUFFIXES: .c .m .cc .cxx .cpp .C .o
118
+
119
+ .cc.o:
120
+ $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c $<
121
+
122
+ .cxx.o:
123
+ $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c $<
124
+
125
+ .cpp.o:
126
+ $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c $<
127
+
128
+ .C.o:
129
+ $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c $<
130
+
131
+ .c.o:
132
+ $(CC) $(CFLAGS) $(CPPFLAGS) -c $<
133
+
134
+ $(DLLIB): $(OBJS)
135
+ @-$(RM) $@
136
+ $(LDSHARED) $(DLDFLAGS) $(LIBPATH) -o $@ $(OBJS) $(LOCAL_LIBS) $(LIBS)
137
+
138
+
139
+
140
+ $(OBJS): ruby.h defines.h
@@ -0,0 +1,2 @@
1
+ require 'mkmf'
2
+ create_makefile("fixedpt")
@@ -0,0 +1,351 @@
1
+ #include <string.h>
2
+ #include <stdio.h>
3
+ #include <math.h>
4
+ #include "ruby.h"
5
+ static int id_rawval;
6
+ static int id_ival;
7
+ static int id_bits;
8
+ static int id_binpt;
9
+ static int id_sign;
10
+ static int id_maxint;
11
+ //static int sign;
12
+ static VALUE minus_one;
13
+ static VALUE positive_one;
14
+
15
+ //#define max(A,B) ( (A) > (B) ? (A):(B))
16
+ //#define min(A,B) ( (A) < (B) ? (A):(B))
17
+
18
+ int max(int a, int b)
19
+ {
20
+ return ( a > b ? a : b );
21
+ }
22
+
23
+ int min(int a, int b)
24
+ {
25
+ return ( a < b ? a : b );
26
+ }
27
+
28
+ static VALUE fp_check_sign(VALUE self, VALUE val)
29
+ {
30
+ double i = NUM2DBL(val);
31
+ //printf("i is: %f\n",i);
32
+
33
+ if(i < 0.0) {
34
+ // retval = -1;
35
+ rb_iv_set(self,"@sign",minus_one);
36
+ }else {
37
+ // retval = 1;
38
+ rb_iv_set(self,"@sign",positive_one);
39
+ }
40
+ //return INT2FIX(retval);
41
+ return self;
42
+ }
43
+
44
+ static VALUE fix_abs(VALUE fix)
45
+ {
46
+ long i = FIX2LONG(fix);
47
+
48
+ if (i < 0) i = -i;
49
+
50
+ return LONG2NUM(i);
51
+ }
52
+
53
+
54
+ static VALUE rfp_init(VALUE self, VALUE rawval, VALUE total_bits, VALUE binpt)
55
+ {
56
+ VALUE sign;
57
+ rb_iv_set(self,"@rawval",fix_abs(rawval));
58
+ rb_iv_set(self,"@bits",total_bits);
59
+ rb_iv_set(self,"@binpt",binpt);
60
+ if( FIX2INT(rawval) < 0){
61
+ sign = INT2FIX(-1);
62
+ } else {
63
+ sign = INT2FIX(1);
64
+ }
65
+ rb_iv_set(self,"@sign",sign);
66
+ return self;
67
+ }
68
+
69
+ static VALUE rfp_rawval(VALUE self)
70
+ {
71
+ return rb_iv_get(self,"@rawval");
72
+ }
73
+
74
+ static VALUE rfp_bits(VALUE self)
75
+ {
76
+ return rb_iv_get(self,"@bits");
77
+ }
78
+
79
+ static VALUE rfp_binpt(VALUE self)
80
+ {
81
+ return rb_iv_get(self,"@binpt");
82
+ }
83
+
84
+
85
+ static VALUE rfp_sign(VALUE self)
86
+ {
87
+ return rb_iv_get(self,"@sign");
88
+ }
89
+ //FixedPt methods
90
+
91
+ static VALUE fp_set_overflow(VALUE self, VALUE boolval)
92
+ {
93
+ rb_iv_set(self,"@overflow",boolval);
94
+ return self;
95
+ }
96
+
97
+ static VALUE fp_rawval(VALUE self)
98
+ {
99
+ return rb_iv_get(self,"@ival");
100
+ }
101
+ static VALUE fp_ival(VALUE self)
102
+ {
103
+ return rb_iv_get(self,"@ival");
104
+ }
105
+
106
+ static VALUE fp_bits(VALUE self)
107
+ {
108
+ return rb_iv_get(self,"@bits");
109
+ }
110
+
111
+ static VALUE fp_int_width(VALUE self)
112
+ {
113
+ return rb_iv_get(self,"@int_width");
114
+ }
115
+
116
+ static VALUE fp_frac_width(VALUE self)
117
+ {
118
+ return rb_iv_get(self,"@frac_width");
119
+ }
120
+
121
+ static VALUE fp_binpt(VALUE self)
122
+ {
123
+ return rb_iv_get(self,"@binpt");
124
+ }
125
+
126
+ static VALUE fp_sign(VALUE self)
127
+ {
128
+ return rb_iv_get(self,"@sign");
129
+ }
130
+
131
+ static VALUE fp_maxint(VALUE self)
132
+ {
133
+ return rb_iv_get(self,"@maxint");
134
+ }
135
+
136
+ static VALUE fp_value(VALUE self)
137
+ {
138
+ //int sign = FIX2INT(fp_sign(self));
139
+ long sign = FIX2LONG(fp_sign(self));
140
+ //int ival = FIX2INT(fp_ival(self));
141
+
142
+ long ival = FIX2LONG(fp_ival(self));
143
+ //return (INT2FIX(ival * sign));
144
+ return (LONG2FIX(ival * sign));
145
+ }
146
+
147
+ static VALUE fp_check_for_overflow(VALUE self, VALUE result)
148
+ {
149
+
150
+ long val = FIX2LONG(result);
151
+ int binpt = FIX2INT(fp_binpt(self));
152
+ int bits = FIX2INT(fp_bits(self));
153
+ long maxint= FIX2LONG(fp_maxint(self));
154
+ long tmpval;
155
+ if(binpt == bits) return result;
156
+ if((tmpval = val >> binpt) > maxint ){
157
+ //printf("OVERFLOW\n");
158
+ //result = LONG2FIX(pow(2,(bits-1)));
159
+
160
+ result = rb_funcall(self,rb_intern("send"),2,rb_iv_get(self,"@overflow_handler"),result);
161
+ if(tmpval > FIX2LONG(rb_iv_get(self,"@max_int_value")))
162
+ rb_iv_set(self,"@max_int_value",LONG2NUM(tmpval));
163
+ }
164
+ return result;
165
+ }
166
+
167
+ static VALUE fp_saturate(VALUE self, VALUE result)
168
+ {
169
+ return ( LONG2FIX( pow(2,(FIX2INT(fp_bits(self))))-1 ) );
170
+ }
171
+
172
+ /*
173
+ static VALUE fp_check_sizes(VALUE self, VALUE other)
174
+ {
175
+ int this_binpt = FIX2INT(fp_binpt(self));
176
+ int other_binpt = FIX2INT(fp_binpt(other));
177
+ if(this_binpt != other_binpt ){
178
+ rb_raise(rb_eRuntimeError, "binary points don't match: ( %d != %d)\n",this_binpt, other_binpt);
179
+ }
180
+ return self;
181
+ }
182
+ */
183
+
184
+ static VALUE fp_calc_min_max(VALUE self)
185
+ {
186
+ int bits = FIX2INT(fp_bits(self));
187
+ int binpt = FIX2INT(fp_binpt(self));
188
+ int intbits = bits - binpt;
189
+ long maxint = pow(2,intbits)-1;
190
+ rb_iv_set( self,"@maxint", LONG2FIX(maxint) ) ;
191
+ rb_iv_set( self,"@minint", LONG2FIX(-1*maxint) ) ;
192
+ return self;
193
+ }
194
+
195
+ /*
196
+ static VALUE fp_sizes_differ(VALUE self, VALUE other)
197
+ {
198
+ VALUE ret_bool = T_FALSE;
199
+ int selfbits = FIX2INT(fp_bits(self));
200
+ int otherbits = FIX2INT(fp_bits(other));
201
+ int selfbinpt = FIX2INT(fp_binpt(self));
202
+ int otherbinpt = FIX2INT(fp_binpt(other));
203
+
204
+ //if( (FIX2INT(fp_bits(self)) != FIX2INT(fp_bits(other))) || (FIX2INT(fp_binpt(self)) != FIX2INT(fp_binpt(other))) )
205
+ if((selfbits != otherbits) || (selfbinpt != otherbinpt))
206
+ {
207
+
208
+ printf(" self size is: %d other size is: %d\n", selfbits,otherbits);
209
+ printf(" self binpt is: %d other binpt is: %d\n", selfbinpt,otherbinpt);
210
+ ret_bool = T_TRUE;
211
+ }
212
+ return ret_bool;
213
+ }
214
+ */
215
+
216
+ static VALUE fp_adjust_sizes(VALUE self, VALUE other)
217
+ {
218
+ //make array to return:
219
+ VALUE ret_array = rb_ary_new();
220
+ int self_width = FIX2INT(fp_int_width(self));
221
+ int other_width = FIX2INT(fp_int_width(other));
222
+ int self_frac_width = FIX2INT(fp_frac_width(self));
223
+ int other_frac_width = FIX2INT(fp_frac_width(other));
224
+ rb_ary_push(ret_array, INT2FIX(max(self_width,other_width)));
225
+ rb_ary_push(ret_array, INT2FIX(max(self_frac_width,other_frac_width)));
226
+
227
+ return ret_array;
228
+ }
229
+
230
+ /*
231
+ static VALUE fp_multiply(VALUE self, VALUE other)
232
+ {
233
+ VALUE result;
234
+
235
+ fp_check_sizes(self,other);
236
+ result = (FIX2INT(fp_value(self)) * FIX2INT(fp_value(other)) >> FIX2INT(fp_binpt(self)) );
237
+ result = fp_check_for_overflow(self,LONG2FIX(result));
238
+ return result;
239
+ }
240
+ */
241
+
242
+ /*
243
+ static VALUE fp_init(VALUE self, VALUE val, VALUE total_bits, VALUE binpt)
244
+ {
245
+ char* name = rb_class2name(rb_obj_class(val));
246
+ switch (TYPE(val)) {
247
+ case T_FIXNUM:
248
+ rb_funcall(self,rb_intern("construct_from_fixnum"),3,val,total_bits,binpt);
249
+ //printf("T_FIXNUM:\n");
250
+ //rb_iv_set(self,"@rawval",val);
251
+ //rb_iv_set(self,"@bits",total_bits);
252
+ //rb_iv_set(self,"@binpt",binpt);
253
+ //rb_iv_set(self,"@sign", INT2FIX(check_sign(val)));
254
+ break;
255
+ case T_FLOAT:
256
+ //printf("T_FLOAT:\n");
257
+ rb_funcall(self,rb_intern("construct_from_float"),3,val,total_bits,binpt);
258
+ break;
259
+ default:
260
+ //printf("*FixedPT:\n");
261
+ if( ! strcmp(name,"RawFixedPt") ){
262
+ //printf("RawFixedPT:\n");
263
+ //rb_iv_set(self,"@ival",rb_funcall(val,id_rawval,0) );
264
+ //rb_iv_set(self,"@bits",rb_funcall(val,id_bits,0) );
265
+ //rb_iv_set(self,"@binpt",rb_funcall(val,id_binpt,0) );
266
+ //rb_iv_set(self,"@sign",rb_funcall(val,id_sign,0) );
267
+ //this should be a bit faster:
268
+ rb_iv_set(self,"@ival",rfp_rawval(val));
269
+ rb_iv_set(self,"@bits",rfp_bits(val));
270
+ rb_iv_set(self,"@binpt",rfp_binpt(val));
271
+ rb_iv_set(self,"@sign",rfp_sign(val));
272
+
273
+ }else if( ! strcmp(name,"FixedPt") ){
274
+ //printf("FixedPT:\n");
275
+ rb_iv_set(self,"@ival",fp_ival(val));
276
+ rb_iv_set(self,"@bits",fp_bits(val));
277
+ rb_iv_set(self,"@binpt",fp_binpt(val));
278
+ rb_iv_set(self,"@sign",fp_sign(val));
279
+ }else {
280
+ rb_raise(rb_eTypeError, "not a valid value");
281
+ }
282
+ break;
283
+ }
284
+ int diff= FIX2INT(rb_iv_get(self,"@bits"))-FIX2INT(rb_iv_get(self,"@binpt"));
285
+ rb_iv_set(self,"@maxint", LONG2FIX((pow(2,diff ))-1 ) ) ;
286
+ return self;
287
+ }
288
+ */
289
+ /*
290
+ static VALUE fp_init(VALUE self, VALUE val, VALUE total_bits, VALUE binpt)
291
+ {
292
+ //rb_funcall(self,rb_intern("from_fixnum"),3,val,total_bits,binpt);
293
+ char* name = rb_class2name(rb_obj_class(val));
294
+ int type = TYPE(val);
295
+ printf("type: %d\n",type);
296
+ printf("class name: %s\n",name);
297
+ printf("T_FIXNUM:\n");
298
+ rb_iv_set(self,"@rawval",val);
299
+ rb_iv_set(self,"@bits",total_bits);
300
+ rb_iv_set(self,"@binpt",binpt);
301
+ rb_iv_set(self,"@sign", INT2FIX(check_sign(val)));
302
+ return self;
303
+ }
304
+ */
305
+
306
+ VALUE cRawFixedPt;
307
+ VALUE cFixedPt;
308
+
309
+ void Init_fixedpt() {
310
+ //class RawFixedPt
311
+ cRawFixedPt = rb_define_class("RawFixedPt", rb_cObject);
312
+ rb_define_method(cRawFixedPt,"initialize", rfp_init, 3);
313
+ rb_define_method(cRawFixedPt,"rawval",rfp_rawval,0);
314
+ rb_define_method(cRawFixedPt,"bits",rfp_bits,0);
315
+ rb_define_method(cRawFixedPt,"binpt",rfp_binpt,0);
316
+ rb_define_method(cRawFixedPt,"sign",rfp_sign,0);
317
+
318
+ //class FixedPt
319
+ cFixedPt = rb_define_class("FixedPt",rb_cObject);
320
+ //rb_define_method(cFixedPt,"initialize",fp_init,3);
321
+ rb_define_method(cFixedPt,"check_sign",fp_check_sign,1);
322
+ rb_define_method(cFixedPt,"rawval",fp_rawval,0);
323
+ rb_define_method(cFixedPt,"ival",fp_ival,0);
324
+ rb_define_method(cFixedPt,"bits",fp_bits,0);
325
+ rb_define_method(cFixedPt,"binpt",fp_binpt,0);
326
+ rb_define_method(cFixedPt,"sign",fp_sign,0);
327
+ rb_define_method(cFixedPt,"maxint",fp_maxint,0);
328
+ //rb_define_method(cFixedPt,"check_sizes",fp_check_sizes,1);
329
+ rb_define_method(cFixedPt,"value",fp_value,0);
330
+ //rb_define_method(cFixedPt,"multiply",fp_value,1);
331
+ rb_define_method(cFixedPt,"check_for_overflow",fp_check_for_overflow,1);
332
+ rb_define_method(cFixedPt,"calc_min_max",fp_calc_min_max,0);
333
+ //rb_define_method(cFixedPt,"sizes_differ?",fp_sizes_differ,1);
334
+ rb_define_method(cFixedPt,"adjust_sizes",fp_adjust_sizes,1);
335
+ rb_define_method(cFixedPt,"saturate",fp_saturate,1);
336
+ //rb_define_method(cFixedPt," fp_set_overflow(VALUE self, VALUE boolval)
337
+ //
338
+
339
+ //create symbols here:
340
+ id_rawval = rb_intern("rawval");
341
+ id_ival = rb_intern("ival");
342
+ id_bits = rb_intern("bits");
343
+ id_binpt = rb_intern("binpt");
344
+ id_sign = rb_intern("sign");
345
+ id_maxint = rb_intern("maxint");
346
+
347
+ minus_one = INT2NUM(-1);
348
+ positive_one = INT2NUM(1);
349
+ }
350
+
351
+
Binary file
Binary file
@@ -0,0 +1,411 @@
1
+ class Numeric
2
+ def to_fp(wid,binpt)
3
+ FixedPt.new(self,wid,binpt)
4
+ end
5
+ end
6
+
7
+ module FPHelpers
8
+
9
+ def max(x,y)
10
+ return x > y ? x : y
11
+ end
12
+
13
+ def min(x,y)
14
+ return x < y ? x : y
15
+ end
16
+
17
+ end
18
+
19
+ include FPHelpers
20
+ class OverflowException < RangeError
21
+ end
22
+
23
+ begin
24
+ #require '/home/phil/development/fixedpt/ext/fixedpt.so'
25
+ require 'fixedpt.so'
26
+ rescue LoadError
27
+ puts "Couldn't find ext/fixedpt.so: thing's will run slow, but it'll work"
28
+
29
+ class RawFixedPt #used only to make FixedPt constructor easier (see case statment below)
30
+ attr_reader :rawval, :bits, :binpt, :sign
31
+ def initialize(rawval,total_bits,binpt)#,sign)
32
+ @rawval = rawval
33
+ @bits = total_bits
34
+ @binpt = binpt
35
+ #@sign = sign
36
+ @sign = if rawval < 0
37
+ -1
38
+ else
39
+ 1
40
+ end
41
+ @rawval = rawval.abs
42
+
43
+ puts "@rawval = #{rawval}, @bits = #{@bits}, @binpt = #{binpt}, @sign = #{@sign}" if $DEBUG
44
+ end
45
+
46
+ end
47
+
48
+ class FixedPt
49
+
50
+ def calc_min_max
51
+ #TODO: What about simulating 2's complement?
52
+ #for 2's comp: positive @maxint = (2**(@bits-@binpt-1)-1)
53
+ # negative @minint = -(2**(@bits-@binpt)-1)
54
+ @maxint = (2**(@bits-@binpt) - 1)
55
+ @minint = -(2**(@bits-@binpt-1) )
56
+ end
57
+
58
+ def check_sign(val)
59
+ puts "check_sign(#{val})" if $DEBUG
60
+ if val < 0
61
+ @sign = -1
62
+ else
63
+ @sign = 1
64
+ end
65
+ end
66
+
67
+ def size
68
+ @bits
69
+ end
70
+
71
+ def adjust_sizes(other)
72
+ return [ max(self.int_width, other.int_width), max(self.frac_width, other.frac_width)]
73
+ end
74
+
75
+ def check_for_overflow(result)
76
+ @overflow = false
77
+ return result if @binpt == @bits
78
+ #shift result right binpt times
79
+ puts "result is: #{result}" if $DEBUG
80
+ puts "if((#{result >> @binpt} ) > #{@maxint} )" if $DEBUG
81
+ if ((tmpval = result >> @binpt ) > @maxint )
82
+ @overflow = true
83
+ if(tmpval > @max_int_value)
84
+ @max_int_value = tmpval
85
+ end
86
+ result = self.send @overflow_handler, result
87
+ end
88
+ result
89
+ end
90
+
91
+ def saturate(result)
92
+ #NOTE: result below is the maximal result for this number of bits
93
+ result = (2**@bits - 1)
94
+ end
95
+
96
+ def truncate(result)
97
+ result & (2**@bits-1)
98
+ end
99
+
100
+ end #FixedPt
101
+ #end of rescue
102
+ else
103
+ end
104
+
105
+ class FixedPt
106
+ attr_accessor :ival, :bits, :maxint, :minint, :binpt, :sign, :int_width, :frac_width
107
+ attr_reader :max_int_value, :overflow
108
+ def initialize(val,total_bits=nil,binpt=nil,overflow_handler=:saturate)
109
+ #TODO: what if total_bits and binpt are nil?
110
+ #raise "binpt should be less than total_bits!" if binpt > total_bits
111
+ @overflow = false
112
+ @overflow_handler = overflow_handler
113
+ @max_int_value = 0
114
+ case val
115
+ when Fixnum
116
+ construct_from_fixnum(val,total_bits,binpt)
117
+ when Float
118
+ construct_from_float(val,total_bits,binpt)
119
+ when FixedPt #essentially a copy constructor
120
+ #was:@ival = val.ival
121
+ @ival = check_for_overflow(val.ival)
122
+ @bits = total_bits || val.bits #so you can override total # of bits
123
+ @binpt= val.binpt #but binpt should remain at same position(for now)
124
+ @sign = val.sign
125
+ @frac_width = @binpt
126
+ @int_width = @bits - @binpt
127
+
128
+ when RawFixedPt
129
+ #construct a FixedPt with a RawFixedPt
130
+ @ival = val.rawval
131
+ @bits = val.bits
132
+ @binpt= val.binpt
133
+ @sign = val.sign
134
+ @frac_width = @binpt
135
+ @int_width = @bits - @binpt
136
+ else
137
+ end
138
+ end
139
+
140
+ def check_binpt
141
+ raise "binpt should be less than total_bits!" if @binpt >= @total_bits
142
+ end
143
+ def value
144
+ @ival*@sign
145
+ end
146
+
147
+ def construct_from_fixnum(val,total_bits,binpt)
148
+ @bits = total_bits
149
+ @binpt= binpt
150
+ calc_min_max
151
+ check_sign(val)
152
+ #was:@ival = (val.abs << binpt)
153
+ @ival = check_for_overflow(val.abs << binpt)
154
+ @frac_width = @binpt
155
+ @int_width = @bits - @binpt
156
+ puts "@ival is: #{@ival}" if $DEBUG
157
+ end
158
+
159
+ def construct_from_float(val,total_bits,binpt)
160
+ @bits = total_bits
161
+ @binpt= binpt
162
+ @frac_width = binpt
163
+ @int_width = total_bits - binpt
164
+ calc_min_max
165
+ check_sign(val)
166
+ #was:@ival = (val*(2**@binpt)).round.abs #NOTE:do we want to round or not?
167
+ #then:@ival = check_for_overflow(val*(2**@binpt)).round.abs #NOTE:do we want to round or not?
168
+ #now:
169
+ from_float(val)
170
+ end
171
+
172
+ def from_float(val)
173
+ #was: (val*(2**@binpt)).round.abs #NOTE:do we want to round or not?
174
+ @ival = check_for_overflow((val*(2**@binpt)).round.abs) #NOTE:do we want to round or not?
175
+ end
176
+
177
+ def assign(val)
178
+ case val
179
+ when Float
180
+ #was:@ival = from_float(val)
181
+ from_float(val)
182
+ check_sign(val)
183
+ when Fixnum
184
+ @ival = (val << @binpt )
185
+ check_sign(val)
186
+ when FixedPt
187
+ from_FixedPt(val)
188
+ else
189
+ end
190
+ end
191
+
192
+ def from_FixedPt(other)
193
+ if sizes_differ?(other)
194
+ other = FixedPt.new(other.to_f,@bits,@binpt)
195
+ end
196
+ @ival = check_for_overflow(other.raw)
197
+ @sign = other.sign
198
+ end
199
+
200
+ def raw
201
+ @ival
202
+ end
203
+
204
+ def to_bin
205
+ #str = sprintf("%0#{@bits}b",@ival)
206
+ str = if @sign < 0
207
+ sprintf("%0#{@bits}b",2**@bits-@ival)
208
+ else
209
+ sprintf("%0#{@bits}b",@ival)
210
+ end
211
+ return str
212
+ end
213
+
214
+ def to_binary
215
+ str = self.to_bin
216
+ values = str.split('')
217
+ values.insert(@bits-@binpt,".")
218
+ values.join('')
219
+ end
220
+
221
+ def to_int
222
+ (@ival >> @binpt)
223
+ end
224
+
225
+ def to_i
226
+ to_int
227
+ end
228
+
229
+ def to_s
230
+ to_int.to_s
231
+ end
232
+
233
+ #convert our limited representation back to float
234
+ def to_f
235
+ f = self.to_int.to_f
236
+ puts " Initial f is: #{f}" if $DEBUG
237
+ puts " self.raw is: #{self.raw}" if $DEBUG
238
+ x = self.raw
239
+ (0 .. (@binpt -1)).each {|i|
240
+ puts "... is is: #{i} " if $DEBUG
241
+ delta = x[i]*(1.0/(2**(@binpt-i)))
242
+ puts "... delta is: #{delta} x[#{i}] is #{x[i]}" if $DEBUG
243
+ f += delta
244
+ }
245
+ puts "@sign is #{@sign}" if $DEBUG
246
+ f *@sign
247
+ end
248
+
249
+
250
+ def to_fp(wid=@bits,binpt=@binpt)
251
+ self
252
+ end
253
+
254
+
255
+ def sizes_differ? (other)
256
+ return ( self.binpt != other.binpt || self.bits != other.bits )
257
+ end
258
+
259
+ def /(other)
260
+ #pass the buck: implement in terms of multiplication
261
+ result = ((self) * (FixedPt.new((1.0/other.to_f),@bits,@binpt)))
262
+ return result
263
+ end
264
+
265
+ def *(other)
266
+ if Fixnum === other || Float === other
267
+ other = FixedPt.new(other,@bits,@binpt)
268
+ end
269
+ if sizes_differ?(other)
270
+
271
+ int_width,frac_width = adjust_sizes(other)
272
+ a = FixedPt.new(self.to_f,(int_width+frac_width),frac_width)
273
+ b = FixedPt.new(other.to_f,(int_width+frac_width),frac_width)
274
+ return (a * b)
275
+ else
276
+ result = ((self.value) * (other.value))
277
+ return FixedPt.new(RawFixedPt.new(result,(2*@bits),2*@binpt),nil,nil)
278
+ end
279
+ #end
280
+ end
281
+
282
+ #perhaps this could be called 'increase_resolution'
283
+ #effect: it preserves the integer portion of the number and
284
+ #increases the number of positions to the right of the binary point
285
+ #this increasing resolution
286
+ def shift_left(num) #for conversion purposes
287
+ #maintain same integer range, add fractional bits
288
+ result = FixedPt.new(RawFixedPt.new(((self.raw) << num),(@bits+num),(@binpt+num)),nil,nil)
289
+ end
290
+
291
+ def shift_right(num) #for conversion purposes, integer portion should
292
+ #be preserved
293
+ if num > @binpt
294
+ raise "can't shift right #{num} positions: only #{@binpt} positions"
295
+ end
296
+ return FixedPt.new(RawFixedPt.new((self.raw>>num),(@bits-num),(@binpt-num)),nil,nil)
297
+ end
298
+
299
+
300
+ def <<(num)
301
+ result = FixedPt.new(RawFixedPt.new(((self.raw)<<num),@bits,@binpt),@bits,@binpt)
302
+ end
303
+
304
+ def ranged_int_part
305
+ @ival = (@ival & 2**@bits-1)
306
+ end
307
+
308
+ def +(other) #assume result size is self size
309
+ if Fixnum === other || Float === other
310
+ other = FixedPt.new(other,@bits,@binpt)
311
+ end
312
+ if sizes_differ?(other)
313
+ int_width,frac_width = adjust_sizes(other)
314
+ a = FixedPt.new(self.to_f,(int_width+frac_width),frac_width)
315
+ b = FixedPt.new(other.to_f,(int_width+frac_width),frac_width)
316
+ return (a + b)
317
+ else
318
+ result = (self.value ) + (other.value )
319
+ return FixedPt.new(RawFixedPt.new(result, @bits, @binpt),nil,nil )#,sign))
320
+ end
321
+ end
322
+
323
+ def coerce(other)
324
+ if Integer === other
325
+ [other, self.value]
326
+ else
327
+ [other.to_f,self.to_f]
328
+ end
329
+ end
330
+
331
+ def -(other) #assume result size is self size
332
+ if Fixnum === other || Float === other
333
+ other = FixedPt.new(other,@bits,@binpt)
334
+ end
335
+ if sizes_differ?(other)
336
+ int_width,frac_width = adjust_sizes(other)
337
+ a = FixedPt.new(self.to_f,(int_width+frac_width),frac_width)
338
+ b = FixedPt.new(other.to_f,(int_width+frac_width),frac_width)
339
+ return (a - b)
340
+ else
341
+ result = (self.value ) - (other.value )
342
+ return FixedPt.new(RawFixedPt.new(result, @bits, @binpt),nil,nil )#,sign))
343
+ end
344
+ end
345
+
346
+ private
347
+
348
+ end
349
+
350
+
351
+
352
+
353
+ if $0 == __FILE__
354
+
355
+ a = FixedPt.new(4.25,6,2)
356
+ puts a.to_binary
357
+ b = FixedPt.new(2,2,0)
358
+ puts b.to_binary
359
+ c = a*b
360
+ puts c.to_binary
361
+ start = Time.now
362
+ 10000.times do |i|
363
+ a = FixedPt.new(9,4,1)
364
+ end
365
+ puts Time.now - start
366
+ exit
367
+ x = FixedPt.new(8,6,1)
368
+ puts "x.to_binary: #{x.to_binary}"
369
+ y = FixedPt.new(2,4,2)
370
+ puts "y.to_binary: #{y.to_binary}"
371
+ puts "sizes differ" if x.sizes_differ? y
372
+ z = x + y
373
+ puts z.to_binary
374
+ z1 = z - y
375
+ puts z1.to_binary
376
+
377
+ z3 = x * y
378
+ puts z3.to_binary
379
+
380
+ exit
381
+ FRAC_PART = 3
382
+ INT_PART = 3
383
+ WIDTH = FRAC_PART + INT_PART
384
+ fixed = FixedPt.new(3,4,2)
385
+ puts "fixed is: #{fixed}"
386
+ fixedfloat = FixedPt.new(-(1/3.0),WIDTH,FRAC_PART)
387
+ puts "fixedfloat is: #{fixedfloat}"
388
+ puts "fixedfloat.raw is: 0x#{sprintf("%x",fixedfloat.raw)}"
389
+
390
+ puts "binary: "+fixedfloat.to_binary+ " = #{fixedfloat.to_f}"
391
+
392
+
393
+ multiplicand = FixedPt.new(6,WIDTH,FRAC_PART)
394
+ results = fixedfloat * multiplicand
395
+ puts "binary: "+results.to_binary+ " = #{results.to_f}"
396
+
397
+ foo = FixedPt.new(-(9/16.0),4,4)
398
+ puts "#{foo.to_binary} #{foo.to_f}"
399
+ foo = FixedPt.new(-(1.0),4,1)
400
+ puts "#{foo.to_binary} #{foo.to_f}"
401
+ foo = FixedPt.new(-(2.0),4,1)
402
+ puts "#{foo.to_binary} #{foo.to_f}"
403
+ foo = FixedPt.new(-(4.0),4,1)
404
+ puts "#{foo.to_binary} #{foo.to_f}"
405
+ foo = FixedPt.new(-(5.0),4,1)
406
+ puts "#{foo.to_binary} #{foo.to_f} minint:#{foo.minint} maxint:#{foo.maxint}"
407
+
408
+ foo = FixedPt.new((1/3.0),11,3)
409
+ puts "#{foo.to_binary} #{foo.to_f}"
410
+
411
+ end
@@ -0,0 +1,262 @@
1
+ # Code Generated by ZenTest v. 2.3.0
2
+ #Couldn't find ext/fixedpt.so: thing's will run slow, but it'll work
3
+ # classname: asrt / meth = ratio%
4
+ # FixedPt: 0 / 33 = 0.00%
5
+ # Numeric: 0 / 1 = 0.00%
6
+ # RawFixedPt: 0 / 1 = 0.00%
7
+ # FPHelpers: 0 / 2 = 0.00%
8
+
9
+ require 'test/unit' unless defined? $ZENTEST and $ZENTEST
10
+ require 'fixedpt'
11
+
12
+ class TestFixedPt < Test::Unit::TestCase
13
+ def setup
14
+
15
+ end
16
+
17
+ def test_subtract
18
+ raise NotImplementedError, 'Need to write test_subtract'
19
+ end
20
+ def test_add
21
+ raise NotImplementedError, 'Need to write test_add'
22
+ end
23
+ def test_multiply
24
+ #raise NotImplementedError, 'Need to write test_multiply'
25
+ a = FixedPt.new(4.25,5,2)
26
+ b = FixedPt.new(2,2,0)
27
+ c = a*b
28
+ assert_match("001000.1000",c.to_binary)
29
+ assert_equal(8.5,c.to_f)
30
+ assert_equal(6,c.int_width)
31
+ assert_equal(4,c.frac_width)
32
+ d = FixedPt.new(-1,2,0)
33
+ e = b*d
34
+ assert_equal(-2,e.value)
35
+ end
36
+
37
+ def test_divide
38
+ raise NotImplementedError, 'Need to write test_divide'
39
+ end
40
+
41
+ def test_adjust_sizes
42
+ raise NotImplementedError, 'Need to write test_adjust_sizes'
43
+ end
44
+
45
+ def test_append
46
+ raise NotImplementedError, 'Need to write test_append'
47
+ end
48
+
49
+ def test_assign
50
+ raise NotImplementedError, 'Need to write test_assign'
51
+ end
52
+
53
+ def test_binpt
54
+ raise NotImplementedError, 'Need to write test_binpt'
55
+ end
56
+
57
+ def test_binpt_equals
58
+ raise NotImplementedError, 'Need to write test_binpt_equals'
59
+ end
60
+
61
+ def test_bits
62
+ raise NotImplementedError, 'Need to write test_bits'
63
+ end
64
+
65
+ def test_bits_equals
66
+ raise NotImplementedError, 'Need to write test_bits_equals'
67
+ end
68
+
69
+ def test_calc_min_max
70
+ raise NotImplementedError, 'Need to write test_calc_min_max'
71
+ end
72
+
73
+ def test_check_binpt
74
+ raise NotImplementedError, 'Need to write test_check_binpt'
75
+ end
76
+
77
+ def test_check_for_overflow
78
+ #raise NotImplementedError, 'Need to write test_check_for_overflow'
79
+ a = FixedPt.new(9.5,4,1)
80
+ assert_match("111.1",a.to_binary)
81
+ assert_equal(true,a.overflow)
82
+ b = FixedPt.new(22.125,16,9)
83
+ assert_match("0010110.001000000",b.to_binary)
84
+ assert_equal(false,b.overflow)
85
+ end
86
+
87
+ def test_check_sign
88
+ raise NotImplementedError, 'Need to write test_check_sign'
89
+ end
90
+
91
+ def test_coerce
92
+ raise NotImplementedError, 'Need to write test_coerce'
93
+ end
94
+
95
+ def test_construct_from_fixnum
96
+ raise NotImplementedError, 'Need to write test_construct_from_fixnum'
97
+ end
98
+
99
+ def test_construct_from_float
100
+ raise NotImplementedError, 'Need to write test_construct_from_float'
101
+ end
102
+
103
+ def test_frac_width
104
+ raise NotImplementedError, 'Need to write test_frac_width'
105
+ end
106
+
107
+ def test_frac_width_equals
108
+ raise NotImplementedError, 'Need to write test_frac_width_equals'
109
+ end
110
+
111
+ def test_from_FixedPt
112
+ raise NotImplementedError, 'Need to write test_from_FixedPt'
113
+ end
114
+
115
+ def test_from_float
116
+ raise NotImplementedError, 'Need to write test_from_float'
117
+ end
118
+
119
+ def test_int_width
120
+ raise NotImplementedError, 'Need to write test_int_width'
121
+ end
122
+
123
+ def test_int_width_equals
124
+ raise NotImplementedError, 'Need to write test_int_width_equals'
125
+ end
126
+
127
+ def test_ival
128
+ raise NotImplementedError, 'Need to write test_ival'
129
+ end
130
+
131
+ def test_ival_equals
132
+ raise NotImplementedError, 'Need to write test_ival_equals'
133
+ end
134
+
135
+ def test_max_int_value
136
+ raise NotImplementedError, 'Need to write test_max_int_value'
137
+ end
138
+
139
+ def test_maxint
140
+ raise NotImplementedError, 'Need to write test_maxint'
141
+ end
142
+
143
+ def test_maxint_equals
144
+ raise NotImplementedError, 'Need to write test_maxint_equals'
145
+ end
146
+
147
+ def test_minint
148
+ raise NotImplementedError, 'Need to write test_minint'
149
+ end
150
+
151
+ def test_minint_equals
152
+ raise NotImplementedError, 'Need to write test_minint_equals'
153
+ end
154
+
155
+ def test_plus
156
+ raise NotImplementedError, 'Need to write test_plus'
157
+ end
158
+
159
+ def test_ranged_int_part
160
+ raise NotImplementedError, 'Need to write test_ranged_int_part'
161
+ end
162
+
163
+ def test_raw
164
+ raise NotImplementedError, 'Need to write test_raw'
165
+ end
166
+
167
+ def test_saturate
168
+ raise NotImplementedError, 'Need to write test_saturate'
169
+ end
170
+
171
+ def test_shift_left
172
+ raise NotImplementedError, 'Need to write test_shift_left'
173
+ end
174
+
175
+ def test_shift_right
176
+ raise NotImplementedError, 'Need to write test_shift_right'
177
+ end
178
+
179
+ def test_sign
180
+ raise NotImplementedError, 'Need to write test_sign'
181
+ end
182
+
183
+ def test_sign_equals
184
+ raise NotImplementedError, 'Need to write test_sign_equals'
185
+ end
186
+
187
+ def test_size
188
+ raise NotImplementedError, 'Need to write test_size'
189
+ end
190
+
191
+ def test_sizes_differ_eh
192
+ raise NotImplementedError, 'Need to write test_sizes_differ_eh'
193
+ end
194
+
195
+ def test_times
196
+ raise NotImplementedError, 'Need to write test_times'
197
+ end
198
+
199
+ def test_to_bin
200
+ #raise NotImplementedError, 'Need to write test_to_bin'
201
+ a = FixedPt.new(42,7,1)
202
+ assert_match("1010100",a.to_bin)
203
+ end
204
+
205
+ def test_to_binary
206
+ #raise NotImplementedError, 'Need to write test_to_binary'
207
+ a = FixedPt.new(9,4,0)
208
+ assert_match("1001.",a.to_binary)
209
+ b = FixedPt.new(12.25,6,2)
210
+ assert_match("1100.01",b.to_binary)
211
+ end
212
+
213
+ def test_to_f
214
+ raise NotImplementedError, 'Need to write test_to_f'
215
+ end
216
+
217
+ def test_to_fp
218
+ raise NotImplementedError, 'Need to write test_to_fp'
219
+ end
220
+
221
+ def test_to_i
222
+ raise NotImplementedError, 'Need to write test_to_i'
223
+ end
224
+
225
+ def test_to_int
226
+ raise NotImplementedError, 'Need to write test_to_int'
227
+ end
228
+
229
+ def test_truncate
230
+ raise NotImplementedError, 'Need to write test_truncate'
231
+ end
232
+
233
+ def test_value
234
+ raise NotImplementedError, 'Need to write test_value'
235
+ end
236
+ end
237
+
238
+ class TestNumeric < Test::Unit::TestCase
239
+ def test_to_fp
240
+ raise NotImplementedError, 'Need to write test_to_fp'
241
+ end
242
+ end
243
+
244
+ class TestRawFixedPt < Test::Unit::TestCase
245
+ def test_binpt
246
+ raise NotImplementedError, 'Need to write test_binpt'
247
+ end
248
+
249
+ def test_bits
250
+ raise NotImplementedError, 'Need to write test_bits'
251
+ end
252
+
253
+ def test_rawval
254
+ raise NotImplementedError, 'Need to write test_rawval'
255
+ end
256
+
257
+ def test_sign
258
+ raise NotImplementedError, 'Need to write test_sign'
259
+ end
260
+ end
261
+
262
+ # Number of errors detected: 5
metadata ADDED
@@ -0,0 +1,45 @@
1
+ --- !ruby/object:Gem::Specification
2
+ rubygems_version: 0.8.1
3
+ specification_version: 1
4
+ name: FixedPt
5
+ version: !ruby/object:Gem::Version
6
+ version: 0.0.1
7
+ date: 2005-06-23
8
+ summary: Fixed point class
9
+ require_paths:
10
+ - lib
11
+ - ext
12
+ author: Phil Tomson
13
+ email: philtomson@gmail.com
14
+ homepage: http://fixedpt.rubyforge.org
15
+ rubyforge_project:
16
+ description:
17
+ autorequire:
18
+ default_executable:
19
+ bindir: bin
20
+ has_rdoc: false
21
+ required_ruby_version: !ruby/object:Gem::Version::Requirement
22
+ requirements:
23
+ -
24
+ - ">"
25
+ - !ruby/object:Gem::Version
26
+ version: 0.0.0
27
+ version:
28
+ platform: ruby
29
+ files:
30
+ - lib/fixedpt
31
+ - lib/fixedpt/fixedpt.rb
32
+ - ext/fixedpt.c
33
+ - ext/extconf.rb
34
+ - ext/Makefile
35
+ - ext/fixedpt.o
36
+ - ext/fixedpt.so
37
+ - test/test_fixedpt.rb
38
+ test_files: []
39
+ rdoc_options: []
40
+ extra_rdoc_files: []
41
+ executables: []
42
+ extensions:
43
+ - ext/extconf.rb
44
+ requirements: []
45
+ dependencies: []