Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- program t1;
- uses Math;
- type vector = array[integer] of char;
- const N = 15;
- const MAXDOUBLE = 1.7e308;
- const MINDOUBLE = 5.0e-324;
- var cntr_real_part: integer;
- arr_chars_cant_be_first: vector;
- arr_add: char;
- arr: vector;
- {flag для подсчёта char, образующих символ}
- flag_for_char: boolean;
- trash: integer;
- {input_base - сс числа, вводоимого пользователем}
- code, base, i, curr_base, curr_digit: integer;
- sign, s: char;
- {flag для сс}
- flag_base: boolean;
- total_result, epsilon: double;
- digit_cntr: integer;
- {наше вещественное число}
- num, num_part_real: double;
- {знак числа, которое вводится через коммандную строку}
- intenal_sign: char;
- digits_for_e: integer;
- {флаг для проверки слова 'finish'}
- flag_for_finish: boolean = False;
- {флаг для того, чтоб понять какой знак у total total_result}
- flag_for_total_result: boolean;
- flag_for_comments: boolean = False;
- {first_it - для того, чтобы проверить количество пробелов на первом цикле}
- count_prog_iteration, first_it: integer;
- flag_for_integer_part: boolean = False;
- {проверка на количество char-ов в digit-е}
- flag_for_float_part: boolean = False;
- {проверка деления на нуль}
- flag_del_zero: boolean = False;
- {флаг для того, если первый символ строки не ялвяется знаком}
- flag_for_inappopriate_digit_in_input: boolean = False;
- flag_for_oveflow: boolean = False;
- flag_eoln: boolean = False;
- flag_for_space: boolean = False;
- flag_internal_tabs_for_ns: boolean = False;
- flag_alot_null: boolean = True;
- procedure Case_comment();
- var c: char;
- begin
- repeat
- read(c);
- until (EOLn)
- end;
- {
- функция, которая будет контролировать самый(!!!) первый char в строке
- на соответствие требованиям
- }
- function For_first_digit(first_char: char): boolean;
- var arr_chars_cant_be_first: vector;
- arr_add: char;
- i: integer;
- flag: boolean;
- begin
- arr_add := '0';
- flag := False;
- for i := 1 to 10 do
- begin
- arr_chars_cant_be_first[i] := arr_add;
- arr_add := succ(arr_add);
- end;
- arr_add := 'a';
- for i := 11 to 36 do
- begin
- if arr_add <> 'f' then
- arr_chars_cant_be_first[i] := arr_add;
- arr_add := succ(arr_add);
- end;
- for i := 1 to 36 do
- begin
- if arr_chars_cant_be_first[i] = first_char then
- begin
- flag := True;
- break;
- end;
- end;
- For_first_digit := flag;
- end;
- function Double_to_int(number: double): integer;
- var i: integer;
- begin
- if abs(number - 0) < 0.1 then
- Double_to_int := 0
- else
- begin
- for i := 1 to 256 do
- begin
- if abs(number - i) < 0.1 then
- begin
- Double_to_int := i;
- break;
- end;
- end;
- end;
- end;
- {перевод из 10-й в 16-юю сс}
- procedure From_any_to_hex(number: integer);
- type vector = array[integer] of char;
- var ch1, ch2: integer;
- mas_of_dec_to_hex: vector;
- piece: char;
- i: integer;
- char_ch1, char_ch2: char;
- begin
- piece := '1';
- for i := 1 to 9 do
- begin
- mas_of_dec_to_hex[i] := piece;
- piece := succ(piece);
- end;
- piece := 'a';
- for i := 10 to 15 do
- begin
- mas_of_dec_to_hex[i] := piece;
- piece := succ(piece);
- end;
- if number = 0 then
- write('00', ' ');
- if (1 <= number) and (number <= 15) then
- write('0', mas_of_dec_to_hex[number], ' ');
- if number > 15 then
- begin
- ch1 := number mod 16;
- char_ch1 := mas_of_dec_to_hex[ch1];
- if ch1 = 0 then
- char_ch1 := '0';
- number := number div 16;
- ch2 := number mod 16;
- char_ch2 := mas_of_dec_to_hex[ch2];
- if ch2 = 0 then char_ch2 := '0';
- write(char_ch2, char_ch1, ' ');
- end;
- end;
- {подсчёт количество цифр при переводе(точность)}
- function E_count_digit(b: integer; eps: double): integer;
- var r: double;
- begin
- r := Ln(1 / eps) / Ln(b);
- E_count_digit := trunc(r) + 1;
- end;
- {ставит пробелы при выводе}
- procedure Space_bar(s: integer);
- var cntr, i: integer;
- begin
- cntr := 0;
- repeat
- s := s div 10;
- cntr := cntr + 1;
- until(s = 0);
- for i := 1 to (6 - cntr) do
- write(' ');
- end;
- function Char_to_digit(a: vector; key: char; piece: integer): integer;
- var i: integer;
- begin
- if key = '0' then
- Char_to_digit := 0
- else
- begin
- for i := 1 to 15 do
- begin
- if a[i] = key then
- begin
- Char_to_digit := i
- end;
- end;
- end;
- end;
- {возведение в степень}
- function Pow(n: integer; degree: integer): double;
- var i: integer;
- ans: double;
- begin
- ans := 1;
- for i := 1 to degree do
- ans := ans * n;
- Pow := ans;
- end;
- {
- процедура вывода, с переводом числа
- accuracy - точность для вещ части, b - основание СС
- }
- procedure Output_with_conversion(accuracy, b: integer; num: double);
- var del_cntr, i: integer;
- float_part, temporary_float_part, digit: double;
- temporary_int_part, n, copy: double;
- int_digit, int_tmp_int_part: integer;
- begin
- del_cntr := 0;
- {нашли целую часть нашего числа}
- n := int(num);
- {дробная часть нашего числа}
- float_part := num - n;
- {подсчёт количества делений числа на СС}
- copy := n;
- repeat
- copy := copy / b;
- copy := int(copy);
- del_cntr := del_cntr + 1;
- until(copy - 0.001 <= 0);
- copy := n;
- del_cntr := del_cntr - 1;
- repeat
- digit := copy / (Pow(b, del_cntr));
- digit := int(digit);
- int_digit := Double_to_int(digit);
- From_any_to_hex(int_digit);
- copy := copy - int_digit * Pow(b, del_cntr);
- del_cntr := del_cntr - 1;
- until(del_cntr = -1);
- write('. ');
- for i := 1 to accuracy do
- begin
- temporary_float_part := float_part * b;
- temporary_int_part := int(temporary_float_part);
- int_tmp_int_part := Double_to_int(temporary_int_part);
- From_any_to_hex(int_tmp_int_part);
- float_part := frac(temporary_float_part);
- end;
- end;
- function Finish_invoke(): boolean;
- var c: char;
- i: integer;
- flag: boolean = True;
- begin
- for i := 1 to 6 do
- begin
- read(c);
- if (i = 1) and (c <> 'i') then
- begin
- flag := False;
- break;
- end
- else if (i = 2) and (c <> 'n') then
- begin
- flag := False;
- break;
- end
- else if (i = 3) and (c <> 'i') then
- begin
- flag := False;
- break;
- end
- else if (i = 4) and (c <> 's') then
- begin
- flag := False;
- break;
- end
- else if (i = 5) and (c <> 'h') then
- begin
- flag := False;
- break;
- end
- end;
- finish_invoke := flag;
- end;
- begin
- SetExceptionMask(GetExceptionMask + [exOverflow,exZeroDivide,exInvalidOp]);
- total_result := 0.0;
- count_prog_iteration := 0;
- flag_for_char := False;
- flag_for_comments := False;
- flag_base := False;
- digit_cntr := 0;
- cntr_real_part := 0;
- num_part_real := 0;
- flag_for_inappopriate_digit_in_input := False;
- first_it := 0;
- {заполнение массива arr, чтобы получить значение char в 10-й СС}
- arr_add := '1';
- for i := 1 to 9 do
- begin
- arr[i] := arr_add;
- arr_add := succ(arr_add);
- end;
- arr_add := 'a';
- for i := 10 to 15 do
- begin
- arr[i] := arr_add;
- arr_add := succ(arr_add);
- end;
- if ParamCount < 2 then
- begin
- writeln('Неправильные параметры входной строки');
- Halt(0);
- end;
- {преобразование эпсилон в real}
- val(ParamStr(1), epsilon, code);
- if (epsilon > 1) or (epsilon <= 0) then
- begin
- writeln('Неправильные параметры входной строки');
- Halt(0);
- end;
- {проверка введённых СС}
- for i := 2 to ParamCount do
- begin
- val(ParamStr(i), base, code);
- if (base >= 257) or (base <= 1) then
- begin
- writeln('Ошибка');
- Halt(0);
- end;
- end;
- while (not EOF) do
- begin
- intenal_sign := '+';
- {определяем, какой знак получаем на вход}
- repeat
- if EOLn then
- begin
- flag_eoln := True;
- break;
- end;
- read(s);
- if s = 'f' then
- begin
- if Finish_invoke() then flag_for_finish := True
- else flag_for_inappopriate_digit_in_input := True;
- break;
- end;
- if (s <> 'f') and (s <> ';') and (s <> '+') and (s <> '-')
- and (s <> '*') and (s <> '/') and (s <> ' ') then
- begin
- flag_for_inappopriate_digit_in_input := True;
- break;
- end;
- if (s = ';') then
- begin
- flag_for_comments := True;
- break;
- end;
- if (For_first_digit(s)) and (s <> ';') then
- begin
- flag_for_inappopriate_digit_in_input := True;
- break;
- end;
- until ((s = '+') or (s = '-') or (s = '*') or (s = '/'));
- {если флаг остановки поднят, то выходим из цикла}
- if (flag_for_finish) and (count_prog_iteration = 0) then
- begin
- writeln('Программа не выполнена ни разу: строка начинается со слова ''finish''');
- break;
- end;
- {если флаг неправильного первого знака поднят, ломаем программу}
- if (flag_for_inappopriate_digit_in_input)
- and (count_prog_iteration = 0) then
- begin
- writeln('Программа не выполнена ни разу, так как строка начинается не с арифметического знака');
- break;
- end;
- if (flag_for_inappopriate_digit_in_input)
- and (count_prog_iteration <> 0) then
- begin
- writeln('Ошибка: строка начинается не с арифметического знака');
- flag_for_inappopriate_digit_in_input := False;
- break;
- end;
- if (flag_for_comments and EOLn) then
- begin
- flag_eoln := True;
- flag_for_comments := False;
- end;
- if flag_for_finish then
- break;
- if (not flag_for_comments) then
- sign := s;
- {считывание значения сс}
- repeat
- if EOLn then
- begin
- flag_eoln := True;
- break;
- end;
- if flag_eoln then
- break;
- if flag_for_comments then
- begin
- break;
- end;
- read(s);
- first_it := first_it + 1;
- if flag_base and (s = #32) then
- flag_internal_tabs_for_ns := True; //проверка на пробелы после СС
- if flag_base and flag_internal_tabs_for_ns
- and (s <> #32) and (s <> ':') then
- begin
- flag_for_inappopriate_digit_in_input := True;
- break;
- end;
- if (s <> ';') and (not(s in ['0'..'9']))
- and (s <> #32) and (s <> ':') then
- begin
- flag_for_inappopriate_digit_in_input := True;
- break;
- end
- else
- if (s <> #32) and (first_it = 1) then
- begin
- flag_for_space := True;
- break;
- end;
- if (s = ';') and (count_prog_iteration = 0) then
- begin
- writeln('Программа не выполнена ни разу');
- flag_for_comments := True;
- Halt(0);
- end
- else if (s = ';') and (count_prog_iteration <> 0) then
- begin
- writeln('Ошибка! Невозможно считать число по причине комментариев');
- flag_for_comments := True;
- break;
- end;
- if s in ['0'..'9'] then
- begin
- val(s, curr_digit, code);
- if flag_base then
- curr_base := curr_base * 10 + curr_digit
- else
- begin
- curr_base := curr_digit;
- flag_base := True;
- end;
- end;
- until(s = ':');
- if (flag_for_comments and EOLn) then
- begin
- flag_eoln := True;
- flag_for_comments := False;
- end;
- if flag_for_space then
- begin
- writeln('Нет пробела между арифметическим знаком и системой счисления');
- break;
- end;
- if flag_for_inappopriate_digit_in_input
- and (count_prog_iteration = 0) then
- begin
- writeln('Ошибка! Программа не выполнена ни разу!');
- break;
- end;
- if flag_for_inappopriate_digit_in_input
- and (count_prog_iteration <> 0) then
- begin
- writeln('Ошибка!');
- break;
- end;
- if ((curr_base > 256) or (curr_base <= 1)) and
- (not flag_eoln) and (not flag_for_comments) then
- begin
- writeln('Система счисления не удовлетворяет условиям задачи');
- break;
- end;
- {считываем число, а именно целую часть}
- repeat
- if EOLn then
- begin
- flag_eoln := True;
- break;
- end;
- if flag_eoln then
- break;
- if flag_for_comments then
- begin
- break;
- end;
- read(s);
- if (s <> '.') and (s <> #32) and (s <> ';') and (s <> '-') and
- (s <> '+') and (not((s in ['0'..'9']) or (s in ['a'..'f']))) then
- begin
- flag_for_inappopriate_digit_in_input := True;
- break;
- end;
- if (s = ';') and (count_prog_iteration = 0)
- and (flag_for_char) then
- begin
- writeln('Программа не выполнена ни разу');
- Halt(0);
- end;
- if (s = ';') and (not flag_for_char) then
- begin
- flag_for_comments := True;
- break;
- end;
- if (s = ';') and (count_prog_iteration <> 0)
- and (flag_for_char) then
- begin
- flag_for_comments := True;
- writeln('Ошибка: неправильно введены цифры числа#');
- break;
- end;
- if s = '-' then
- intenal_sign := '-';
- if ((s in ['1'..'9']) or (s in ['a'..'f'])) then
- flag_alot_null := False;
- if ((s in ['0'..'9']) or (s in ['a'..'f']))
- and (flag_for_char = False) then
- begin
- curr_digit := Char_to_digit(arr, s, trash);
- flag_for_char := True;
- digit_cntr := digit_cntr + 1;
- end
- else
- begin
- if ((s in ['0'..'9']) or (s in ['a'..'f']))
- and (flag_for_char = True) then
- begin
- curr_digit := curr_digit * 16 + Char_to_digit(arr, s, trash);
- if curr_digit >= curr_base then
- begin
- writeln('Ошибка! Полученная цифра не удовлетворяет данной системе счисления');
- Halt(0);
- end;
- {проверка num - числа на переполнение}
- if ((num * curr_base) + curr_digit) > MAXDOUBLE then
- begin
- writeln('Ошибка! Переполнение!');
- flag_for_oveflow := True;
- break;
- end;
- flag_for_char := False;
- num := num * curr_base + curr_digit;
- curr_digit := 0;
- end;
- end;
- until(s = '.');
- if (flag_for_comments and EOLn) then
- begin
- flag_eoln := True;
- flag_for_comments := False;
- end;
- if flag_alot_null then
- num := 0;
- if flag_for_oveflow then
- break;
- if flag_for_char then
- begin
- if (count_prog_iteration = 0) then
- begin
- writeln('Ошибка! Нечётное число char, нельзя получить отдельные digits');
- Halt(0);
- end;
- end;
- if flag_for_inappopriate_digit_in_input then
- begin
- writeln('Ошибка!');
- break;
- end;
- {далее считываем число после точки}
- repeat
- if EOLn then
- begin
- flag_eoln := True;
- break;
- end;
- if flag_eoln then
- break;
- if flag_for_comments then
- begin
- break;
- end;
- read(s);
- if ((s <> #32) and (s <> ';') and
- (not((s in ['0'..'9']) or (s in ['a'..'f'])))) then
- begin
- flag_for_inappopriate_digit_in_input := True;
- break;
- end;
- if (s = ';') and (count_prog_iteration = 0)
- and (flag_for_char) then
- begin
- writeln('Программа не выполнена ни разу');
- Halt(0);
- end;
- if (s = ';') and (count_prog_iteration = 0)
- and (not flag_for_char) then
- begin
- flag_for_comments := True;
- break;
- end;
- if (s = ';') and (count_prog_iteration <> 0)
- and (flag_for_char) then
- begin
- flag_for_comments := True;
- writeln('Ошибка: неправильно введены цифры числа');
- flag_for_float_part := True;
- break;
- end;
- if (s = ';') and (count_prog_iteration <> 0)
- and (not flag_for_char) then
- begin
- flag_for_comments := True;
- break;
- end;
- if ((s in ['1'..'9']) or (s in ['a'..'f'])) then
- flag_alot_null := False;
- if ((s in ['0'..'9']) or (s in ['a'..'f']))
- and (flag_for_char = False) then
- begin
- curr_digit := Char_to_digit(arr, s, trash);
- flag_for_char := True;
- end
- else begin
- if ((s in ['0'..'9']) or (s in ['a'..'f']))
- and (flag_for_char = True) then
- begin
- curr_digit := curr_digit * 16
- + Char_to_digit(arr, s, trash);
- if curr_digit >= curr_base then
- begin
- writeln('Ошибка! Полученная цифра не удовлетворяет данной системе счисления');
- Halt(0);
- end;
- cntr_real_part := cntr_real_part + 1;
- flag_for_char := False;
- if (Pow(curr_base, cntr_real_part) > MAXDOUBLE)
- and (not flag_alot_null) then
- begin
- writeln('Ошибка! Переполнение!');
- flag_for_oveflow := True;
- break;
- end;
- if (num_part_real + curr_digit /
- Pow(curr_base, cntr_real_part) > MAXDOUBLE)
- and (not flag_alot_null) then
- begin
- flag_for_oveflow := True;
- writeln('Ошибка! Переполнение!');
- break;
- end;
- if flag_alot_null then
- num_part_real := 0
- else num_part_real := num_part_real +
- curr_digit / Pow(curr_base, cntr_real_part);
- end;
- end;
- until(EOLn);
- if (flag_for_comments and EOLn) then
- begin
- flag_eoln := True;
- flag_for_comments := False;
- end;
- if flag_alot_null then
- num_part_real := 0;
- if flag_for_float_part
- then break;
- if flag_for_oveflow then
- break;
- if (flag_for_char = True) then
- begin
- flag_for_char := False;
- if (count_prog_iteration = 0) then
- begin
- writeln('Ошибка!');
- break;
- end;
- end;
- if flag_for_inappopriate_digit_in_input then
- begin
- writeln('Ошибка!##');
- break;
- end;
- if flag_for_comments then Case_comment();
- if num + num_part_real > MAXDOUBLE then
- begin
- writeln('Ошибка! Переполнение!');
- break;
- end
- else num := num + num_part_real;
- count_prog_iteration := count_prog_iteration + 1;
- if intenal_sign = '-' then
- num := num * (-1);
- if sign = '+' then
- begin
- if (total_result + num) > MAXDOUBLE then
- begin
- flag_for_oveflow := True;
- writeln('Ошибка! Переполнение!');
- break;
- end
- else total_result := total_result + num;
- end;
- if (sign = '-') then
- begin
- if (total_result - num) < MINDOUBLE then
- begin
- flag_for_oveflow := True;
- writeln('Ошибка! Переполнение!');
- break;
- end
- else total_result := total_result - num;
- end;
- if (sign = '*') then
- begin
- if (total_result * num) > MAXDOUBLE then
- begin
- flag_for_oveflow := True;
- writeln('Ошибка! Переполнение!');
- break;
- end
- else total_result := total_result * num;
- end;
- if (sign = '/') then
- begin
- if (total_result / num < MINDOUBLE)
- or (total_result / num > MAXDOUBLE)
- or (IsNaN(total_result / num)) then
- begin
- flag_for_oveflow := True;
- writeln('Ошибка!');
- break;
- end
- else if IsInfinite(total_result / num) then
- begin
- flag_for_oveflow := True;
- writeln('Ошибка: Деление на ноль. Невозможно совершить операцию.');
- break;
- end
- else total_result := total_result / num;
- end;
- sign := ' ';
- flag_base := False;
- flag_for_char := False;
- curr_base := 0;
- curr_digit := 0;
- num := 0;
- num_part_real := 0;
- cntr_real_part := 0;
- flag_for_comments := False;
- flag_for_oveflow := False;
- flag_eoln := False;
- flag_for_inappopriate_digit_in_input := False;
- flag_for_space := False;
- first_it := 0;
- flag_internal_tabs_for_ns := False;
- flag_alot_null := True;
- readln();
- end;
- if total_result < 0 then
- begin
- flag_for_total_result := False;
- total_result := total_result * (-1);
- end
- else flag_for_total_result := True;
- {пошёл вывод}
- for i := 2 to ParamCount do
- begin
- val(ParamStr(i), base, code);
- write(base);
- Space_bar(base);
- if flag_for_total_result = False then
- write('-');
- digits_for_e := E_count_digit(base, epsilon);
- Output_with_conversion(digits_for_e, base, total_result);
- writeln;
- end;
- end.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement