如何解决我可以将 NULL 传递给 modf/modff 吗?
modf()
family of functions 都带一个指针参数:
float modff( float arg,float* iptr );
double modf( double arg,double* iptr );
long double modfl( long double arg,long double* iptr );
用于返回其输入 arg
的整数部分(小数部分是实际返回值)。
如果我只需要小数部分,我可以通过传递NULL
来“跳过”整数部分的计算吗?
我喜欢的 cppreference 页面和 man modff
都没有说明当您为 NULL
传递 iptr
时会发生什么,而其他一些标准库函数将 NULL 作为“忽略此参数”。
解决方法
standard 没有定义这个
说明
2 modf 函数将参数值分解为整数部分和小数部分,每个部分与参数具有相同的类型和符号。它们将整数部分(以浮点格式)存储在 iptr 指向的对象中。
退货
3 modf 函数返回值的有符号小数部分。
因此传递 NULL
时的行为将是未定义的。您可能会找到一些允许它的编译器,但任何依赖于此的代码都无法移植(即使在同一编译器的版本之间)。
根据ISO/IEC 9899:2017草案:
F.10.3.12 modf 函数
...
...
3 modf 的行为就像是由
实现的 #include<math.h>
#include<fenv.h>
#pragma STDC FENV_ACCESS ON
double modf(doublevalue,double*iptr){
intsave_round =fegetround();
fesetround(FE_TOWARDZERO);
*iptr =nearbyint(value);
fesetround(save_round);
return copysign(isinf(value) ? 0.0:value - (*iptr),value);
}
所以,我会说你不能。
,正如其他人的回答所暗示的那样,您无法通过 NULL
- 或者至少,您不能依赖能够通过 NULL
。
相反,请使用以下内容:
inline float fractional_part_float( float arg ) {
float integral_part;
return modff(arg,&integral_part);
}
对于 double
和 long double
也类似。
我可以将 NULL 传递给 modf/modff 吗?
modf(double arg,double* iptr)
和朋友在 iptr == NULL
时缺乏定义的功能。传递 NULL
是未定义行为 (UB)。
如果代码需要一个不需要保存整数部分供以后使用的单行代码,请考虑使用 复合字面量作为临时 double
并相信编译器能够进行优化。
#include <math.h>
double fraction(double x) {
return modf(x,&(double){0});
}
,
手册页没有提到这种使用函数的方式,如果我们查看 glibc 实现,它肯定没有处理这种情况:
https://code.woboq.org/userspace/glibc/sysdeps/ieee754/dbl-64/wordsize-64/s_modf.c.html
所以不,这不是你可以合法做的事情。
此外,C99 关于 modf 的全部内容是:
modf 函数将参数值分解为整数和 小数部分,每个部分都具有相同的类型和符号 争论。它们将整数部分(以浮点格式)存储在 iptr 指向的对象。
所以 glibc 的实现完全符合标准。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。