C语言浮点函数中的modf和fmod详解

modf函数可以提取出浮点数的整数部分和小数部分。fmod函数可以返回两个浮点数相除的余数。它们的函数原型如下:

  double __cdecl modf(double _X,double *_Y);
  double __cdecl fmod(double _X,double _Y);

这两个函数的功能看起来都挺简单的,但是为什么在C语言库中还要专门搞一个函数来计算呢?在使用这两个函数之前,首先看一个简单的浮点数相关的例子。

int main ()
{
	int i;
	float j=1.0;

	for(i=0; i<100; i++)
	{
		j+=0.1;
		printf("%f \n",j);
	}
	return(0);
}

给一个浮点数1.0每次累加0.1,总共累加100,感觉就是一个简单的加法运算,它的输出结果肯定也知道是什么了,下面来运行一下这个代码,输出结果如下:

看到结果的第一眼,是不是感觉计算机算错了?怎么算着算着结果还给跑偏了。其实计算机并没有算错,程序运行的结果也是正确的。这里使用一个在线浮点数转换工具验证一下。

首先看一下浮点数1.0在内存的存储情况。

再看一下浮点数2.8在内存的存储情况。

通过对比可以看出1.0的实际存储值是1,和真实值是一样的。2.8的实际存储值是2.7999999523162841796875,和真实值已经产生了一点误差。那么这个误差是什么引起的呢?这里就要从浮点数的存储原理说起了。

通在C语言中,一个浮点数占32位,其中第一位表示符号位,0表示正数,1表示负数。紧接着8位表示指数部分,也就是系统会将浮点数表示为指数计数法,这8位就是指数部分的值,但是这里的指数是以2为底的。剩下的23位表示的就是尾数,也就是有效数据。

由于小数部分都是通过 2^a+2^b+2^c.......2^n 这种指数的累加来实现的,而指数的累加不一定可以百分百的等于原值,它只可能无限的接近原值。所以对于浮点数的操作不是像整数那样简单,为了保证操作浮点数时的精度,所以C语言的库函数才给我们提供了这两种浮点数操作的函数,方便使用。

接下来看一下modf函数的用法。

#include <stdio.h>
#include <math.h>

int main ()
{
	double x, fractpart, intpart;

	x = 8.123456;
	fractpart = modf(x, &intpart);

	printf("整数部分= %lf\n", intpart);
	printf("小数部分 = %lf \n", fractpart);

	return(0);
}

modf函数有两个参数,第一个参数时待操作的浮点数,第二个参数用来存储浮点数的整数部分,它的返回值是浮点数的小数部分。

通过输出结果可以看到,浮点数的整数部分和小数部分精度都没有丢失。

再看一下fmod函数的用法。

#include <stdio.h>
#include <math.h>

int main ()
{
   float a, b;
   int c;
   a = 9.0;
   b = 3.7;
   c = 2;

   printf("%f / %f 的余数是 %lf\n", a, b, fmod(a,b));
   printf("%f / %d 的余数是 %lf\n", a, c, fmod(a,c));

	return(0);
}

fmod函数有两个参数,第一个参数是分子,第二个参数是分母,它返回第一个参数除以第二个参数的余数。

通过输出的结果可以看到,浮点数的精度没有丢失。

总结

本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注我们的更多内容!

(0)

相关推荐

  • PHP中round()函数对浮点数进行四舍五入的方法

    本文实例讲述了PHP中round()函数对浮点数进行四舍五入的方法.分享给大家供大家参考.具体方法如下: 语法:round(x,prec) 参数 描述 x 可选,规定要舍入的数字. prec 可选,规定小数点后的位数. 说明:返回将 x 根据指定精度 prec(十进制小数点后数字的数目)进行四舍五入的结果,prec 也可以是负数或零(默认值). 提示和注释 注释:php默认不能正确处理类似 "12,300.2" 的字符串. 注释:prec 参数是在 php 4 中被引入的,实例代码如下

  • 解决Python中的modf()函数取小数部分不准确问题

    使用math.modf()对一个浮点数进行拆分时经常会遇到如下情况 如下 import math print(math.modf(2.4)) # 输出 (0.3999999999999999, 2.0) 我们会发现对2.4进行拆分得到的小数并不是0.4,这是因为什么呢? 这是因为计算机采用的是二进制代码,而二进制代码由于计算上的误差无法准确表示某些十进制数的小数部分. 下面我们具体来讲一下. 我们知道一个十进制数转化为二进制数需要分为两部分进行计算:整数部分和小数部分. 整数部分采用"除二取余法

  • Python字符串转换成浮点数函数分享

    利用map和reduce编写一个str2float函数,把字符串'123.456'转换成浮点数123.456 from functools import reduce def str2float(s): return reduce(lambda x,y:x+int2dec(y),map(str2int,s.split('.'))) def char2num(s): return {'0':0,'1':1,'2':2,'3':3,'4':4,'5':5,'6':6,'7':7,'8':8,'9':

  • js判断输入是否为正整数、浮点数等数字的函数代码

    1.下面列出了一些判读数值类型的正则表达式 复制代码 代码如下: /^\d+$/ //非负整数(正整数 + 0) /^[0-9]*[1-9][0-9]*$/ //正整数 /^((-\d+)|(0+))$/ //非正整数(负整数 + 0) /^-[0-9]*[1-9][0-9]*$/ //负整数 /^-?\d+$/ //整数 /^\d+(\.\d+)?$/ //非负浮点数(正浮点数 + 0) /^(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0

  • C语言实现字符串转浮点函数的示例

      字符串不仅可以转换为整数,也可以转换为浮点数,字符串转浮点数函数原型如下: float __cdecl __mingw_strtof (const char * __restrict__, char ** __restrict__); double __cdecl __mingw_strtod (const char * __restrict__, char ** __restrict__);   strtof函数返回值是一个单精度浮点数,strtod返回值是一个双精度浮点数.   首先来看

  • php的sprintf函数的用法 控制浮点数格式

    控制浮点数打印格式 浮点数的打印和格式控制是sprintf 的一大常用功能,浮点数使用格式符"%f"控制,默认保留小数点后6 位数字,比如: 复制代码 代码如下: sprintf("%f", 3.1415926); //结果:"3.141593" 但,有时我们希望自己控制打印的宽度和小数位数,这时就应该使用:"%m.nf"格式,其中m 表示打印数字的整体宽度,n 表示小数点后的位数.比如: 复制代码 代码如下: sprintf

  • C语言浮点函数中的modf和fmod详解

    modf函数可以提取出浮点数的整数部分和小数部分.fmod函数可以返回两个浮点数相除的余数.它们的函数原型如下: double __cdecl modf(double _X,double *_Y); double __cdecl fmod(double _X,double _Y); 这两个函数的功能看起来都挺简单的,但是为什么在C语言库中还要专门搞一个函数来计算呢?在使用这两个函数之前,首先看一个简单的浮点数相关的例子. int main () { int i; float j=1.0; for

  • JS函数(普通函数,箭头函数)中this的指向问题详解

    目录 普通函数 箭头函数 普通函数 具名普通函数.匿名普通函数,在不作为对象的属性值的情况下,其内部的 this 总是指向代码运行环境下的全局对象 ( 例如,浏览器中的 window ). 示例: (function() { console.log(this); // window (function() { console.log(this); // window (function() { console.log(this); // window })() })() })() 普通函数,均可

  • C语言字符串函数操作(strlen,strcpy,strcat,strcmp)详解

    目录 一.strlen函数模拟 二. strcpy函数模拟 三.strcat函数模拟 四.strcmp函数模拟 总结 一.strlen函数模拟 字符串以‘\0’作为结束标志,strlen函数返回的是在字符串中‘\0’前面出现的字符个数(不包括‘\0’); 有三种方法可以实现该操作: ①计数器方式 ②不能创建临时变量计数器 ③指针-指针 方法一:计数器方式 int my_strlen(const char* str) { int count = 0;//定义count用来记录字符串数组中字符数 w

  • Python函数中的可变长参数详解

    一.Python函数中的参数 1.使用python的函数时,有参数类别,比如位置参数.关键字参数.可变长参数 2.位置参数.关键字参数很好理解,关键是可变长参数经常能见到,但是一直没有搞懂是什么意思 二.可变长参数 1.一个星号:函数可以接收任意个数的参数,只需要在形参前面加一个*(星号),一个星号形参的函数会把多个位置参数值当成元祖的形式传入,也就是传入的多个参数值可以在函数内部进行元祖遍历 def length_param(a, *args): print("a=", a) pri

  • JavaScript this在函数中的指向及实例详解

    一.this,其实可以类比成人 说到this的话,我们在js中主要研究的都是函数中的this,在javascript中,this代表当前行为的执行主体,而context代表的是当前行为执行的的环境(区域). 例如男神在北理珠吃饭,这句话分别代表的含义如下 男神 -->> 主体(this) 吃饭 -->> 函数(function) 北理珠 -->> 环境(context) -->>说明:吃饭是函数,男神是函数的主体,北理珠就是当前行为的执行环境(context

  • C语言main函数的三种形式实例详解

    在C语言中,main()函数有三种形式. 1.无参数 #include <stdio.h> int main(void) { printf("Hello World!\n"); return 0; } 2.有两个参数 习惯上第一个参数是整型argc,保存了外部调用命令的参数个数,第二个参数是指针数组或二级指针argv,以字符串形式保存了与argc对应的参数,如下例子: #include <stdio.h> int main(int argc, char* arg

  • python numpy函数中的linspace创建等差数列详解

    前言 本文主要给大家介绍的是关于linspace创建等差数列的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧. numpy.linspace 是用于创建一个由等差数列构成的一维数组.它最长用的有三个参数,当然不止三个. 第一个例子,用到三个参数,第一个参数表示起始点.第二个参数表示终止点,第三个参数表示数列的个数. import numpy as np print(np.linspace(1,10,10,endpoint=False)) 创建一个元素全部为1的等差数列,

  • C语言中函数参数的入栈顺序详解及实例

    C语言中函数参数的入栈顺序详解及实例 对技术执着的人,比如说我,往往对一些问题,不仅想做到"知其然",还想做到"知其所以然".C语言可谓博大精深,即使我已经有多年的开发经验,可还是有许多问题不知其所以然.某天某地某人问我,C语言中函数参数的入栈顺序如何?从右至左,我随口回答.为什么是从右至左呢?我终究没有给出合理的解释.于是,只好做了个作业,于是有了这篇小博文. #include void foo(int x, int y, int z) { printf(&quo

  • Kotlin 语言中调用 JavaScript 方法实例详解

    Kotlin 语言中调用 JavaScript 方法实例详解 Kotlin 已被设计为能够与 Java 平台轻松互操作.它将 Java 类视为 Kotlin 类,并且 Java 也将 Kotlin 类视为 Java 类.但是,JavaScript 是一种动态类型语言,这意味着它不会在编译期检查类型.你可以通过动态类型在 Kotlin 中自由地与 JavaScript 交流,但是如果你想要 Kotlin 类型系统的全部威力 ,你可以为 JavaScript 库创建 Kotlin 头文件. 内联 J

  • C语言中强制地址跳转详解

    C语言中强制地址跳转详解 #define jump(TargetAddr ) (*((void(*)())(TargetAddr))() 第一个(( void( * )(  )) ,意思为强制类型转换为一个无形参,无返回值的函数指针,(*(TargetAddr))为跳转地址,但是函数指针变量不能为常数所以要加((void( * )(  )) 进行强制类型转换.最后一个()为执行的意思. 整一条指定的目的是为了跳转到一个绝对地址执行函数. 1.在单片机中可以实现软件复位,比如跳转到0地址. 2.如

随机推荐