Binary Fixed-Point in Ruby? (Improved FixedPt?)

Hi,

does anybody have/know of an alternative or improved version of FixedPt
("http://rubyforge.org/projects/fixedpt/)?

FixedPt handels fixed-point binaries (not decimals).

For example, this should work:

fi = FixedPt.new(0.1,5,7)

p fi.bin
gives: "11111"
but should give something like: "01100"

and

p fi.to_f
gives: 0.2421875
but should give something like.: 0.1016

I run the ruby-version of FixedPoint (not the compiled version).
I want to use it for checking the fixed-point formats of calculations
done with hardware.

Kind regards,
Axel

···

--
Posted via http://www.ruby-forum.com/.

There is BigDecimal in the standard library.

irb(main):011:0> require 'bigdecimal'
=> true
irb(main):012:0> BigDecimal
=> BigDecimal
irb(main):014:0> BigDecimal.new '123'
=> #<BigDecimal:13c0950,'0.123E3',9(18)>

http://www.ruby-doc.org/stdlib-1.9.3/libdoc/bigdecimal/rdoc/index.html

-- Matma Rex

Axel Friedrich wrote in post #1088522:

FixedPt handels fixed-point binaries (not decimals).

For example, this should work:

fi = FixedPt.new(0.1,5,7)

p fi.bin
gives: "11111"
but should give something like: "01100"

What are the 5 and 7 meant to signify?

0.1 in decimal has no exact representation in binary. It would be
0.00011001100...

I don't know of an existing library for working in fixed-point. If the
number of digits after the binary point is fixed, then you could just
work with integers with a power-of-two scaling factor - similar to
working with cents instead of dollars.

class FixBin
  def initialize(value, binbits)
    @value = (value * (1 << binbits)).to_i
    @binbits = binbits
  end
  def to_f
    @value * 1.0 / (1 << @binbits)
  end
  def to_s
    res = "%0#{@binbits+1}b" % @value
    res[-@binbits,0] = "."
    res
  end
end

a = FixBin.new(0.1, 7)
puts a.to_f
puts a.to_s

···

--
Posted via http://www.ruby-forum.com/\.

Unfortunatly, I don't understand how BigDecimal could help with my
Binary- Fixed-Point problems.

Maybe I should explain in more details:

I have _no_ problem with accuracy.
I'm developing hardware, which calculates mathematic expressions using
"fixed-point binary representations" of values. That is a certain number
of bits (say 16) represent a value (say 0.1). The format of the
fixed-point representation must "set" right (right number of bits and
right place of the virtual binary point), in order to avoid overflow or
loss of accuracy. For checking, if I have "set" the format right, I want
to simulate it in Ruby. Normaly, Ruby does it's calculations in Integer,
or Double or even BigDecimal, but not in BINARY Fixed-Point, so I think
I must use a special library for this, for example the existing
"FixedPt"-library. But unfortunately, this library is not perfect enough
for my purpose.

Maybe this explains it better:
http://en.wikibooks.org/wiki/Floating_Point/Fixed-Point_Numbers

Axel

Bartosz Dziewoński wrote in post #1088523:

···

There is BigDecimal in the standard library.

irb(main):011:0> require 'bigdecimal'
=> true
irb(main):012:0> BigDecimal
=> BigDecimal
irb(main):014:0> BigDecimal.new '123'
=> #<BigDecimal:13c0950,'0.123E3',9(18)>

Index of Classes & Methods in bigdecimal: Ruby Standard Library Documentation (Ruby 1.9.3)

-- Matma Rex

--
Posted via http://www.ruby-forum.com/\.

Hi Brian,

many thanks for your answer.!

fi = FixedPt.new(0.1,5,7)

What are the 5 and 7 meant to signify?

This means:
* Use 5 Bits, and
* The binary point (similar to the "decimal point") is assumed to be
between the 7th and 8th bit, counting from right.

In the above example, it is like this:
A value of decimal 0.1 shall be handled by hardware.
The hardware (FPGA, actually) handels these bits (representing not
exactly decimal 0.1):
01100 (5 Bits)
The logic is designed in such a way, that these bits represent the
following value:
0.0001100 (binary point between the 7th and 8th bit from right)

class FixBin
  def initialize(value, binbits)
    @value = (value * (1 << binbits)).to_i
    @binbits = binbits
  end
  def to_f
    @value * 1.0 / (1 << @binbits)
  end
  def to_s
    res = "%0#{@binbits+1}b" % @value
    res[-@binbits,0] = "."
    res
  end
end

That's a very neat and elegant way! Thank you for that. I think, I'll
modify the existing "fixedpt.rb" file for my needs, with your code in
mind.

Axel

···

--
Posted via http://www.ruby-forum.com/\.

Ah. Sorry then, I misread your post.

I don't know of anything that would serve your purpose, but I wish you
good luck :slight_smile:

-- Matma Rex