FixedPt 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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: []