Home > database >  What is CGFloat.leastNonzeroMagnitude equivalent in Obj-C
What is CGFloat.leastNonzeroMagnitude equivalent in Obj-C

Time:08-31

What is the equivalent of CGFloat.leastNonzeroMagnitude equivalent in Objective-C? I googled but could not find any answer.

CodePudding user response:

Note that the documentation of leastNonzeroMagnitude says:

Compares less than or equal to all positive numbers, but greater than zero. If the target supports subnormal values, this is smaller than leastNormalMagnitude; otherwise they are equal.

So the value of this also depends on "if the target supports subnormal values". Looking at the implementation, we can see:

public static var leastNonzeroMagnitude: ${Self} {
#if arch(arm)
  // On 32b arm, the default FPCR has subnormals flushed to zero.
  return leastNormalMagnitude
#else
  return leastNormalMagnitude * ulpOfOne
#endif
}

It turns out that ARM is the target that doesn't "support subnormal values". :)

If you translate the two branches into Objective-C separately, it would be:

CGFLOAT_MIN

and

CGFLOAT_MIN * CGFLOAT_EPSILON

CodePudding user response:

Apple doesn't provide an Objective-C constant equivalent to CGFloat.leastNonzeroMagnitude.

Apple does provide CGFLOAT_MIN, which is the smallest positive normal nonzero value. It's equivalent to CGFloat.leastNormalMagnitude. This is 2.225073858507201e-308 on systems with 64-bit CGFloat.

There are constants (specified by the C11 standard) for the smallest positive non-zero float and double, including subnormals: FLT_TRUE_MIN is 1.401298e-45 and DBL_TRUE_MIN is 4.940656458412465e-324.

Apple provides a constant CGFLOAT_IS_DOUBLE which is 1 if CGFloat is double and zero if it is float. So you can check that to define your own CGFLOAT_TRUE_MIN. You should also guard against Apple adding its own definition in the future.

#ifndef CGFLOAT_TRUE_MIN
#if CGFLOAT_IS_DOUBLE
#define CGFLOAT_TRUE_MIN DBL_TRUE_MIN
#else
#define CGFLOAT_TRUE_MIN FLT_TRUE_MIN
#endif
#endif

But the only supported platform that still uses 32-bit CGFloat is watchOS, and its unlikely that you're targeting watchOS if you're using Objective-C. If you are only targeting 64-bit versions of iOS/macOS/tvOS, you can simplify the definition:

#ifndef CGFLOAT_TRUE_MIN
#define CGFLOAT_TRUE_MIN DBL_TRUE_MIN
#endif
  • Related