C2F REXX Character to Float Conversion.
Browse text version of C2F

REXX Floating point conversion
   File  Edit  Confirm  Menu  Utilities  Compilers  Test  Help                  
 -------------------------------------------------------------------------------
 EDIT         JIM.CLIST(C2F) - 01.06                        Columns 00009 00080
 Command ===>                                                  Scroll ===> CSR 
 ****** ***************************** Top of Data ******************************
 000001 /*------------ REXX -----------------------------+
 000002  *                                               |
 000003  * Converts a number to internal float format.   |
 000004  * Displays the result                           |
 000005  * Then converts the result back out to decimal. |
 000006  *                                               |
 000007  * Written by Jim Connelley                      |
 000008  *                                               |
 000009  * Tracing thru this code is a good way to get   |
 000010  * familiar with IBM system 390 internal         |
 000011  * floating point format.                        |
 000012  *                                               |
 000013  *-----------------------------------------------+
 000014  */
 000015 Numeric Digits 100     /* handle BIG numbers */
 000016 Parse Upper Arg input_val .
 000017 Say "Input Value:                  " input_val
 000018 If datatype(input_val) /= "NUM" Then Do
 000019   Say "invalid value"
 000020   Exit 0
 000021   End
 000022 If input_val = 0 Then Do      /* special case zero */
 000023   Say "Resulting Value:               0000000000000000"
 000024   Say "Floating value converted back: 0"
 000025   Exit 0
 000026   End                                                                   
 000027 input_val = Format(input_val)                                           
 000028 
 000029 /*-------------------------------------------------------+
 000030  * Handle leading minus sign                             |
 000031  *-------------------------------------------------------+
 000032  */
 000033 If left(input_val,1) = "-" Then Do
 000034   Sign = "80"x
 000035   input_val = Substr(input_val,2)   /* remove sign */
 000036   End
 000037 Else Do
 000038   Sign = "00"x
 000039   End
 000040 
 000041 /*-------------------------------------------------------+
 000042  * Separate input into integer and fraction              |
 000043  *-------------------------------------------------------+
 000044  */
 000045 Parse Var input_val input_integer "." input_fract
 000046 
 000047 /*-------------------------------------------------------+
 000048  * If no fraction given, then default to zero            |
 000049  *-------------------------------------------------------+
 000050  */
 000051 If input_fract = "" Then input_fract = 0
 000052 input_fract = "."input_fract
 000053                                                                         
 000054 /*-------------------------------------------------------+              
 000055  * Convert integer portion directly                      |
 000056  *-------------------------------------------------------+
 000057  */
 000058 float_value = D2x(input_integer)
 000059 If float_value = "0" Then float_value = ""
 000060 
 000061 /*-------------------------------------------------------+
 000062  * If there is no integer portion, then we can normalize |
 000063  * just the fraction portion of the input value.         |
 000064  *-------------------------------------------------------+
 000065  */
 000066 exponent = Length(float_value)
 000067 If exponent = 0 Then Do Forever
 000068   normalizing_fraction = input_fract * 16
 000069   If normalizing_fraction >= 1 Then Leave
 000070   input_fract = normalizing_fraction
 000071   exponent = exponent - 1
 000072   End
 000073 
 000074 /*-------------------------------------------------------+
 000075  * compute amount to normalize                           |
 000076  *-------------------------------------------------------+
 000077  */
 000078 If exponent < 0 Then Do
 000079   amount_to_normalize = 0
 000080   End                                                                   
 000081 Else Do                                                                 
 000082   amount_to_normalize = exponent
 000083   End
 000084 
 000085 /*-------------------------------------------------------+
 000086  * Normalize the build float value.                      |
 000087  *-------------------------------------------------------+
 000088  */
 000089 remainder = input_fract
 000090 Do i = 1 To (14 - amount_to_normalize)
 000091   normalizing_value = remainder * 16
 000092   quotient = normalizing_value % 1
 000093   remainder = normalizing_value // 1
 000094   float_value = float_value || D2x(quotient)
 000095   End
 000096 
 000097 /*-------------------------------------------------------+
 000098  * Convert integer portion directly                      |
 000099  *-------------------------------------------------------+
 000100  */
 000101 sign_and_exponent = C2x(Bitor(X2c(D2x(exponent+64)),Sign))
 000102 result_value = Substr(C2x(X2c(sign_and_exponent||float_value)),1,16)
 000103 Say "Resulting floating value:     " result_value
 000104 
 000105 /*-------------------------------------------------------+
 000106  * Now begin conversion back out to decimal display.     |
 000107  *-------------------------------------------------------+              
 000108  */                                                                     
 000109 internal_float = X2c(result_value)
 000110 
 000111 /*-------------------------------------------------------+
 000112  * Extract the sign and exponent byte                    |
 000113  *-------------------------------------------------------+
 000114  */
 000115 sign_and_exponent = Substr(internal_float,1,1)
 000116 
 000117 /*-------------------------------------------------------+
 000118  * Compute the true exponent                             |
 000119  *-------------------------------------------------------+
 000120  */
 000121 x_exponent    = Bitand(sign_and_exponent,"7f"x)
 000122 excess_64_exp = C2d(x_exponent)
 000123 true_exponent = excess_64_exp - 65
 000124 
 000125 /*-------------------------------------------------------+
 000126  * Create a factor of +1 or -1 from the sign bit         |
 000127  *-------------------------------------------------------+
 000128  */
 000129 sign_factor = ((Bitand(sign_and_exponent,"80"x)="00"x)-.5)*2
 000130 
 000131 /*-------------------------------------------------------+
 000132  * Extract the "fraction" part of the number             |
 000133  *-------------------------------------------------------+
 000134  */                                                                     
 000135 fraction     = Substr(internal_float,2)                                 
 000136 hex_fraction = C2x(fraction)
 000137 result_value = 0
 000138 
 000139 /*-------------------------------------------------------+
 000140  * Sum the result value by processing each hex digit     |
 000141  *-------------------------------------------------------+
 000142  */
 000143 Do i = 1 To Length(hex_fraction)
 000144   hex_digit     = X2d(Substr(hex_fraction,i,1))
 000145   result_value  = result_value + (hex_digit * (16**true_exponent))
 000146   true_exponent = true_exponent - 1
 000147   End
 000148 
 000149 /*-------------------------------------------------------+
 000150  * Factor in the sign                                    |
 000151  *-------------------------------------------------------+
 000152  */
 000153 result_value   = result_value * sign_factor
 000154 
 000155 /*-------------------------------------------------------+
 000156  * Format the result                                     |
 000157  *-------------------------------------------------------+
 000158  */
 000159 print_value = Strip(Strip(Format(result_value,,14),T,0),T,.)
 000160 If print_value = 0 Then  /* Maybe we stripped too much */
 000161   print_value = Format(result_value,2,14,2,0)                           
 000162                                                                         
 000163 Say "Floating value converted back:" print_value
 000164 Exit 0
 ****** **************************** Bottom of Data ****************************