当前位置: 首页 > news >正文

C标准库--C99--控制浮点环境<fenv.h>

文章目录

  • 一、简介
  • 二、浮点异常
  • 三、舍入模式
  • 四、主要函数和宏
    •    浮点异常处理
    •    舍入模式控制
    •    浮点环境控制
  • 五、实例
    •    检测浮点异常和控制舍入模式实例
    •    检测浮点异常实例
    •    控制舍入方向实例
    •    保存和恢复浮点环境实例
    •    临时屏蔽异常实例
    •    精确计算示例实例
    •    异常处理包装器实例
  • 六、注意事项

一、简介

   <fenv.h> 是 C 标准库中的一个头文件,用于控制浮点环境(Floating-Point Environment)。
   <fenv.h> 在 C99 标准中引入,提供了对浮点异常、舍入模式和其他浮点状态的控制和查询功能。
   <fenv.h> 的主要目的是:
      检测和处理浮点异常(如除以零、溢出等)。
      控制浮点运算的舍入模式(如向零舍入、向最近舍入等)。
      查询和修改浮点状态标志。

二、浮点异常

   浮点异常是指在浮点运算中发生的特殊情况,例如:
    在这里插入图片描述

   这些异常通过浮点状态标志来表示,可以通过 <fenv.h> 中的函数检测和处理。

三、舍入模式

   舍入模式控制浮点运算结果的舍入方式。<fenv.h> 定义了以下舍入模式:
    在这里插入图片描述

四、主要函数和宏

   <fenv.h> 提供了一组函数和宏,用于操作浮点环境和处理浮点异常。

   浮点异常处理

    在这里插入图片描述

   舍入模式控制

    在这里插入图片描述

   浮点环境控制

    在这里插入图片描述

五、实例

   检测浮点异常和控制舍入模式实例

		#include <stdio.h>#include <fenv.h>#include <math.h>int main() {// 启用浮点异常检测feclearexcept(FE_ALL_EXCEPT);// 触发除以零异常double x = 1.0, y = 0.0;double z = x / y;// 检测是否发生除以零异常if (fetestexcept(FE_DIVBYZERO)) {printf("Divide by zero exception occurred.\n");}// 设置舍入模式为向零舍入fesetround(FE_TOWARDZERO);// 测试舍入模式double a = 1.5;double b = rint(a); // 舍入到整数printf("Rounding 1.5 toward zero: %.1f\n", b);return 0;}输出结果为:Divide by zero exception occurred.Rounding 1.5 toward zero: 1.0

   检测浮点异常实例

		#include <fenv.h>#include <stdio.h>#include <math.h>#pragma STDC FENV_ACCESS ONvoid check_exceptions() {// 清除所有异常标志feclearexcept(FE_ALL_EXCEPT);// 执行可能引发异常的运算double x = 0.0;double y = 1.0 / x;  // 除零// 检查特定异常if (fetestexcept(FE_DIVBYZERO)) {printf("Division by zero occurred!\n");}// 检查任何异常if (fetestexcept(FE_ALL_EXCEPT)) {printf("At least one floating-point exception occurred\n");}}int main() {check_exceptions();return 0;}

   控制舍入方向实例

		#include <fenv.h>#include <stdio.h>#pragma STDC FENV_ACCESS ONvoid test_rounding(double num) {int modes[] = {FE_TONEAREST, FE_UPWARD, FE_DOWNWARD, FE_TOWARDZERO};const char *names[] = {"Nearest", "Up", "Down", "Toward zero"};for (int i = 0; i < 4; i++) {if (fesetround(modes[i]) == 0) {printf("Rounding %s: %.1f -> %.0f\n",names[i], num, rint(num));}}}int main() {test_rounding(2.5);  // 测试2.5在不同舍入模式下的结果test_rounding(-2.5); // 测试-2.5在不同舍入模式下的结果return 0;}

   保存和恢复浮点环境实例

		#include <fenv.h>#include <stdio.h>#include <math.h>#pragma STDC FENV_ACCESS ONvoid sensitive_calculation() {fenv_t env;// 保存当前环境fegetenv(&env);// 设置严格环境: 捕获所有异常feclearexcept(FE_ALL_EXCEPT);// 执行关键计算double result = sqrt(-1.0);  // 无效操作if (fetestexcept(FE_INVALID)) {printf("Invalid operation detected in sensitive calculation\n");}// 恢复原始环境fesetenv(&env);}int main() {sensitive_calculation();return 0;}

   临时屏蔽异常实例

		#include <fenv.h>#include <stdio.h>#include <math.h>#pragma STDC FENV_ACCESS ONvoid temp_disable_exceptions() {fenv_t env;// 保存环境并临时屏蔽所有异常feholdexcept(&env);// 执行可能产生异常的运算double x = 0.0;double y = 1.0 / x;  // 不会触发异常printf("Division by zero was performed but not reported\n");// 恢复环境并处理之前发生的异常feupdateenv(&env);// 现在可以检查异常if (fetestexcept(FE_DIVBYZERO)) {printf("Division by zero was detected after restoring environment\n");}}int main() {temp_disable_exceptions();return 0;}

   精确计算示例实例

		#include <fenv.h>#include <stdio.h>#include <math.h>#pragma STDC FENV_ACCESS ONdouble precise_sum(double a, double b) {int original_round = fegetround();fenv_t env;// 保存环境并设置最高精度模式fegetenv(&env);fesetround(FE_TONEAREST);feclearexcept(FE_ALL_EXCEPT);double result = a + b;// 检查计算是否精确if (fetestexcept(FE_INEXACT)) {printf("Warning: Sum was not exact, possible precision loss\n");}// 恢复原始环境fesetround(original_round);fesetenv(&env);return result;}int main() {double a = 1.0 / 3.0;double b = 2.0 / 3.0;printf("Sum: %.17g\n", precise_sum(a, b));return 0;}

   异常处理包装器实例

		#include <fenv.h>#include <stdio.h>#include <math.h>#pragma STDC FENV_ACCESS ONtypedef double (*math_func)(double);double safe_math(math_func f, double x, int *error) {fenv_t env;*error = 0;feclearexcept(FE_ALL_EXCEPT);fegetenv(&env);double result = f(x);int exceptions = fetestexcept(FE_ALL_EXCEPT);if (exceptions) {*error = exceptions;if (exceptions & FE_INVALID) printf("Invalid operation\n");if (exceptions & FE_DIVBYZERO) printf("Division by zero\n");if (exceptions & FE_OVERFLOW) printf("Overflow\n");if (exceptions & FE_UNDERFLOW) printf("Underflow\n");if (exceptions & FE_INEXACT) printf("Inexact result\n");}fesetenv(&env);return result;}int main() {int error;double a = safe_math(sqrt, -1.0, &error);printf("sqrt(-1) = %f (error: %d)\n", a, error);double b = safe_math(log, 0.0, &error);printf("log(0) = %f (error: %d)\n", b, error);return 0;}

六、注意事项

   使用浮点环境功能前通常需要启用 #pragma STDC FENV_ACCESS ON,以告知编译器不要优化掉浮点环境操作并非所有实现都支持全部功能,使用前应检查宏 FE_DFL_ENV 是否定义<fenv.h> 仅在 C99 及更高版本中可用。

   浮点异常检测和舍入模式控制的具体行为可能依赖于硬件和编译器实现。
   在某些平台上,浮点异常可能默认被屏蔽,需要通过 feenableexcept 等函数显式启用。
   浮点环境操作可能会影响性能,应谨慎使用。
   <fenv.h> 提供了对浮点环境的控制功能,包括浮点异常的检测和处理、舍入模式的设置以及浮点状态的查询和修改。
   它是进行高精度浮点计算和调试浮点问题的强大工具,特别适用于科学计算和工程应用。
通过使用 <fenv.h>,开发者可以更好地控制浮点运算的行为,确保计算结果的准确性和可靠性。

http://www.dtcms.com/a/507251.html

相关文章:

  • 【Linux】“ 权限 “ 与相关指令
  • webrtc弱网-ReceiveSideCongestionController类源码分析及算法原理
  • 通达信--主题投资分析
  • 揭阳专业做网站天台县建设规划局网站
  • 福海网站制作关键词堆砌的作弊网站
  • sql特训
  • LeetCode 刷题【126. 单词接龙 II】
  • 防火墙规则设置
  • 江协科技STM32课程笔记(五)— ADC模数转换器
  • 什么是慢查询,慢请求,以及如何避免
  • 网站设计模板简约福州网站设计
  • 各大网站做推广广告什么是企业形象设计
  • 大模型金融量化比赛
  • Kubernetes深入学习之容器入门(一)
  • Docker安装部署MrDoc觅思文档-免费的国产知识库管理系统
  • 批量更新操作全攻略:从JDBC原理到多框架实现(MyBatis/MyBatis-Plus/Nutz)
  • 简述:普瑞时空数据建库软件(国土变更建库)之一(2025年部分新规则)
  • 零基础新手小白快速了解掌握服务集群与自动化运维(十二)Python编程之面向对象
  • 刚学做网站怎么划算普洱专业企业网站建设
  • Java基础——面向对象复习知识点12
  • IPv6路由技术
  • 网站建设开票开什么内容电脑禁止访问网站设置
  • WPeChatGPT 插件使用教程(转载)
  • 从 Sora 到 Sora 2:文本生成视频进入下一个阶段(附sora教程)
  • k8s(十二)Rancher详解
  • 4. 前馈网络(FeedForward):给每个词“做深度加工”
  • wordpress一步步建企业网站上海有名的广告设计公司
  • 百度搜索站长平台汽车网站建设目的
  • EDA--三井物产商品预测挑战赛 Exploratory Data Analysis(探索性数据分析)
  • 【云计算专题会议】第二届云计算与大数据国际学术会议(ICCBD 2025)