Class: FixedPoint::Number

Inherits:
Object
  • Object
show all
Defined in:
lib/fixed_point/number.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(number, input_format = Format.new(1,12,20), decimal_mark = ".") ⇒ Number

Returns a new instance of Number.



16
17
18
19
20
21
22
23
24
25
# File 'lib/fixed_point/number.rb', line 16

def initialize(number, input_format=Format.new(1,12,20), decimal_mark=".")
  @source       = number
  @format       = input_format
  @decimal_mark = decimal_mark

  @warnings     = false

  #Now construct values based on config data
  @quantised    = quantise_value( source )
end

Instance Attribute Details

#formatObject (readonly)

Returns the value of attribute format.



5
6
7
# File 'lib/fixed_point/number.rb', line 5

def format
  @format
end

#sourceObject (readonly)

Input value



4
5
6
# File 'lib/fixed_point/number.rb', line 4

def source
  @source
end

Instance Method Details

#binObject

Alias for binary.



46
47
48
# File 'lib/fixed_point/number.rb', line 46

def bin
  binary
end

#binaryObject

Calculate Binary format



87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
# File 'lib/fixed_point/number.rb', line 87

def binary
  #Take signed quantised value and create binary string
  if (@quantised < 0) and frac.nonzero?
    # Fractional numbers not negative
    # So the integer part is 1 less than other wise would be and add 1+frac
    ret_bin_int = (@format.max_int_unsigned + to_i  )
    frac_value  = 1 + frac
  end

  if (@quantised < 0) and frac.zero?
    ret_bin_int = (@format.max_int_unsigned + to_i + 1 )
    frac_value  = frac
  end

  if @quantised >= 0
    ret_bin_int = self.to_i
    frac_value  = frac
  end

  ## Convert to binary String and extend to correct length
  ret_bin_int = ret_bin_int.to_s(2).rjust(@format.int_bits, '0')

  ## Normalise Fractional (fractional bits shifted to appear as integer)
  ret_bin_frac = Integer(frac_value * 2**@format.frac_bits)
  ret_bin_frac = ret_bin_frac.to_s(2).rjust(@format.frac_bits, '0' ) 

  #Decide if we need to add Decimal( Binary ) Point
  if @format.frac_bits > 0
    binary_string = ret_bin_int +  @decimal_mark + ret_bin_frac
  else 
    binary_string = ret_bin_int
  end

  return binary_string
end

#binary=(text) ⇒ Object

Methods to set value from fixed point format



142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
# File 'lib/fixed_point/number.rb', line 142

def binary=(text)
  if text.match(/([01]*)(.?)([01]*)/ )
    set_int       = $1
    int_bits      = $1.size 

    @decimal_mark = $2
    set_frac      = $3
    frac_bits     = $3.size

    #TODO Warn if the number of bits supplied does not match @format 

    ## This should now create a new format type
    #  Do not change the Signed format as can not detect that from bit pattern
    @format = Format.new(@format.signed, int_bits, frac_bits)

    @source  = binary_to_float( set_int, set_frac)
    
    ## Set the Quantised value
    @quantised = @source

    return binary
  else 
    $stderr.puts "ERROR invalid binary input \(#{text}\)"
    return nil
  end
end

#fracObject

Fractional section of quantised value.



76
77
78
# File 'lib/fixed_point/number.rb', line 76

def frac
  (@quantised - to_i)
end

#hexObject

Alias for hexadecimal.



51
52
53
# File 'lib/fixed_point/number.rb', line 51

def hex
  hexadecimal
end

#hex=(text) ⇒ Object

TODO this feature for version 0.2.1



170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
# File 'lib/fixed_point/number.rb', line 170

def hex=( text )
  ## Hex numbers do not get delimited
  ## TODO Strip leading \d+'h (Verilog denominator)
  
  if text.match(/(0x)?([0-9a-fA-F]*)/ )
    # Convert Hex to integer
    #   integer to binary string
    binary_bits = $2.to_i(16).to_s(2)
    
    #Ensure min length (for reliability manipulating string)
    binary_bits = binary_bits.rjust(text.size*4, '0')
   
    if @format.frac_bits > 0
      set_frac = binary_bits[-@format.frac_bits, @format.frac_bits]
    else
      set_frac = ""
    end
    
    set_int  = binary_bits[-(@format.width)..-(@format.frac_bits+1)]

    ## Was the input word length too Long
    oversized_bits = binary_bits.size - @format.width 
    if oversized_bits > 0
      # give a semantic name to the discarded bits
      discarded_bits = binary_bits[0,oversized_bits]

      #If data (mix of 1 and 0) contained in the discarded bits raise Error
      unless all_bits_the_same discarded_bits   
        $stderr.puts %{Error using hex=#{text}, format is #{@format.width}, truncated data is #{discarded_bits}
  The MSBs seem to contain data they are not just 0 or 1 padded}
      end
    end

    @source    = binary_to_float( set_int, set_frac )
    @quantised = @source

  else
    $stderr.puts "ERROR invalid hex input \(#{text}\)"
    return nil
  end
end

#hexadecimalObject

Calculate Hexadecimal format



126
127
128
129
130
131
132
133
134
135
136
137
# File 'lib/fixed_point/number.rb', line 126

def hexadecimal
  #Clean Binary code (remove _ - . etc)
  clean_binary = to_b.scan(/[01]/).join('')

  #Convert to unsigned int then to hex
  hex          = clean_binary.to_i(2).to_s(16)
  hex_chars    = (@format.width/4.0).ceil

  ## Extend to the correct length
  ## Negative numbers will already have MSBs this if for small +VE
  return hex.rjust(hex_chars, '0')
end

#overflow?Boolean

Numerical overflow flag

Returns:

  • (Boolean)


30
31
32
# File 'lib/fixed_point/number.rb', line 30

def overflow?
  @overflow
end

#to_bObject

Alias for binary.



56
57
58
# File 'lib/fixed_point/number.rb', line 56

def to_b
  binary
end

#to_fObject

Floating Point form of the quantised value.



66
67
68
# File 'lib/fixed_point/number.rb', line 66

def to_f
  @quantised
end

#to_hObject

Alias for hexadecimal.



61
62
63
# File 'lib/fixed_point/number.rb', line 61

def to_h
  hexadecimal
end

#to_iObject

Integer, integer part of quantised value.



71
72
73
# File 'lib/fixed_point/number.rb', line 71

def to_i
  @quantised.to_i
end

#to_sObject



80
81
82
# File 'lib/fixed_point/number.rb', line 80

def to_s
  to_f.to_s
end

#underflow?Boolean

Numerical underflow flag

Returns:

  • (Boolean)


37
38
39
# File 'lib/fixed_point/number.rb', line 37

def underflow?
  @underflow
end

#warnings(val = true) ⇒ Object

TODO def log def log2



217
218
219
# File 'lib/fixed_point/number.rb', line 217

def warnings( val=true )
  @warnings = val
end