练习 3-4 在数的对二的补码表示中,我们编写的itoa函数不能处理最大的负数,即n等于-2^(字长-1)的情况。请解释其原因。修改该函数,使它在任何机器上运行时都能打印出正确的值。
来源:互联网 发布:win10的80端口被占用 编辑:程序博客网 时间:2024/06/08 15:41
在原文中的itoa函数为:
/* itoa: convert n to characters in s */void itoa(int n, char s[]){int i, sign;if ((sign = n) < 0) /* record sign */n = -n; /* make n positive */i = 0;do { /* generate digits in reverse order */s[i++] = n % 10 + '0'; /* get next digit */} while ((n /= 10) > 0); /* delete it */if (sign < 0)s[i++] = '-';s[i] = '\0';reverse(s);}
我们知道,最大负数的二进制形式是10000……,在上面的函数itoa中,对最大负数进行n=-n运算时,只改变其符号位,我们可以看到n将会变成0,这样会得到错误的结果,这种情况下,我们可以将这个最大的负数变为无符号数,即n=(unsigned)n,这样子的话,这个无符号数的绝对值等于原来的最大负数的绝对值。为了解决这个问题,我们需要在最开始的位置对最大的负数进行识别并处理,剩下的程序部分不需要改变,直接照搬就行。
判别最大负数的方法有很多,利用它的特殊性质就可以了。比如,一,如果是负数的话,进行减一处理,得到的差如果大于零,说明他就是最大负数;二将这个最大负数变为无符号数,然后进行左移运算,得到结果为0的话,说明这个数就是最大负数。
#include <stdio.h>#include <limits.h>void itoa1(int n, char s[]);//这是改进后可以将最大负数正常输出的函数void itoa2(int n, char s[]);//这是原文中的函数,在输出最大负数时会出现错误void reverse(char s[]);int main(){ int n=INT_MIN; char s[100]; itoa2(n,s); for(int i=0;s[i]!='\0';++i){ printf("%c",s[i]); } printf("\n"); n=INT_MIN; itoa1(n,s); for(int i=0;s[i]!='\0';++i){ printf("%c",s[i]); } return 0;}void itoa1(int n, char s[]){int i=0;int sign=n;unsigned n_copy;if ((sign=n)<0){ if((n-1)>0){ n_copy=n; }else{ n_copy = -n; }}else{ n_copy=n;}do { s[i++] = n_copy % 10 + '0'; } while ((n_copy /= 10) > 0);if (sign < 0)s[i++] = '-';s[i] = '\0';reverse(s);}void itoa2(int n, char s[]){int i, sign;if ((sign = n) < 0) n = -n; i = 0;do { s[i++] = n % 10 + '0'; } while ((n /= 10) > 0);if (sign < 0)s[i++] = '-';s[i] = '\0';reverse(s);}void reverse(char s[]){ int i; for(i=0;s[i]!='\0';++i){ ; } --i; for(int j=0;i>j;--i,++j){ char temp=s[i]; s[i]=s[j]; s[j]=temp; }}
执行结果如下图所示:
阅读全文
0 0
- 练习 3-4 在数的对二的补码表示中,我们编写的itoa函数不能处理最大的负数,即n等于-2^(字长-1)的情况。请解释其原因。修改该函数,使它在任何机器上运行时都能打印出正确的值。
- 练习3-4 在数的对二的补码表示中,我们编写的itoa函数不能处理最大的负数,修改该函数,使它在任何机器上运行时都能打印出正确的值
- 能处理最小负数的itoa函数
- 练习2-9 在求对二的补码时,表达式 x &= (x - 1) 可以删除 x 中最右边值为 1 的一个二进制位,请解释这样做的道理。用这一方法重写biecount函数,以加快其执行速度。
- 练习 2-9 在求对二的补码时,表达式x &= (x – 1)可以删除x中最右边值为1的一个二进制位。请解释这样做的道理。用这一方法重写bitcount函数,以加快其执行速度。
- 练习 2-9 在求对二的补码时,表达式x &= (x – 1)可以删除x中最右边值为1 的一个二进制位。请解释这样做的道理。用这一方法重写bitcount函数,以加快其执行速度。
- itoa函数,考虑当待处理整数为-2^(字长-1)的情况
- 二进制负数用补码表示的原因
- 二进制负数用补码表示的原因
- 练习2: 打印出所有的"水仙花数",所谓"水仙花数"是指一个三位数,其各位数字立方和等于该数本身。
- 输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示
- 输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。
- Java实现输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。
- 输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。
- 输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。
- 输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。
- 输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。
- 输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。
- 2818: Gcd
- Android Studio Gradle配置详解
- Jekyll博客中加入评论功能和Google分析
- FPGA初始化SD卡及其仿真
- socket.io 中文手册 socket.io 中文文档
- 练习 3-4 在数的对二的补码表示中,我们编写的itoa函数不能处理最大的负数,即n等于-2^(字长-1)的情况。请解释其原因。修改该函数,使它在任何机器上运行时都能打印出正确的值。
- 机器学习实战_初识决策树(ID3)算法_理解其python代码(二)
- JAVA实现http/https的Post、Get、代理访问请求
- CSU-ACM2017暑期训练12-KMP H
- A*算法
- chromedriver_selenium_java2(图片,JavaScript)
- C#使用Dropzone.js上传图片
- Nginx性能优化
- Docker介绍