From 0c7cf6f6d3a85c6a5cda60d8840b3a0660eeb64d Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Wed, 21 Feb 2024 19:55:16 +0100 Subject: [PATCH] Implement RtlInfiniteDouble() and RtlNanDouble() routines --- xtoskrnl/includes/rtli.h | 8 +++++ xtoskrnl/rtl/math.c | 68 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 76 insertions(+) diff --git a/xtoskrnl/includes/rtli.h b/xtoskrnl/includes/rtli.h index d6f12a7f..bd5fd51a 100644 --- a/xtoskrnl/includes/rtli.h +++ b/xtoskrnl/includes/rtli.h @@ -260,6 +260,10 @@ LONG RtlGetBaseExponent(IN DOUBLE Value, OUT PDOUBLE PowerOfTen); +XTCDECL +BOOLEAN +RtlInfiniteDouble(IN DOUBLE Value); + XTCDECL VOID RtlInitializeListHead(IN PLIST_ENTRY ListHead); @@ -286,6 +290,10 @@ XTCDECL BOOLEAN RtlListLoop(IN PLIST_ENTRY ListHead); +XTCDECL +BOOLEAN +RtlNanDouble(IN DOUBLE Value); + XTCDECL VOID RtlRemoveEntryList(IN PLIST_ENTRY Entry); diff --git a/xtoskrnl/rtl/math.c b/xtoskrnl/rtl/math.c index 37944d05..6261e93b 100644 --- a/xtoskrnl/rtl/math.c +++ b/xtoskrnl/rtl/math.c @@ -600,6 +600,40 @@ RtlGetBaseExponent(IN DOUBLE Value, return Exponent; } +/** + * Determines whether a floating-point number is infinite. + * + * @param Value + * Supplies the floating-point value to test. + * + * @return This routine returns TRUE if the argument is infinite or a NaN, or FALSE otherwise. + * + * @since XT 1.0 + */ +XTCDECL +BOOLEAN +RtlInfiniteDouble(IN DOUBLE Value) +{ + /* DOUBLE argument in IEEE 754 standard format */ + union + { + PDOUBLE Double; + struct + { + UINT MantissaLow:32; + UINT MantissaHigh:20; + UINT Exponent:11; + UINT Sign:1; + } *DoubleS; + } Var; + + /* Convert input double value to IEEE 754 format */ + Var.Double = &Value; + + /* Return TRUE if it is infinite, or FALSE otherwise */ + return ((Var.DoubleS->Exponent & 0x7FF) == 0x7FF); +} + /** * Multiplies a signed large integer by a signed integer. * @@ -624,3 +658,37 @@ RtlMultiplyLargeInteger(IN LARGE_INTEGER Multiplicand, LargeInt.QuadPart = (LONGLONG) Multiplicand.QuadPart * Multiplier; return LargeInt; } + +/** + * Determines whether a floating-point number is a NaN ("Not a Number"). + * + * @param Value + * Supplies the floating-point value to test. + * + * @return This routine returns TRUE if the argument is a NaN, or FALSE otherwise. + * + * @since XT 1.0 + */ +XTCDECL +BOOLEAN +RtlNanDouble(IN DOUBLE Value) +{ + /* DOUBLE argument in IEEE 754 standard format */ + union + { + PDOUBLE Double; + struct + { + UINT MantissaLow:32; + UINT MantissaHigh:20; + UINT Exponent:11; + UINT Sign:1; + } *DoubleS; + } Var; + + /* Convert input double value to IEEE 754 format */ + Var.Double = &Value; + + /* Return TRUE if it is NaN, or FALSE otherwise */ + return (Var.DoubleS->Exponent == 0x7FF && (Var.DoubleS->MantissaHigh != 0 || Var.DoubleS->MantissaLow != 0)); +}