Упражнение 3.4 K&R - C (СИ)
Формулировка задачи:
Дана функция:
поглядел видосы про доп код, понял что проблема в смещении бита знакового за пределы битовой сетки.
ну, и, правильно ли я понимаю что достаточно использовать тип double для принимаемого значения n, и там оно само приведется все по типам и заработает?
/* itoa: преобразование n в строку s */ void itoa (int n, char s[]) { int i, sign; if ((sign = n) < 0) /* сохраняем знак */ n = -n; /* делаем n положительным */ i = 0; do { /* генерируем цифры в обратном порядке */ s[i++] = n % 10 + '0'; /* следующая цифра */ } while ((n /= 10) > 0); /* исключить ее */ if (sign < 0) s[i++] = '-'; s[i] = '\0'; reverse(s); }
При условии, что для представления чисел используется дополнительный код, наша версия itoa не справляется с самым большим по модулю отрицательным числом, значение которого равняется -(2^n-1), где n — размер слова. Объясните, чем это вызвано. Модифицируйте программу таким образом, чтобы она давала правильное значение указанного числа независимо от машины, на которой выполняется.
Решение задачи: «Упражнение 3.4 K&R»
textual
Листинг программы
#include <stdio.h> #include <math.h> #define MAX 100 void itoa (int n, char s[]); void reverse (char s[]); int main (){ char s[MAX] = ""; int n; printf("Введите число: "); scanf("%d", &n); itoa (n,s); printf("%s \n", s); return 0; } /* itoa: преобразование n в строку s */ void itoa (int n, char s[]) { int i=0; int sign; if ((sign = n) > 0) /* если положительное */ n -= (n+n); /* делаем отрицательным */ do { /* генерируем цифры в обратном порядке */ s[i++] = abs(n%10)+'0'; /* следующая цифра */ } while (n /= 10); /* исключить ее */ if (sign < 0) s[i++] = '-'; s[i] = '\0'; reverse(s); } void reverse (char s[]) { int i, j; int temp; for (j = 0; s[j] != '\0'; ++j) /* Получаем размер массива */ ; for (i = 0, j--; i < j; i++, j--){ temp = s[i]; s[i] = s[j]; s[j] = temp; } }
Объяснение кода листинга программы
- Объединение двух строк с помощью оператора
+
происходит в функцииitoa
при генерации цифр в обратном порядке. - В функции
main
используется функцияscanf
для ввода целого числа в переменнуюn
. - Функция
itoa
вызывается в функцииmain
для преобразования числаn
в строкуs
. - В функции
itoa
используется циклdo-while
для генерации цифр в обратном порядке. - В функции
itoa
используется оператор/= 10
для деления числаn
на 10 и получения следующей цифры. - В функции
itoa
используется функцияabs
для получения абсолютного значения числаn
. - В функции
itoa
используется функцияreverse
для переворота строкиs
. - В функции
reverse
используется циклfor
для получения размера строкиs
. - В функции
reverse
используется временная переменнаяtemp
для обмена символами в строкеs
. - В функции
main
выводится строкаs
с помощью функцииprintf
. - В функции
main
используется функцияscanf
для ввода числа. - В функции
main
вызывается функцияitoa
для преобразования числа в строку. - В функции
main
выводится строкаs
с помощью функцииprintf
. - В функции
main
возвращается значение 0, что означает успешный конец работы программы. - В функции
itoa
используется переменнаяsign
для хранения знака числаn
. - В функции
itoa
используется оператор%
для получения остатка от деления числаn
на 10. - В функции
itoa
используется функцияabs
для получения абсолютного значения числаn
. - В функции
itoa
используется переменнаяi
для хранения индекса текущей цифры в строкеs
. - В функции
itoa
используется переменнаяj
для хранения индекса последней цифры в строкеs
. - В функции
reverse
используется переменнаяtemp
для обмена символами в строкеs
.
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д