我可以将 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);
}

对于 doublelong 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 的实现完全符合标准。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...