1// Licensed to the .NET Foundation under one or more agreements.
2// The .NET Foundation licenses this file to you under the MIT license.
3// See the LICENSE file in the project root for more information.
4
5/*============================================================================
6**
7** Source: test1.c
8**
9** Purpose: Checks that _finitef correctly classifies all types
10** of floating point numbers (NaN, -Infinity, Infinity,
11** finite nonzero, unnormalized, 0, and -0)
12**
13**==========================================================================*/
14
15#include <palsuite.h>
16
17/*
18The IEEE single precision floating point standard looks like this:
19
20 S EEEEEEEE FFFFFFFFFFFFFFFFFFFFFFF
21 0 1 8 9 31
22
23S is the sign bit. The E bits are the exponent, and the 23 F bits are
24the fraction. These represent a value, V.
25
26If E=255 and F is nonzero, then V=NaN ("Not a number")
27If E=255 and F is zero and S is 1, then V=-Infinity
28If E=255 and F is zero and S is 0, then V=Infinity
29If 0<E<255 then V=(-1)^S * 2^(E-1028) * (1.F) where "1.F" is the binary
30 number created by prefixing F with a leading 1 and a binary point.
31If E=0 and F is nonzero, then V=(-1)^S * 2^(-127) * (0.F) These are
32 "unnormalized" values.
33If E=0 and F is zero and S is 1, then V=-0
34If E=0 and F is zero and S is 0, then V=0
35
36*/
37
38#define TO_FLOAT(x) (*((float*)((void*)&x)))
39
40int __cdecl main(int argc, char **argv)
41{
42 /*non-finite numbers*/
43 UINT32 lsnan = 0xffffffffu;
44 UINT32 lqnan = 0x7fffffffu;
45 UINT32 lneginf = 0xff800000u;
46 UINT32 lposinf = 0x7f800000u;
47
48 float snan = TO_FLOAT(lsnan);
49 float qnan = TO_FLOAT(lqnan);
50 float neginf = TO_FLOAT(lneginf);
51 float posinf = TO_FLOAT(lposinf);
52
53 /*finite numbers*/
54 UINT32 lnegunnormalized = 0x807fffffu;
55 UINT32 lposunnormalized = 0x007fffffu;
56 UINT32 lnegzero = 0x80000000u;
57
58 float negunnormalized = TO_FLOAT(lnegunnormalized);
59 float posunnormalized = TO_FLOAT(lposunnormalized);
60 float negzero = TO_FLOAT(lnegzero);
61
62 /*
63 * Initialize the PAL and return FAIL if this fails
64 */
65 if (PAL_Initialize(argc, argv) != 0)
66 {
67 return FAIL;
68 }
69
70 /*non-finite numbers*/
71 if (_finitef(snan) || _finitef(qnan))
72 {
73 Fail("_finitef() found NAN to be finite.\n");
74 }
75
76 if (_finitef(neginf))
77 {
78 Fail("_finitef() found negative infinity to be finite.\n");
79 }
80
81 if (_finitef(posinf))
82 {
83 Fail("_finitef() found infinity to be finite.\n");
84 }
85
86 /*finite numbers*/
87 if (!_finitef(negunnormalized))
88 {
89 Fail("_finitef() found a negative unnormalized value to be infinite.\n");
90 }
91
92 if (!_finitef(posunnormalized))
93 {
94 Fail("_finitef() found an unnormalized value to be infinite.\n");
95 }
96
97 if (!_finitef(negzero))
98 {
99 Fail("_finitef() found negative zero to be infinite.\n");
100 }
101
102 if (!_finitef(+0.0f))
103 {
104 Fail("_finitef() found zero to be infinite.\n");
105 }
106
107 if (!_finitef(-123.456f))
108 {
109 Fail("_finitef() found %f to be infinite.\n", -123.456f);
110 }
111
112 if (!_finitef(+123.456f))
113 {
114 Fail("_finitef() found %f to be infinite.\n", +123.456f);
115 }
116
117 PAL_Terminate();
118 return PASS;
119}
120