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

Posted by Axel Friedrich (axel555)
on 2012-12-10 15:15
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.

http://en.wikipedia.org/wiki/Fixed-point_arithmetic

Kind regards,
Axel
Posted by Bartosz Dziewoński (matmarex)
on 2012-12-10 15:23
(Received via mailing list)
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/bigdec...

-- Matma Rex
Posted by Axel Friedrich (axel555)
on 2012-12-10 15:58
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-...

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)>
>
> http://www.ruby-doc.org/stdlib-1.9.3/libdoc/bigdec...
>
> -- Matma Rex
Posted by Bartosz Dziewoński (matmarex)
on 2012-12-10 16:30
(Received via mailing list)
Ah. Sorry then, I misread your post.

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

-- Matma Rex
Posted by Brian Candler (candlerb)
on 2012-12-10 21:19
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 by Axel Friedrich (axel555)
on 2012-12-11 09:22
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
Please log in before posting. Registration is free and takes only a minute.
Existing account (Switch to SSL-encrypted connection)
NEW: Do you have a Google/GoogleMail or Yahoo account? No registration required!
Log in with Google account | Log in with Yahoo account
No account? Register here.