@@ -369,6 +369,58 @@ template <class _Tp>
369369 }
370370}
371371
372+ // __fp_epsilon
373+
374+ template <__fp_format _Fmt>
375+ [[nodiscard]] _CCCL_API constexpr __fp_storage_t <_Fmt> __fp_epsilon () noexcept
376+ {
377+ using _Storage = __fp_storage_t <_Fmt>;
378+ if constexpr (_Fmt == __fp_format::__fp4_nv_e2m1 || _Fmt == __fp_format::__fp6_nv_e2m3)
379+ {
380+ return _Storage{0x1u };
381+ }
382+ else
383+ {
384+ return static_cast <_Storage>(
385+ (static_cast <_Storage>(__fp_exp_bias_v<_Fmt> + 1 - __fp_digits_v<_Fmt>) << __fp_mant_nbits_v<_Fmt>)
386+ | __fp_explicit_bit_mask_v<_Fmt>);
387+ }
388+ }
389+
390+ template <class _Tp >
391+ [[nodiscard]] _CCCL_API constexpr _Tp __fp_epsilon () noexcept
392+ {
393+ constexpr auto __fmt = __fp_format_of_v<_Tp>;
394+ if constexpr (__fp_is_native_type_v<_Tp> && __fmt == __fp_format::__binary16)
395+ {
396+ return static_cast <_Tp>(0x1p-10 );
397+ }
398+ else if constexpr (__fp_is_native_type_v<_Tp> && __fmt == __fp_format::__binary32)
399+ {
400+ return static_cast <_Tp>(0x1p-23 );
401+ }
402+ else if constexpr (__fp_is_native_type_v<_Tp> && __fmt == __fp_format::__binary64)
403+ {
404+ return static_cast <_Tp>(0x1p-52 );
405+ }
406+ else if constexpr (__fp_is_native_type_v<_Tp> && __fmt == __fp_format::__binary128)
407+ {
408+ return static_cast <_Tp>(0x1p-112 );
409+ }
410+ else if constexpr (__fp_is_native_type_v<_Tp> && __fmt == __fp_format::__fp80_x86)
411+ {
412+ return static_cast <_Tp>(0x8p-66 );
413+ }
414+ else if constexpr (__fp_is_native_type_v<_Tp> && __fmt == __fp_format::__bfloat16)
415+ {
416+ return static_cast <_Tp>(0x1p-7 );
417+ }
418+ else
419+ {
420+ return ::cuda::std::__fp_from_storage<_Tp>(::cuda::std::__fp_epsilon<__fmt>());
421+ }
422+ }
423+
372424_CCCL_END_NAMESPACE_CUDA_STD
373425
374426#include < cuda/std/__cccl/epilogue.h>
0 commit comments