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 ****************************
|