home *** CD-ROM | disk | FTP | other *** search
-
-
- {$P-}
- {$M+}
- {$E+}
- PROGRAM Mock;
-
- {$I i:\opus.i}
- {$I i:\GCTV.inc}
-
- FUNCTION Do_Alert( alert : Str255 ; def_btn : integer ) : integer ;
- EXTERNAL ;
- PROCEDURE Hide_Mouse ;
- EXTERNAL ;
- PROCEDURE Show_Mouse ;
- EXTERNAL ;
-
- PROCEDURE REAL_TO_STRING ( real_num : REAL;
- VAR string_real : STRING;
- digits : INTEGER;
- sci_not : BOOLEAN );
-
- (*
- real_num : real number to be converted into a string
- string_real : working variable that also passes string result to caller
- digits : specifies # of digits to be displayed right of decimal,
- valid values are 0-11
- sci_not : flag which determines whether to express in sci. not. or not
- *)
-
- (*
- FORMAT of string returned is:
- sci. not.:
- sign ( - or SPACE ), #.#####... , E, sign ( - or nothing ), ##.
- non-sci. not. :
- sign ( - or SPACE ), ####.####.
- *)
-
- (*
- Round-off errors of the nature x.xxxx9999 are corrected; consequently,
- any number with a sequence of 1 or more terminal 9's
- is affected, even if this is NOT an artifact. This should rarely be a
- problem. Also, if a number is to be expressed in expanded form, the
- magnitude of the exponent plus the # of digits to be displayed can not
- exceed 8, since LONG_ROUND generates long_ints- size < 2e9. This is not
- too severe a problem since only 11 digits of precision are supported
- anyway. That is, specifying 4 digits for the # 100,000,000.9012 is
- meaningless since the number is rounded to 100,000,000.9 as it becomes
- a REAL. The last digits are unavailable to real_to_string. In such
- cases, no action is performed on the number- it emerges untouched by
- the rounding function. Also, note that the detection of 999 occurs after
- conversion to 1 <= mag_num < 10. Thus, 99,999,999,999 becomes 9.9999999999
- which indicates a rounding error.
- *)
-
- LABEL 1;
- VAR c,i,j : INTEGER;
- sign_exp : STRING[1];
- loc_char : CHAR;
-
- PROCEDURE INSERT_COMMAS;
- BEGIN
- dec_pos := POS('.',string_real);
- IF (dec_pos > 5) OR (dec_pos = 0) THEN BEGIN
- IF dec_pos = 0 THEN
- comma_pos := LENGTH(string_real) -2
- ELSE
- comma_pos := dec_pos-3;
- WHILE comma_pos > 2 DO BEGIN
- INSERT(',',string_real,comma_pos);
- comma_pos := comma_pos-3
- END
- END
- END; { INSERT_COMMAS }
-
- PROCEDURE ADJUST_TO_SPECIFIED_LENGTH;
- (* adjusts appearance following rounding *)
- BEGIN
- dec_pos := POS ( '.',string_real );
- n_digits := dec_pos+digits;
- WHILE LENGTH(string_real) < n_digits DO
- string_real := CONCAT(string_real,'0');
- WHILE LENGTH(string_real) > n_digits DO
- DELETE(string_real,LENGTH(string_real),1);
- IF POS('.' , string_real ) = LENGTH(string_real) THEN
- DELETE(string_real,LENGTH(string_real),1)
- END; (* adjust_to_specified_length *)
-
- PROCEDURE DO_EXPONENT;
- BEGIN
- temp_1 := '';
- IF c >= 30 THEN BEGIN
- temp_1 := '3';
- c := c-30
- END;
- IF c >= 20 THEN BEGIN
- temp_1 := '2';
- c := c-20
- END;
- IF c >= 10 THEN BEGIN
- temp_1 := '1';
- c := c-10
- END;
- temp_1 := CONCAT(temp_1,CHR(c+48));
- adjust_to_specified_length;
- string_real := CONCAT(string_real,'E',sign_exp,temp_1)
- END;
-
- PROCEDURE REMOVE_9s;
- VAR i , j : INTEGER;
- BEGIN
- (* Get rid of artifactual "999999" generated, if any *)
- temp_1 := COPY(string_real,4,10);
- i := 10;
- found := FALSE;
- WHILE (NOT found) AND (i >= 1) DO
- IF temp_1[i] <> '9' THEN
- found := TRUE
- ELSE
- i := i-1;
- i := i+1;
- IF i <= 10 THEN BEGIN
- FOR j := 1 TO 15 DO
- last[j] := 'f';
- str_len := i+2;
- FOR i := 1 TO str_len DO
- last[i] := string_real[i];
- IF str_len = 3 THEN BEGIN (* x.9999999999 *)
- IF last[2] = '9' THEN BEGIN
- last[2] := '1';
- last[4] := '0';
- IF sign_exp = '' THEN
- c := c+1
- ELSE
- c := c-1
- END
- ELSE BEGIN
- last[2] := CHR(ORD(last[2])+1);
- last[4] := '0'
- END
- END
- ELSE (* x.xxxx999999 *)
- (* needn't check here if last[str_len]=9; it CAN'T be,
- as it would have been a part of the string of 9's *)
- last[str_len] := CHR(ORD(last[str_len])+1);
- string_real := '';
- i := 1;
- WHILE last[i] <> 'f' DO BEGIN (* recreate string_real *)
- string_real := CONCAT(string_real,last[i]);
- i := i+1
- END
- END
- END; (* REMOVE_9s *)
-
- BEGIN (* REAL_TO_STRING *)
- IF real_num <> 0.0 THEN BEGIN
- (* sign of number *)
- IF real_num < 0.0 THEN
- string_real := '-'
- ELSE
- string_real := ' ';
- IF ((real_num < 1.0) AND (real_num > 0.0)) OR
- ((real_num < 0.0) AND (real_num > -1.0)) THEN
- sign_exp := '-'
- ELSE
- sign_exp := '';
- (* got sign, so work with number magnitude *)
- mag_num := ABS (real_num);
- (* c counts the number of times the number can be multiplied or div-
- ided by 10 so that finally 1 <= number < 10 *)
- c := 0;
- (* make 1 <= number < 10 *)
- IF mag_num >= 10.0 THEN
- REPEAT
- mag_num := mag_num/10.0;
- c := c+1
- UNTIL mag_num < 10.0
- ELSE IF mag_num < 1.0 THEN
- REPEAT
- mag_num := mag_num*10.0;
- c := c+1
- UNTIL mag_num >= 1.0;
-
- (* Round mag_num to specified # of digits *)
-
- IF (sci_not) AND (digits <= 8) THEN
- mag_num := LONG_ROUND(mag_num*PwrOfTen(digits))/PwrOfTen(digits);
- IF NOT sci_not THEN BEGIN (* Round to spec # digit if possible *)
- IF (c+digits <= 8) AND ((real_num > 1) OR (real_num < -1)) THEN
- mag_num := LONG_ROUND(mag_num*PwrOfTen(c+digits)) /
- PwrOfTen(c+digits);
- (* bug fix- account for numbers between -1.0 and 1.0 *)
- i := digits-c;
- IF (real_num < 1) AND (real_num > -1) THEN BEGIN
- IF ABS(i) <= 8 THEN BEGIN
- IF i >= 0 THEN
- mag_num := LONG_ROUND(mag_num*PwrOfTen(i))/PwrOfTen(i)
- ELSE
- mag_num := LONG_ROUND(mag_num/PwrOfTen(ABS(i)))*
- PwrOfTen(ABS(i))
- END
- END
- END;
- IF mag_num = 0 THEN BEGIN
- string_real := ' 0';
- GOTO 1
- END;
- IF mag_num >= 10 THEN BEGIN (* rounded up to 10 *)
- IF sign_exp = '-' THEN BEGIN
- c := c-1;
- IF c = 0 THEN
- sign_exp := '';
- END
- ELSE
- c := c+1;
- mag_num := 1
- END;
-
- (* reals have 11 digits of precision *)
- (* convert REAL to a string equivalent *)
-
- FOR i := 1 TO 11 DO BEGIN
- j := TRUNC (mag_num);
- string_real := CONCAT(string_real,CHR (j+48));
- mag_num := (mag_num-j)*10
- END; (* FOR i *)
- INSERT('.',string_real,3);
-
- remove_9s;
-
- { now have the mantissa converted in string_real, so... }
-
- IF NOT sci_not THEN BEGIN
- (* express in expanded form *)
- IF sign_exp = '-' THEN BEGIN (* mag_num < 1, mag_num <> 0 *)
- loc_char := string_real[2];
- DELETE(string_real,2,1);
- INSERT('0',string_real,2);
- INSERT(loc_char,string_real,4);
- FOR i := 1 TO c-1 DO
- INSERT('0',string_real,4);
- adjust_to_specified_length
- END
- ELSE BEGIN
- DELETE(string_real,3,1);
- IF 3+c > LENGTH(string_real) THEN
- FOR i := LENGTH(string_real) TO 2+c DO
- string_real := CONCAT(string_real,'0');
- INSERT('.',string_real,3+c);
- adjust_to_specified_length;
- insert_commas
- END
- END
- ELSE
- do_exponent;
- END (* begin of first then clause *)
- ELSE (* real_num = 0 *)
- string_real := ' 0';
- 1: END; (* REAL_TO_STRING *)
-
-
-
- FUNCTION STRING_TO_REAL ( VAR str : STR30 ) : REAL;
-
- (*
- Strings passed must follow the following rules:
- 1. may have been created by REAL_TO_STRING,
- 2. may have been entered via READ or WINDOW_INPUT
- a. Strings entered via WINDOW_INPUT may contain NO imbedded spaces,
- and if given in sci. not. must use either 'e' or 'E' .
- 3. overflows are trapped, STRING_TO_REAL returns 0 and string_real
- returns 'OVERFLOW'; otherwise string_real is preserved intact
- 4. must be an exact image of a valid real! VALID_NUMBER screens out
- all miswritten numbers, i.e 1.22.4-e0-4
- 5. must have at least one digit preceding a decimal
- 6. doesn't check for spaces because the routines that call it either
- eat up the spaces or don't allow them
- 7. doesn't check for a null string since one is never passed
- *)
-
- LABEL 1;
-
- BEGIN
- loverflow := FALSE;
- sign_num := 1;
- sign_exp := 1;
- lpower := 1;
- real_num := 0;
- exp_val := 0;
- lfactor := 0;
- str_pos := 1;
- str_len := LENGTH(str);
- IF (str[1] = '+') OR (str[1] = '-') OR (str[1] = ' ') THEN BEGIN
- IF str[1] = '-' THEN
- sign_num := -1;
- str_pos := 2
- END;
- lquit := FALSE;
- WHILE (str_pos <= str_len) AND (NOT lquit) DO
- IF str[str_pos] IN digits THEN BEGIN
- real_num := real_num*10+ORD(str[str_pos])-ORD('0');
- str_pos := str_pos+1
- END
- ELSE
- lquit := TRUE;
- IF str_pos <= str_len THEN
- IF str[str_pos] = '.' THEN BEGIN
- places := 0;
- str_pos := str_pos+1;
- lquit := FALSE;
- WHILE (str_pos <= str_len) AND (NOT lquit) DO
- IF str[str_pos] IN digits THEN BEGIN
- places := places+1;
- real_num := real_num*10+ORD(str[str_pos])-ORD('0');
- str_pos := str_pos+1
- END
- ELSE
- lquit := TRUE;
- real_num := real_num/PwrOfTen(places)
- END;
- IF str_pos <= str_len THEN
- IF (str[str_pos] = 'E') OR (str[str_pos] = 'e') THEN BEGIN
- str_pos := str_pos+1;
- IF str_pos <= str_len THEN BEGIN
- IF (str[str_pos] = '+') OR (str[str_pos] = '-') THEN BEGIN
- IF str[str_pos] = '-' THEN
- sign_exp := -1;
- str_pos := str_pos+1
- END;
- lquit := FALSE;
- WHILE (str_pos <= str_len) AND (NOT lquit) DO
- IF str[str_pos] IN digits THEN BEGIN
- exp_val := exp_val*10+ORD(str[str_pos])-ORD('0');
- str_pos := str_pos+1
- END
- ELSE
- lquit := TRUE;
- IF exp_val > 38 THEN BEGIN
- loverflow := TRUE;
- GOTO 1
- END;
- lpower := PwrOfTen(exp_val);
- IF sign_exp < 0 THEN
- lpower := 1/lpower
- END
- END;
-
- (* Check for potential overflow *)
-
- mag_num := real_num;
-
- IF mag_num <> 0 THEN
- IF mag_num >= 10 THEN
- REPEAT
- mag_num := mag_num/10.0;
- lfactor := lfactor+1
- UNTIL mag_num < 10.0
- ELSE IF mag_num < 1.0 THEN
- REPEAT
- mag_num := mag_num*10.0;
- lfactor := lfactor-1
- UNTIL mag_num >= 1.0;
-
- 1: IF (ABS(exp_val*sign_exp+lfactor) >= 37) OR (loverflow) THEN BEGIN
- alert := Do_Alert(float_over,1);
- str := 'OVERFLOW';
- string_to_real := 0
- END
- ELSE
- string_to_real := real_num*sign_num*lpower
-
- END; (* STRING_TO_REAL *)
-
-
- PROCEDURE INT_TO_STRING ( n : INTEGER; VAR s : STR10 );
- { for non_negative integers }
- VAR
- digit,divisor : INTEGER;
- leading : BOOLEAN;
- BEGIN { INT_TO_STRING }
- IF n <= 0 THEN
- s := '0'
- ELSE BEGIN
- s := '';
- divisor := 10000;
- leading := TRUE;
- WHILE divisor > 0 DO BEGIN
- digit := n DIV divisor;
- IF (digit <> 0) OR (NOT leading) THEN BEGIN
- s := CONCAT(s,CHR(digit+48));
- leading := FALSE
- END;
- n := n MOD divisor;
- divisor := divisor DIV 10
- END
- END
- END; { INT_TO_STRING }
-
- BEGIN (* dummy program for modular compilation *)
- END.
-
-
-