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.
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.
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
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
This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.