简体   繁体   English

我可以将 NULL 传递给 modf/modff 吗?

[英]Can I pass NULL to modf/modff?

The modf() family of functions all take a pointer parameter: modf()系列函数都带有一个指针参数:

float       modff( float arg, float* iptr );
double      modf( double arg, double* iptr );
long double modfl( long double arg, long double* iptr );

for returning the integral part of their input arg (the fractional part is the actual return value).用于返回其输入arg的整数部分(小数部分是实际返回值)。

If I only need the fractional part, can I "skip" the computation of the integral part by passing NULL ?如果我只需要小数部分,我可以通过传递NULL “跳过”整数部分的计算吗?

Neither the cppreference page I liked to, nor man modff , say anything about what happens when you pass NULL for iptr , while some other standard library functions take NULL as an indication of "ignore this parameter".我喜欢的 cppreference 页面和man modff都没有说明当您将NULL传递给iptr时会发生什么,而其他一些标准库函数将 NULL 用作“忽略此参数”的指示。

The standard doesn't define this标准没有定义这个

Description描述

2 The modf functions break the argument value into integral and fractional parts, each of which has the same type and sign as the argument. 2 modf 函数将参数值分解为整数和小数部分,每个部分都具有与参数相同的类型和符号。 They store the integral part (in floating-point format) in the object pointed to by iptr.它们将整数部分(以浮点格式)存储在 iptr 指向的 object 中。

Returns退货

3 The modf functions return the signed fractional part of value. 3 modf 函数返回值的有符号小数部分。

so behaviour when passing NULL will be undefined.因此传递NULL时的行为将是未定义的。 You may find some compiler which allows it but any code relying on this would not be portable (even between versions of the same compiler).您可能会发现一些允许它的编译器,但任何依赖于此的代码都不可移植(即使在同一编译器的版本之间)。

According to the ISO/IEC 9899:2017 draft:根据ISO/IEC 9899:2017草案:

F.10.3.12 The modf functions F.10.3.12 modf 函数

... ...

... ...

3 modf behaves as though implemented by 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);
    }

So, I would say that you can't.所以,我会说你不能。

As others answers suggest, you can't pass NULL - or at least, you can't rely on being able to pass NULL .正如其他答案所暗示的那样,您不能通过NULL - 或者至少,您不能依赖能够通过NULL

Instead, use something like this:相反,使用这样的东西:

inline float fractional_part_float( float arg ) {
    float integral_part;
    return modff(arg, &integral_part);
}

and similarly for double and long double .同样对于doublelong double

Can I pass NULL to modf/modff?我可以将 NULL 传递给 modf/modff 吗?

modf(double arg, double* iptr) and friends lack defined functionality when iptr == NULL . modf(double arg, double* iptr)和朋友在iptr == NULL时缺少定义的功能。 Passing a NULL is undefined behavior (UB).传递NULL未定义的行为(UB)。

If code wants a one liner that does not need to save the integer part for later use, consider a compound literal for the temporary double and trust the compiler to optimize as able.如果代码需要一个不需要保存 integer 部分供以后使用的单行,请考虑为临时double精度值使用复合文字,并相信编译器会尽可能优化。

#include <math.h>

double fraction(double x) {
  return modf(x, &(double){0});
}

Man pages do not mention this way of using the function and if we look at the glibc implementation, it definitely doesn't have handling for that case:手册页没有提到这种使用 function 的方式,如果我们查看 glibc 实现,它肯定没有处理这种情况:

https://code.woboq.org/userspace/glibc/sysdeps/ieee754/dbl-64/wordsize-64/s_modf.c.html https://code.woboq.org/userspace/glibc/sysdeps/ieee754/dbl-64/wordsize-64/s_modf.c.ZFC35FDC7830D5FC69D2E3629

So no, that's not a thing you can legally do.所以不,这不是你可以合法做的事情。

Also all that C99 has to say about modf is:此外,C99 对 modf 的评价是:

The modf functions break the argument value into integral and fractional parts, each of which has the same type and sign as the argument. modf 函数将参数值分解为整数和小数部分,每个部分都具有与参数相同的类型和符号。 They store the integral part (in floating-point format) in the object pointed to by iptr.它们将整数部分(以浮点格式)存储在 iptr 指向的 object 中。

so the glibc implementation is perfectly fine in its conformance to the standard.所以 glibc 的实现完全符合标准。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM