1
/****************************************************************************
2
**
3
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4
** All rights reserved.
5
** Contact: Nokia Corporation (qt-info@nokia.com)
6
**
7
** This file is part of the QtCore module of the Qt Toolkit.
8
**
9
** $QT_BEGIN_LICENSE:LGPL$
10
** GNU Lesser General Public License Usage
11
** This file may be used under the terms of the GNU Lesser General Public
12
** License version 2.1 as published by the Free Software Foundation and
13
** appearing in the file LICENSE.LGPL included in the packaging of this
14
** file. Please review the following information to ensure the GNU Lesser
15
** General Public License version 2.1 requirements will be met:
16
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17
**
18
** In addition, as a special exception, Nokia gives you certain additional
19
** rights. These rights are described in the Nokia Qt LGPL Exception
20
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21
**
22
** GNU General Public License Usage
23
** Alternatively, this file may be used under the terms of the GNU General
24
** Public License version 3.0 as published by the Free Software Foundation
25
** and appearing in the file LICENSE.GPL included in the packaging of this
26
** file. Please review the following information to ensure the GNU General
27
** Public License version 3.0 requirements will be met:
28
** http://www.gnu.org/copyleft/gpl.html.
29
**
30
** Other Usage
31
** Alternatively, this file may be used in accordance with the terms and
32
** conditions contained in a signed written agreement between you and Nokia.
33
**
34
**
35
**
36
**
37
**
38
** $QT_END_LICENSE$
39
**
40
****************************************************************************/
41
42
#ifndef QNUMERIC_P_H
43
#define QNUMERIC_P_H
44
45
//
46
//  W A R N I N G
47
//  -------------
48
//
49
// This file is not part of the Qt API.  It exists purely as an
50
// implementation detail.  This header file may change from version to
51
// version without notice, or even be removed.
52
//
53
// We mean it.
54
//
55
56
#include "QtCore/qglobal.h"
57
58
QT_BEGIN_NAMESPACE
59
60
#if !defined(Q_CC_MIPS)
61
62
static const union { unsigned char c[8]; double d; } qt_be_inf_bytes = { { 0x7f, 0xf0, 0, 0, 0, 0, 0, 0 } };
63
static const union { unsigned char c[8]; double d; } qt_le_inf_bytes = { { 0, 0, 0, 0, 0, 0, 0xf0, 0x7f } };
64
static const union { unsigned char c[8]; double d; } qt_armfpa_inf_bytes = { { 0, 0, 0xf0, 0x7f, 0, 0, 0, 0 } };
65
static inline double qt_inf()
66
{
67
#ifdef QT_ARMFPA
68
    return qt_armfpa_inf_bytes.d;
69
#else
70
    return (QSysInfo::ByteOrder == QSysInfo::BigEndian
71
            ? qt_be_inf_bytes.d
72
            : qt_le_inf_bytes.d);
73
#endif
74
}
75
76
// Signaling NAN
77
static const union { unsigned char c[8]; double d; } qt_be_snan_bytes = { { 0x7f, 0xf8, 0, 0, 0, 0, 0, 0 } };
78
static const union { unsigned char c[8]; double d; } qt_le_snan_bytes = { { 0, 0, 0, 0, 0, 0, 0xf8, 0x7f } };
79
static const union { unsigned char c[8]; double d; } qt_armfpa_snan_bytes = { { 0, 0, 0xf8, 0x7f, 0, 0, 0, 0 } };
80
static inline double qt_snan()
81
{
82
#ifdef QT_ARMFPA
83
    return qt_armfpa_snan_bytes.d;
84
#else
85
    return (QSysInfo::ByteOrder == QSysInfo::BigEndian
86
            ? qt_be_snan_bytes.d
87
            : qt_le_snan_bytes.d);
88
#endif
89
}
90
91
// Quiet NAN
92
static const union { unsigned char c[8]; double d; } qt_be_qnan_bytes = { { 0xff, 0xf8, 0, 0, 0, 0, 0, 0 } };
93
static const union { unsigned char c[8]; double d; } qt_le_qnan_bytes = { { 0, 0, 0, 0, 0, 0, 0xf8, 0xff } };
94
static const union { unsigned char c[8]; double d; } qt_armfpa_qnan_bytes = { { 0, 0, 0xf8, 0xff, 0, 0, 0, 0 } };
95
static inline double qt_qnan()
96
{
97
#ifdef QT_ARMFPA
98
    return qt_armfpa_qnan_bytes.d;
99
#else
100
    return (QSysInfo::ByteOrder == QSysInfo::BigEndian
101
            ? qt_be_qnan_bytes.d
102
            : qt_le_qnan_bytes.d);
103
#endif
104
}
105
106
#else // Q_CC_MIPS
107
108
static const unsigned char qt_be_inf_bytes[] = { 0x7f, 0xf0, 0, 0, 0, 0, 0, 0 };
109
static const unsigned char qt_le_inf_bytes[] = { 0, 0, 0, 0, 0, 0, 0xf0, 0x7f };
110
static const unsigned char qt_armfpa_inf_bytes[] = { 0, 0, 0xf0, 0x7f, 0, 0, 0, 0 };
111
static inline double qt_inf()
112
{
113
    const unsigned char *bytes;
114
#ifdef QT_ARMFPA
115
    bytes = qt_armfpa_inf_bytes;
116
#else
117
    bytes = (QSysInfo::ByteOrder == QSysInfo::BigEndian
118
             ? qt_be_inf_bytes
119
             : qt_le_inf_bytes);
120
#endif
121
122
    union { unsigned char c[8]; double d; } returnValue;
123
    qMemCopy(returnValue.c, bytes, sizeof(returnValue.c));
124
    return returnValue.d;
125
}
126
127
// Signaling NAN
128
static const unsigned char qt_be_snan_bytes[] = { 0x7f, 0xf8, 0, 0, 0, 0, 0, 0 };
129
static const unsigned char qt_le_snan_bytes[] = { 0, 0, 0, 0, 0, 0, 0xf8, 0x7f };
130
static const unsigned char qt_armfpa_snan_bytes[] = { 0, 0, 0xf8, 0x7f, 0, 0, 0, 0 };
131
static inline double qt_snan()
132
{
133
    const unsigned char *bytes;
134
#ifdef QT_ARMFPA
135
    bytes = qt_armfpa_snan_bytes;
136
#else
137
    bytes = (QSysInfo::ByteOrder == QSysInfo::BigEndian
138
             ? qt_be_snan_bytes
139
             : qt_le_snan_bytes);
140
#endif
141
142
    union { unsigned char c[8]; double d; } returnValue;
143
    qMemCopy(returnValue.c, bytes, sizeof(returnValue.c));
144
    return returnValue.d;
145
}
146
147
// Quiet NAN
148
static const unsigned char qt_be_qnan_bytes[] = { 0xff, 0xf8, 0, 0, 0, 0, 0, 0 };
149
static const unsigned char qt_le_qnan_bytes[] = { 0, 0, 0, 0, 0, 0, 0xf8, 0xff };
150
static const unsigned char qt_armfpa_qnan_bytes[] = { 0, 0, 0xf8, 0xff, 0, 0, 0, 0 };
151
static inline double qt_qnan()
152
{
153
    const unsigned char *bytes;
154
#ifdef QT_ARMFPA
155
    bytes = qt_armfpa_qnan_bytes;
156
#else
157
    bytes = (QSysInfo::ByteOrder == QSysInfo::BigEndian
158
             ? qt_be_qnan_bytes
159
             : qt_le_qnan_bytes);
160
#endif
161
162
    union { unsigned char c[8]; double d; } returnValue;
163
    qMemCopy(returnValue.c, bytes, sizeof(returnValue.c));
164
    return returnValue.d;
165
}
166
167
#endif // Q_CC_MIPS
168
169
static inline bool qt_is_inf(double d)
170
{
171
    uchar *ch = (uchar *)&d;
172
#ifdef QT_ARMFPA
173
    return (ch[3] & 0x7f) == 0x7f && ch[2] == 0xf0;
174
#else
175
    if (QSysInfo::ByteOrder == QSysInfo::BigEndian) {
176
        return (ch[0] & 0x7f) == 0x7f && ch[1] == 0xf0;
177
    } else {
178
        return (ch[7] & 0x7f) == 0x7f && ch[6] == 0xf0;
179
    }
180
#endif
181
}
182
183
static inline bool qt_is_nan(double d)
184
{
185
    uchar *ch = (uchar *)&d;
186
#ifdef QT_ARMFPA
187
    return (ch[3] & 0x7f) == 0x7f && ch[2] > 0xf0;
188
#else
189
    if (QSysInfo::ByteOrder == QSysInfo::BigEndian) {
190
        return (ch[0] & 0x7f) == 0x7f && ch[1] > 0xf0;
191
    } else {
192
        return (ch[7] & 0x7f) == 0x7f && ch[6] > 0xf0;
193
    }
194
#endif
195
}
196
197
static inline bool qt_is_finite(double d)
198
{
199
    uchar *ch = (uchar *)&d;
200
#ifdef QT_ARMFPA
201
    return (ch[3] & 0x7f) != 0x7f || (ch[2] & 0xf0) != 0xf0;
202
#else
203
    if (QSysInfo::ByteOrder == QSysInfo::BigEndian) {
204
        return (ch[0] & 0x7f) != 0x7f || (ch[1] & 0xf0) != 0xf0;
205
    } else {
206
        return (ch[7] & 0x7f) != 0x7f || (ch[6] & 0xf0) != 0xf0;
207
    }
208
#endif
209
}
210
211
static inline bool qt_is_inf(float d)
212
{
213
    uchar *ch = (uchar *)&d;
214
    if (QSysInfo::ByteOrder == QSysInfo::BigEndian) {
215
        return (ch[0] & 0x7f) == 0x7f && ch[1] == 0x80;
216
    } else {
217
        return (ch[3] & 0x7f) == 0x7f && ch[2] == 0x80;
218
    }
219
}
220
221
static inline bool qt_is_nan(float d)
222
{
223
    uchar *ch = (uchar *)&d;
224
    if (QSysInfo::ByteOrder == QSysInfo::BigEndian) {
225
        return (ch[0] & 0x7f) == 0x7f && ch[1] > 0x80;
226
    } else {
227
        return (ch[3] & 0x7f) == 0x7f && ch[2] > 0x80;
228
    }
229
}
230
231
static inline bool qt_is_finite(float d)
232
{
233
    uchar *ch = (uchar *)&d;
234
    if (QSysInfo::ByteOrder == QSysInfo::BigEndian) {
235
        return (ch[0] & 0x7f) != 0x7f || (ch[1] & 0x80) != 0x80;
236
    } else {
237
        return (ch[3] & 0x7f) != 0x7f || (ch[2] & 0x80) != 0x80;
238
    }
239
}
240
241
QT_END_NAMESPACE
242
243
#endif // QNUMERIC_P_H