Examining the routines on this page helped me greatly. Thank you Mike and Nippur 77.
Here is my converter as a Ruby method.
Code: Select all
=begin
title ; CBM FLOAT CONVERTER
language ; RUBY
format ; METHOD
author ; RYAN LISTON
date ; 5/8/2021
description ; CONVERTS DECIMAL INPUT INTO 40-BIT SCALER FLOAT
=end
require 'bigdecimal' #includes BigDecimal class for precicion decimals
#method translates decimal input into 40 bit scaler float otput
def cbm_float_converter x #recieves input as x
@x=x.to_s #converts input to a string as @x
@float=BigDecimal (@x) #converts @x to BigDecimal type as @float
@absolute=BigDecimal(@x).abs #retrieves the absolute value of @x to @absolute
@integer=@absolute.floor #extracts the integer from @absolute to @integer
@fraction=BigDecimal((@absolute-@integer).to_s) #extracts fraction as a string to @fraction
@bin_integer=(@integer.to_s(2)) #coverts integer as binary string to @bin_interger
#sets up sign bit as a string on @ sign
if @float==@absolute #determins sign
@sign="0" #if positiv
else @sign="1" #if negative
end
#generates the fraction portion for the final binary string
@bin_fraction=String.new #initializes @convert as an empty string
@frac=@fraction #tranfers @fraction to @frac
@y=0 #sets @y as a counter starting at 0
while @y<62#@y<31-(@bin_integer.length-1) #sets up loop for 0 to (31 - [binary integer length])
@frac=@frac*BigDecimal("2.0") #multiplys @fraction *2
@floor=BigDecimal((@floor=@frac.floor.to_s)) #extract integer from result
@bin_fraction=@bin_fraction+(@floor.to_i).to_s #Drops interger (1 or 0) as a bit in a binary string to @convert
@frac=@frac-@floor #extract new fraction
@y+=1 #increment @y and loop
end
#extracts exponant byte and proccesses the integer segment
if @integer>0 #if integer is > 0
@exponent=(@bin_integer.length+128).to_s(2) #extracts length of binary integer string to @exponent
@bin_integer=(@bin_integer[1..-1]) #drops the assumed bit from binary integer string
#if integer = 0
else @exponent=@bin_fraction #tranfer @bin_fraction to @exponent
@bin_integer=nil.to_s #deletes integer segment
@y=0 #sets @y to 0 for counter
while @exponent[0]=="0" #if bit=0
@exponent=(@exponent[1..-1]) #delete 0-bit
@y+=1 #increment @y
end
@exponent=(-@y+128).to_s(2) #sets exponent byte as a binary string
while @exponent.length<8 #fills exponent byte
@exponent="0"+@exponent #until size = 8
end
end
#sets up output
@bin_fraction=@bin_fraction[0...31-@bin_integer.length] #trims extra bytes off of fraction
@bin_string=@exponent+@sign+@bin_integer+@bin_fraction #joins segments together in a single
@float_array=[0,0] #initializes array for output
@labels="exponent ","mantissa 1","mantissa 2","mantissa 3","mantissa 4" #byte labels for output
@y=0 #sets @y to 0 for counter
while @y<5 #sets loop until @y=5
@float_array[@y]=(((@bin_string.slice(0..7)).to_i(2)).chr).unpack("H*") #slices the binary string
@bin_string=@bin_string.slice(8..-1) #...into 8-bit segments and converts to hex output to @float_array[@y]
@y+=1 #increment @y and loop
end
#outputs 40-bit scaler float as bytes in hex format
for t in (0..4) #sets loop
print "#{@labels[t]} = " #prints byte label
puts "$#{@float_array[t][0]}" #prints byte
end
end
#get user input
y=0
while y==0
puts "\n enter float as decimal"
user_input=gets.to_f
cbm_float_converter user_input
end