VirtualBox

source: vbox/trunk/src/VBox/Runtime/common/math/frexpl.cpp@ 96298

Last change on this file since 96298 was 96298, checked in by vboxsync, 3 years ago

IPRT/nocrt: Implemented frexp, frexpf and frexpl. bugref:10261

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 4.7 KB
Line 
1/* $Id: frexpl.cpp 96298 2022-08-18 14:28:28Z vboxsync $ */
2/** @file
3 * IPRT - No-CRT - frexpl().
4 */
5
6/*
7 * Copyright (C) 2022 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 *
17 * The contents of this file may alternatively be used under the terms
18 * of the Common Development and Distribution License Version 1.0
19 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
20 * VirtualBox OSE distribution, in which case the provisions of the
21 * CDDL are applicable instead of those of the GPL.
22 *
23 * You may elect to license modified versions of this file under the
24 * terms and conditions of either the GPL or the CDDL or both.
25 */
26
27
28/*********************************************************************************************************************************
29* Header Files *
30*********************************************************************************************************************************/
31#define IPRT_NO_CRT_FOR_3RD_PARTY
32#include "internal/nocrt.h"
33#include <iprt/nocrt/math.h>
34#include <iprt/assertcompile.h>
35#include <iprt/nocrt/limits.h>
36#ifdef RT_COMPILER_WITH_128BIT_LONG_DOUBLE
37# include <iprt/uint128.h>
38#endif
39
40
41/* Similar to the fxtract instruction. */
42#undef frexpl
43long double RT_NOCRT(frexpl)(long double lrdValue, int *piExp)
44{
45#ifdef RT_COMPILER_WITH_64BIT_LONG_DOUBLE
46 RTFLOAT64U Value;
47 AssertCompile(sizeof(Value) == sizeof(lrdValue));
48 Value.lrd = lrdValue;
49
50 if (RTFLOAT64U_IS_NORMAL(&Value))
51 {
52 *piExp = (int)Value.s.uExponent - RTFLOAT64U_EXP_BIAS + 1;
53 Value.s.uExponent = RTFLOAT64U_EXP_BIAS - 1;
54 }
55 else if (RTFLOAT64U_IS_ZERO(&Value))
56 {
57 *piExp = 0;
58 return lrdValue;
59 }
60 else if (RTFLOAT64U_IS_SUBNORMAL(&Value))
61 {
62 int iExp = -RTFLOAT64U_EXP_BIAS + 1;
63 uint64_t uFraction = Value.s64.uFraction;
64 while (!(uFraction & RT_BIT_64(RTFLOAT64U_FRACTION_BITS)))
65 {
66 iExp--;
67 uFraction <<= 1;
68 }
69 Value.s64.uFraction = uFraction;
70 Value.s64.uExponent = RTFLOAT64U_EXP_BIAS - 1;
71 *piExp = iExp + 1;
72 }
73 else
74 {
75 /* NaN, Inf */
76 *piExp = Value.s.fSign ? INT_MIN : INT_MAX;
77 return lrdValue;
78 }
79 return Value.lrd;
80
81#elif defined(RT_COMPILER_WITH_80BIT_LONG_DOUBLE)
82 RTFLOAT80U2 Value;
83 Value.r = lrdValue;
84
85 if (RTFLOAT80U_IS_NORMAL(&Value))
86 {
87 *piExp = (int)Value.s.uExponent - RTFLOAT80U_EXP_BIAS + 1;
88 Value.s.uExponent = RTFLOAT80U_EXP_BIAS - 1;
89 }
90 else if (RTFLOAT80U_IS_ZERO(&Value))
91 {
92 *piExp = 0;
93 return lrdValue;
94 }
95 else if (RTFLOAT80U_IS_DENORMAL_OR_PSEUDO_DENORMAL(&Value))
96 {
97 int iExp = -RTFLOAT80U_EXP_BIAS + 1;
98 while (!(Value.s.uMantissa & RT_BIT_64(RTFLOAT80U_FRACTION_BITS)))
99 {
100 iExp--;
101 Value.s.uMantissa <<= 1;
102 }
103 Value.s.uExponent = RTFLOAT80U_EXP_BIAS - 1;
104 *piExp = iExp + 1;
105 }
106 else /* NaN, Inf */
107 {
108 *piExp = Value.s.fSign ? INT_MIN : INT_MAX;
109 return lrdValue;
110 }
111 return Value.r;
112
113
114#elif defined(RT_COMPILER_WITH_128BIT_LONG_DOUBLE)
115 RTFLOAT128U Value;
116 AssertCompile(sizeof(Value) == sizeof(lrdValue));
117 Value.r = lrdValue;
118
119 if (RTFLOAT128U_IS_NORMAL(&Value))
120 {
121 *piExp = (int)Value.s.uExponent - RTFLOAT128U_EXP_BIAS + 1;
122 Value.s.uExponent = RTFLOAT128U_EXP_BIAS - 1;
123 }
124 else if (RTFLOAT128U_IS_ZERO(&Value))
125 {
126 *piExp = 0;
127 return lrdValue;
128 }
129 else if (RTFLOAT128U_IS_SUBNORMAL(&Value))
130 {
131 int iExp = -RTFLOAT128U_EXP_BIAS + 1;
132 RTUINT128U uFraction;
133 uFraction.s.Hi = Value.s64.uFractionHi;
134 uFraction.s.Lo = Value.s64.uFractionLo;
135 while (!(uFraction.s.Hi & RT_BIT_64(RTFLOAT128U_FRACTION_BITS - 64)))
136 {
137 iExp--;
138 RTUInt128AssignShiftLeft(&uFraction, 1);
139 }
140 Value.s64.uFractionHi = uFraction.s.Hi;
141 Value.s64.uFractionLo = uFraction.s.Lo;
142 Value.s64.uExponent = RTFLOAT64U_EXP_BIAS - 1;
143 *piExp = iExp + 1;
144 }
145 else
146 {
147 /* NaN, Inf */
148 *piExp = Value.s.fSign ? INT_MIN : INT_MAX;
149 return lrdValue;
150 }
151 return Value.r;
152#else
153# error "Port ME!"
154#endif
155}
156RT_ALIAS_AND_EXPORT_NOCRT_SYMBOL(frexpl);
157
Note: See TracBrowser for help on using the repository browser.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette