有符号数加减法,存在溢出问题,经常被用于攻击构造。那么如何编写一个可以防止溢出的“正确的”函数呢?

加法运算

错误写法

signed int func(signed int a, signed int b) {return a + b;
}

分析:a与b相加可能溢出(又分为上溢和下溢)
上溢条件:a + b > INT_MAX
下溢条件:a + b < INT_MIN
正确写法

signed int func(signed int a, signed int b)
{if (((b > 0) && (a > INT_MAX - b)) || ((b < 0) && (a < INT_MIN - b))) {/* Handle error */} else {return a + b;}
}

减法运算

错误写法

signed int func(signed int a, signed int b)
{return a - b;
}

正确写法

signed int func(signed int a, signed int b)
{if ((b > 0 && a < INT_MIN + b) ||(b < 0 && a > INT_MAX + b)) {/* Handle error */} else {return a - b;}
}

乘法

错误写法

signed int func(signed int a, signed int b)
{return a * b;
}

正确写法

#include <stddef.h>
#include <assert.h>
#include <limits.h>
#include <inttypes.h>extern size_t popcount(uintmax_t)
#define PRECISION(umax_value) popcount(umax_value)signed int func(signed int a, signed int b)
{signed long long tmp;assert(PRECISION(ULLONG_MAX) >= 2 * PRECISION(UINT_MAX));tmp = (signed long long)a * (signed long long)b;if ((tmp > INT_MAX) || (tmp < INT_MIN)) {/* 处理错误 */} else {return tmp;}
}

除法

错误写法

signed int func(signed int a, signed int b)
{if (b == 0) {/* 处理错误 */} else {return a / b;}
}

正确写法

signed long func(signed long a, signed long b)
{if ((b == 0) || ((a == LONG_MIN) && (b == -1))) {/* 处理错误 */} else {return a / b;}
}

这里这个(a == LONG_MIN) && (b == -1)的条件非常有意思,要理解为什么这种情况下计算会出错,得理解数在计算机中是如何存储的。

取余

错误写法

signed long func(signed long a, signed long b)
{if (b == 0) {/* 错误处理 */} else {return a % b;}
}

正确写法

#include <limits.h>signed long func(signed long a, signed long b)
{if ((b == 0) || ((a == LONG_MIN) && (b == -1))) {/* 错误处理 */} else {return a % b;}
}

如何正确的写加减乘除函数相关推荐

  1. linux 为什么 c语言,为什么C程序里一定要写main函数

    为什么C程序里一定要写main函数 一. 学习过程 编写程序f.c: 对其进行编译,正常通过,再对其进行连接,出现错误: 显示的出错信息为: 翻译成中文是:在c0s模块没有定义符号'_main'. 那 ...

  2. 为什么c程序里一定要写main函数

    一. 学习过程 编写程序f.c: 对其进行编译,正常通过,再对其进行连接,出现错误: 显示的出错信息为: 翻译成中文是:在c0s模块没有定义符号'_main'. 那么这个错误信息可能与文件c0s.ob ...

  3. 如何在matlab sfunction 函数中调用自己写的函数?

    自己编写了一个s函数,有几个参数引用了自己写的几个函数,在脚本中可以正确运行,但在写成s函数,进行 simulink 仿真的时候,已知提示"too many input auguments& ...

  4. 自己动手写 printf函数

    我们在C语言编程中会遇到一些参数个数可变的函数,例如printf() 这个函数,它的定义是这样的: int printf( const char* format, ...); 它除了有一个参数form ...

  5. ACMNO.41C语言-数字调序 有n个整数,使前面各数顺序向后移m个位置,最后m个数变成前面m个数,见图。写一函数:实现以上功能,在主函数中输入n个数和输出调整后的n个数

    题目描述 有n个整数,使前面各数顺序向后移m个位置,最后m个数变成前面m个数,见图. 写一函数:实现以上功能,在主函数中输入n个数和输出调整后的n个数. 输入 输入数据的个数n n个整数 移动的位置m ...

  6. ACMNO.40 C语言-子串 有一字符串,包含n个字符。写一函数,将此字符串中从第m个字符开始的全部字符复制成为另一个字符串

    题目描述 有一字符串,包含n个字符. 写一函数,将此字符串中从第m个字符开始的全部字符复制成为另一个字符串. 输入 数字n 一行字符串 数字m 输出 从m开始的子串 样例输入 6 abcdef 3 样 ...

  7. ACMNO.27 Python的两行代码解决 C语言-字符逆序 写一函数。使输入的一个字符串按反序存放,在主函数中输入输出反序后的字符串。 输入 一行字符 输出 逆序后的字符串

    题目描述 写一函数,使输入的一个字符串按反序存放,在主函数中输入输出反序后的字符串. 输入 一行字符 输出 逆序后的字符串 样例输入 123456abcdef 样例输出 fedcba654321 来源 ...

  8. ACMNO.25 C语言-间隔输出 写一函数,输入一个四位数字,要求输出这四个数字字符,但每两个数字间空格。如输入1990,应输出1 9 9 0。 输入 一个四位数 输出 增加空格输出

    题目描述 写一函数,输入一个四位数字,要求输出这四个数字字符,但每两个数字间空格.如输入1990,应输出"1 9 9 0". 输入 一个四位数 输出 增加空格输出 样例输入 199 ...

  9. ACMNO.24 C语言-转置矩阵 写一个函数,使给定的一个二维数组(3×3)转置,即行列互换。 输入 一个3x3的矩阵 输出 转置后的矩阵 样例

    题目描述 写一个函数,使给定的一个二维数组(3×3)转置,即行列互换. 输入 一个3x3的矩阵 输出 转置后的矩阵 样例输入 1 2 3 4 5 6 7 8 9 样例输出 1 4 7 2 5 8 3 ...

最新文章

  1. 文献记录(part31)--Dynamic relationship identification for abnormality detection on financial time ...
  2. SpringBoot入门到精通_第2篇 _1分钟实战需求项目
  3. Django 博客教程(三):创建应用和编写数据库模型
  4. linux终端美化,如何美化你的命令行终端Terminal
  5. 实现文本超出显示省略号
  6. linux sftp创建多用户,同一台 Centos (Linux)服务器设置多个sftp 账号,并限制用户只能访问指定文件路径...
  7. STANDBY REDO LOG
  8. 软件开发项目成本管理实践
  9. 如何使用Teamtoken工具软件做员工股权激励
  10. 基于Python实现仿Windows标准计算器
  11. 代码 马佳义_武汉大学电子信息学院
  12. java 填数独_java – 数独求解方法
  13. win10自带看图工具找不到了咋办
  14. cupsd进程_CUPS 简介
  15. 刷四百道题总结的24种常用的刷题思路
  16. C语言中负数在计算机内部的二进制表示方式(以补码表示负数、整数的范围及所占字节数)
  17. JavaScript 实现网页截屏五种方法
  18. 编程笔试(解析及代码实现):求和为N的正整数序列之实现一个函数,输入为一个正整数N (比如100),输出为所有和等于N的[连续]正整数序列
  19. 晕菜:新域名在60天内不能转移。
  20. ALSA声卡驱动中的DAPM详解之一:kcontrol

热门文章

  1. 计算机屏幕无信号咋回事,电脑显示屏无信号怎么回事?电脑打不开显示器无信号的解决办法...
  2. python朋友圈数据分析_基于Python的微信朋友圈数据可视化分析之地点
  3. iOS个人整理33-GCD----多线程优化
  4. notoriously 众所周知地;声名狼藉地;恶名昭彰地
  5. 辞职文案火了!程序员的辞职理由要命不要钱。
  6. android 特效UI
  7. 干掉 LaTeX !用BookDown写本书
  8. 2021年中国建筑行业发展概况:建筑业总产值持续增长,未来发展方向明确[图]
  9. iOS11遇到的坑及解决方法
  10. H264和音频流打包成TS流 (MPEG2-TS)