1 /* coded by Ketmar // Invisible Vector <ketmar@ketmar.no-ip.org>
2 * Understanding is not required. Only obedience.
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 module iv
.nanpay
/*is aliced*/;
21 enum MinSignedNanPay
= -0x7_ffff_ffff_ffffL
; // 51 bits
22 enum MaxSignedNanPay
= +0x7_ffff_ffff_ffffL
; // 51 bits
24 enum MinUnsignedNanPay
= 0UL;
25 enum MaxUnsignedNanPay
= 0x7_ffff_ffff_ffffUL
; // 51 bits
28 enum MinSignedNanPayF
= -0x3f_ffff
; // 22 bits
29 enum MaxSignedNanPayF
= +0x3f_ffff
; // 22 bits
31 enum MinUnsignedNanPayF
= 0U;
32 enum MaxUnsignedNanPayF
= 0x3f_ffffU
; // 22 bits
35 // ////////////////////////////////////////////////////////////////////////// //
36 /// is `v` finite (i.e. not a nan and not an infinity)?
37 bool isFinite (in double v
) pure nothrow @trusted @nogc {
39 return (((*cast(const(ulong)*)&v
)&0x7ff0_0000_0000_0000UL) != 0x7ff0_0000_0000_0000UL);
43 /// is `v` finite (i.e. not a nan and not an infinity)?
44 bool isFiniteF (in float v
) pure nothrow @trusted @nogc {
46 return (((*cast(const(uint)*)&v
)&0x7f80_0000U) != 0x7f80_0000U);
50 // ////////////////////////////////////////////////////////////////////////// //
52 * Create a NaN, storing an integer inside the payload.
54 * The largest possible payload is 0x7_ffff_ffff_ffff (51 bits).
55 * One bit is reserved to not turn nans into infinity.
56 * But sign bit can be used to store sign, which allows to store signed values.
57 * IDC about quiet and signaling nans: check your numbers!
59 double makeNanPay(bool doChecking
=false) (long pay
) pure nothrow @trusted @nogc {
61 static if (doChecking
) {
62 if (pay
< MinSignedNanPay || pay
> MaxSignedNanPay
) assert(0, "invalid payload");
64 pay
&= 0x8007_ffff_ffff_ffffUL
; // left only bits we are interested in
65 pay |
= 0x7ff8_0000_0000_0000UL; // set highest mantissa bit to ensure nan, and exponent to nan/inf
67 return *cast(double*)&pay
;
71 /// (rough) check if the given double contains "good nan" with payload.
72 bool hasNanPay (in double v
) pure nothrow @trusted @nogc {
74 return (((*cast(const(ulong)*)&v
)&0x7ff8_0000_0000_0000UL) == 0x7ff8_0000_0000_0000UL);
79 * Extract an integral payload from a NaN.
82 * the integer payload as a long.
84 * The largest possible payload is 0x7_ffff_ffff_ffff (51 bits).
85 * One bit is reserved to not turn nans into infinity.
86 * But sign bit can be used to store sign, which allows to store signed values.
87 * Check if your number is "good nan" before extracting!
89 long getNanPay (in double v
) pure nothrow @trusted @nogc {
91 long pay
= (*cast(const(long)*)&v
)&0x8007_ffff_ffff_ffffUL
; // remove exponent
92 // this bitors the missing "1" bits for negative numbers
93 // shift either by 16 (effectively removing the mask) or by 0
94 pay |
= 0xfff8_0000_0000_0000UL<<(((pay
>>59)&0x10)^
0x10);
100 * Extract an integral payload from a NaN.
103 * the integer payload as a long or default value if NaN has no payload.
105 * The largest possible payload is 0x7_ffff_ffff_ffff (51 bits).
106 * One bit is reserved to not turn nans into infinity.
107 * But sign bit can be used to store sign, which allows to store signed values.
108 * Check if your number is "good nan" before extracting!
110 long getNanPayDef (in double v
, long def
) pure nothrow @trusted @nogc {
111 pragma(inline
, true);
112 if (((*cast(const(ulong)*)&v
)&0x7ff8_0000_0000_0000UL) == 0x7ff8_0000_0000_0000UL) {
113 long pay
= (*cast(const(long)*)&v
)&0x8007_ffff_ffff_ffffUL
; // remove exponent
114 // this bitors the missing "1" bits for negative numbers
115 // shift either by 16 (effectively removing the mask) or by 0
116 pay |
= 0xfff8_0000_0000_0000UL<<(((pay
>>59)&0x10)^
0x10);
124 // ////////////////////////////////////////////////////////////////////////// //
126 * Create a NaN, storing an integer inside the payload.
128 * The largest possible payload is 0x7_ffff_ffff_ffff (51 bits).
129 * One bit is reserved to not turn nans into infinity.
130 * Sign bit is unused, and should be zero.
131 * IDC about quiet and signaling nans: check your numbers!
133 double makeNanPayU(bool doChecking
=false) (ulong pay
) pure nothrow @trusted @nogc {
134 pragma(inline
, true);
135 static if (doChecking
) {
136 if (pay
> MaxUnsignedNanPay
) assert(0, "invalid payload");
138 pay
&= 0x0007_ffff_ffff_ffffUL
; // left only bits we are interested in
139 pay |
= 0x7ff8_0000_0000_0000UL; // set highest mantissa bit to ensure nan, and exponent to nan/inf
141 return *cast(double*)&pay
;
145 /// (rough) check if the given double contains "good nan" with payload. sign bit should not be set.
146 bool hasNanPayU (in double v
) pure nothrow @trusted @nogc {
147 pragma(inline
, true);
148 return (((*cast(const(ulong)*)&v
)&0xfff8_0000_0000_0000UL) == 0x7ff8_0000_0000_0000UL);
153 * Extract an integral payload from a NaN.
156 * the integer payload as a long or default value if NaN has no payload.
158 * The largest possible payload is 0x7_ffff_ffff_ffff (51 bits).
159 * One bit is reserved to not turn nans into infinity.
160 * Sign bit is unused, and should be zero.
161 * Check if your number is "good nan" before extracting!
163 ulong getNanPayU (in double v
) pure nothrow @trusted @nogc {
164 pragma(inline
, true);
165 return (*cast(const(ulong)*)&v
)&0x0007_ffff_ffff_ffffUL
; // remove exponent
170 * Extract an integral payload from a NaN.
173 * the integer payload as a long or default value if NaN has no payload.
175 * The largest possible payload is 0x7_ffff_ffff_ffff (51 bits).
176 * One bit is reserved to not turn nans into infinity.
177 * Sign bit is unused, and should be zero.
178 * Check if your number is "good nan" before extracting!
180 ulong getNanPayUDef (in double v
, ulong def
) pure nothrow @trusted @nogc {
181 pragma(inline
, true);
182 return (((*cast(const(ulong)*)&v
)&0xfff8_0000_0000_0000UL) == 0x7ff8_0000_0000_0000UL ?
183 (*cast(const(ulong)*)&v
)&0x0007_ffff_ffff_ffffUL
: def
);
187 // ////////////////////////////////////////////////////////////////////////// //
188 // return 0, something <0, or something >0
189 int getDoubleXSign (in double v
) pure nothrow @trusted @nogc {
190 pragma(inline
, true);
191 version(LittleEndian
) {
192 return ((*cast(const(ulong)*)&v
)&(0x7fff_ffff_ffff_ffffUL
) ?
*((cast(const(int)*)&v
)+1) : 0);
194 static assert(0, "unimplemented arch");
199 // ////////////////////////////////////////////////////////////////////////// //
201 * Create a NaN, storing an integer inside the payload.
203 * The largest possible payload is 0x3f_ffff (22 bits).
204 * One bit is reserved to not turn nans into infinity.
205 * But sign bit can be used to store sign, which allows to store signed values.
206 * IDC about quiet and signaling nans: check your numbers!
208 float makeNanPayF(bool doChecking
=false) (int pay
) pure nothrow @trusted @nogc {
209 pragma(inline
, true);
210 static if (doChecking
) {
211 if (pay
< MinSignedNanPayF || pay
> MaxSignedNanPayF
) assert(0, "invalid payload");
213 pay
&= 0x803f_ffffU
; // left only bits we are interested in
214 pay |
= 0x7fc0_0000U; // set highest mantissa bit to ensure nan, and exponent to nan/inf
216 return *cast(float*)&pay
;
220 /// (rough) check if the given float contains "good nan" with payload.
221 bool hasNanPayF (in float v
) pure nothrow @trusted @nogc {
222 pragma(inline
, true);
223 return (((*cast(const(uint)*)&v
)&0x7fc0_0000U) == 0x7fc0_0000U);
228 * Extract an integral payload from a NaN.
231 * the integer payload as a int.
233 * The largest possible payload is 0x3f_ffff (22 bits).
234 * One bit is reserved to not turn nans into infinity.
235 * But sign bit can be used to store sign, which allows to store signed values.
236 * Check if your number is "good nan" before extracting!
238 int getNanPayF (in float v
) pure nothrow @trusted @nogc {
239 pragma(inline
, true);
240 int pay
= (*cast(const(int)*)&v
)&0x803f_ffffU
; // remove exponent
241 // this bitors the missing "1" bits for negative numbers
242 // shift either by 8 (effectively removing the mask) or by 0
243 pay |
= 0xfc00_0000U<<(((pay
>>28)&0x08)^
0x08);
249 * Extract an integral payload from a NaN.
252 * the integer payload as a int or default value if NaN has no payload.
254 * The largest possible payload is 0x3f_ffff (22 bits).
255 * One bit is reserved to not turn nans into infinity.
256 * But sign bit can be used to store sign, which allows to store signed values.
257 * Check if your number is "good nan" before extracting!
259 int getNanPayFDef (in float v
, int def
) pure nothrow @trusted @nogc {
260 pragma(inline
, true);
261 if (((*cast(const(uint)*)&v
)&0x7fc0_0000U) == 0x7fc0_0000U) {
262 int pay
= (*cast(const(int)*)&v
)&0x803f_ffffU
; // remove exponent
263 // this bitors the missing "1" bits for negative numbers
264 // shift either by 8 (effectively removing the mask) or by 0
265 pay |
= 0xfc00_0000U<<(((pay
>>28)&0x08)^
0x08);
273 // ////////////////////////////////////////////////////////////////////////// //
275 * Create a NaN, storing an integer inside the payload.
277 * The largest possible payload is 0x3f_ffff (22 bits).
278 * One bit is reserved to not turn nans into infinity.
279 * Sign bit is unused, and should be zero.
280 * IDC about quiet and signaling nans: check your numbers!
282 float makeNanPayUF(bool doChecking
=false) (uint pay
) pure nothrow @trusted @nogc {
283 pragma(inline
, true);
284 static if (doChecking
) {
285 if (pay
> MaxUnsignedNanPayF
) assert(0, "invalid payload");
287 pay
&= 0x003f_ffffU
; // left only bits we are interested in
288 pay |
= 0x7fc0_0000U; // set highest mantissa bit to ensure nan, and exponent to nan/inf
290 return *cast(float*)&pay
;
294 /// (rough) check if the given float contains "good nan" with payload. sign bit should not be set.
295 bool hasNanPayUF (in float v
) pure nothrow @trusted @nogc {
296 pragma(inline
, true);
297 return (((*cast(const(uint)*)&v
)&0xffc0_0000U) == 0x7fc0_0000U);
302 * Extract an integral payload from a NaN.
305 * the integer payload as a uint.
307 * The largest possible payload is 0x3f_ffff (22 bits).
308 * One bit is reserved to not turn nans into infinity.
309 * Sign bit is unused, and should be zero.
310 * Check if your number is "good nan" before extracting!
312 uint getNanPayUF (in float v
) pure nothrow @trusted @nogc {
313 pragma(inline
, true);
314 return (*cast(const(uint)*)&v
)&0x003f_ffffU
; // remove exponent
319 * Extract an integral payload from a NaN.
322 * the integer payload as a uint or default value if NaN has no payload.
324 * The largest possible payload is 0x3f_ffff (22 bits).
325 * One bit is reserved to not turn nans into infinity.
326 * Sign bit is unused, and should be zero.
327 * Check if your number is "good nan" before extracting!
329 uint getNanPayUFDef (in float v
, uint def
) pure nothrow @trusted @nogc {
330 pragma(inline
, true);
331 return (((*cast(const(uint)*)&v
)&0xffc0_0000U) == 0x7fc0_0000U ?
332 (*cast(const(uint)*)&v
)&0x003f_ffffU
: def
);
336 // ////////////////////////////////////////////////////////////////////////// //
337 // return 0, something <0, or something >0
338 int getFloatXSign (in float v
) pure nothrow @trusted @nogc {
339 pragma(inline
, true);
340 version(LittleEndian
) {
341 return ((*cast(const(uint)*)&v
)&0x7fff_ffffU ?
*(cast(const(int)*)&v
) : 0);
343 static assert(0, "unimplemented arch");