blob: 5e5879465b3e47886e58e4df66ec1a702743e79a [file] [log] [blame]
Laurence Lundblade68a13352018-09-23 02:19:54 -07001/*==============================================================================
Laurence Lundblade2d85ce42018-10-12 14:12:47 +08002 float_tests.c -- tests for float and conversion to/from half-precision
Laurence Lundblade781fd822018-10-01 09:37:52 -07003
Laurence Lundbladeee851742020-01-08 08:37:05 -08004 Copyright (c) 2018-2020, Laurence Lundblade. All rights reserved.
Laurence Lundblade035bd782019-01-21 17:01:31 -08005
Laurence Lundbladea3fd49f2019-01-21 10:16:22 -08006 SPDX-License-Identifier: BSD-3-Clause
Laurence Lundblade035bd782019-01-21 17:01:31 -08007
Laurence Lundbladea3fd49f2019-01-21 10:16:22 -08008 See BSD-3-Clause license in README.md
Laurence Lundblade035bd782019-01-21 17:01:31 -08009
Laurence Lundbladea3fd49f2019-01-21 10:16:22 -080010 Created on 9/19/18
Laurence Lundbladeee851742020-01-08 08:37:05 -080011 =============================================================================*/
Laurence Lundblade68a13352018-09-23 02:19:54 -070012
Laurence Lundblade585127a2020-07-15 03:25:24 -070013#include "qcbor/qcbor_encode.h"
14#include <math.h> // For INFINITY and NAN and isnan()
15
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -070016#ifndef QCBOR_DISABLE_PREFERRED_FLOAT
Laurence Lundblade9682a532020-06-06 18:33:04 -070017
Laurence Lundblade2d85ce42018-10-12 14:12:47 +080018#include "float_tests.h"
Laurence Lundblade844bb5c2020-03-01 17:27:25 -080019#include "qcbor/qcbor_decode.h"
Laurence Lundbladed711fb22018-09-26 14:35:22 -070020#include "half_to_double_from_rfc7049.h"
Laurence Lundblade68a13352018-09-23 02:19:54 -070021
Laurence Lundblade2d85ce42018-10-12 14:12:47 +080022
Laurence Lundblade2d85ce42018-10-12 14:12:47 +080023
Laurence Lundbladebb474be2018-10-22 11:53:21 +053024static const uint8_t spExpectedHalf[] = {
Laurence Lundblade7d40d812018-09-30 02:44:01 -070025 0xB1,
Laurence Lundblade68a13352018-09-23 02:19:54 -070026 0x64,
27 0x7A, 0x65, 0x72, 0x6F,
28 0xF9, 0x00, 0x00, // 0.000
29 0x6A,
30 0x69, 0x6E, 0x66, 0x69, 0x6E, 0x69, 0x74, 0x69, 0x74, 0x79,
31 0xF9, 0x7C, 0x00, // Infinity
32 0x73,
Laurence Lundbladeee851742020-01-08 08:37:05 -080033 0x6E, 0x65, 0x67, 0x61, 0x74, 0x69, 0x76, 0x65, 0x20, 0x69, 0x6E,
34 0x66, 0x69, 0x6E, 0x69, 0x74, 0x69, 0x74, 0x79,
Laurence Lundblade68a13352018-09-23 02:19:54 -070035 0xF9, 0xFC, 0x00, // -Inifinity
36 0x63,
37 0x4E, 0x61, 0x4E,
38 0xF9, 0x7E, 0x00, // NaN
39 0x63,
40 0x6F, 0x6E, 0x65,
41 0xF9, 0x3C, 0x00, // 1.0
42 0x69,
43 0x6F, 0x6E, 0x65, 0x20, 0x74, 0x68, 0x69, 0x72, 0x64,
44 0xF9, 0x35, 0x55, // 0.333251953125
45 0x76,
Laurence Lundbladeee851742020-01-08 08:37:05 -080046 0x6C, 0x61, 0x72, 0x67, 0x65, 0x73, 0x74, 0x20, 0x68, 0x61, 0x6C,
47 0x66, 0x2D, 0x70, 0x72, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6F, 0x6E,
Laurence Lundblade68a13352018-09-23 02:19:54 -070048 0xF9, 0x7B, 0xFF, // 65504.0
Laurence Lundbladeee851742020-01-08 08:37:05 -080049 0x78, 0x18,
50 0x74, 0x6F, 0x6F, 0x2D, 0x6C, 0x61, 0x72, 0x67, 0x65, 0x20, 0x68,
51 0x61, 0x6C, 0x66, 0x2D, 0x70, 0x72, 0x65, 0x63, 0x69, 0x73, 0x69,
52 0x6F, 0x6E,
Laurence Lundblade68a13352018-09-23 02:19:54 -070053 0xF9, 0x7C, 0x00, // Infinity
54 0x72,
Laurence Lundbladeee851742020-01-08 08:37:05 -080055 0x73, 0x6D, 0x61, 0x6C, 0x6C, 0x65, 0x73, 0x74, 0x20, 0x73, 0x75,
56 0x62, 0x6E, 0x6F, 0x72, 0x6D, 0x61, 0x6C,
Laurence Lundblade68a13352018-09-23 02:19:54 -070057 0xF9, 0x00, 0x01, // 0.000000059604
58 0x6F,
Laurence Lundbladeee851742020-01-08 08:37:05 -080059 0x73, 0x6D, 0x61, 0x6C, 0x6C, 0x65, 0x73, 0x74, 0x20, 0x6E, 0x6F,
60 0x72, 0x6D, 0x61, 0x6C,
Laurence Lundblade68a13352018-09-23 02:19:54 -070061 0xF9, 0x03, 0xFF, // 0.0000609755516
62 0x71,
Laurence Lundbladeee851742020-01-08 08:37:05 -080063 0x62, 0x69, 0x67, 0x67, 0x65, 0x73, 0x74, 0x20, 0x73, 0x75, 0x62,
64 0x6E, 0x6F, 0x72, 0x6D, 0x61, 0x6C,
Laurence Lundblade68a13352018-09-23 02:19:54 -070065 0xF9, 0x04, 0x00, // 0.000061988
66 0x70,
Laurence Lundbladeee851742020-01-08 08:37:05 -080067 0x73, 0x75, 0x62, 0x6E, 0x6F, 0x72, 0x6D, 0x61, 0x6C, 0x20, 0x73,
68 0x69, 0x6E, 0x67, 0x6C, 0x65,
Laurence Lundblade68a13352018-09-23 02:19:54 -070069 0xF9, 0x00, 0x00,
70 0x03,
Laurence Lundblade7d40d812018-09-30 02:44:01 -070071 0xF9, 0xC0, 0x00, // -2
72 0x04,
73 0xF9, 0x7E, 0x00, // qNaN
74 0x05,
75 0xF9, 0x7C, 0x01, // sNaN
76 0x06,
77 0xF9, 0x7E, 0x0F, // qNaN with payload 0x0f
78 0x07,
79 0xF9, 0x7C, 0x0F, // sNaN with payload 0x0f
Laurence Lundblade3aee3a32018-12-17 16:17:45 -080080
Laurence Lundblade68a13352018-09-23 02:19:54 -070081};
82
83
Laurence Lundbladec5fef682020-01-25 11:38:45 -080084int32_t HalfPrecisionDecodeBasicTests()
Laurence Lundblade68a13352018-09-23 02:19:54 -070085{
Laurence Lundbladebb474be2018-10-22 11:53:21 +053086 UsefulBufC HalfPrecision = UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spExpectedHalf);
Laurence Lundblade3aee3a32018-12-17 16:17:45 -080087
Laurence Lundblade68a13352018-09-23 02:19:54 -070088 QCBORDecodeContext DC;
89 QCBORDecode_Init(&DC, HalfPrecision, 0);
Laurence Lundblade3aee3a32018-12-17 16:17:45 -080090
Laurence Lundblade68a13352018-09-23 02:19:54 -070091 QCBORItem Item;
92
93 QCBORDecode_GetNext(&DC, &Item);
94 if(Item.uDataType != QCBOR_TYPE_MAP) {
95 return -1;
96 }
97
98 QCBORDecode_GetNext(&DC, &Item);
Laurence Lundblade67bd5512018-11-02 21:44:06 +070099 if(Item.uDataType != QCBOR_TYPE_DOUBLE || Item.val.dfnum != 0.0F) {
Laurence Lundblade7d40d812018-09-30 02:44:01 -0700100 return -2;
Laurence Lundblade68a13352018-09-23 02:19:54 -0700101 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800102
Laurence Lundblade68a13352018-09-23 02:19:54 -0700103 QCBORDecode_GetNext(&DC, &Item);
Laurence Lundblade67bd5512018-11-02 21:44:06 +0700104 if(Item.uDataType != QCBOR_TYPE_DOUBLE || Item.val.dfnum != INFINITY) {
Laurence Lundblade7d40d812018-09-30 02:44:01 -0700105 return -3;
Laurence Lundblade68a13352018-09-23 02:19:54 -0700106 }
107
108 QCBORDecode_GetNext(&DC, &Item);
Laurence Lundblade67bd5512018-11-02 21:44:06 +0700109 if(Item.uDataType != QCBOR_TYPE_DOUBLE || Item.val.dfnum != -INFINITY) {
Laurence Lundblade7d40d812018-09-30 02:44:01 -0700110 return -4;
Laurence Lundblade68a13352018-09-23 02:19:54 -0700111 }
112
Laurence Lundbladeee851742020-01-08 08:37:05 -0800113 // TODO, is this really converting right? It is carrying payload, but
114 // this confuses things.
115 QCBORDecode_GetNext(&DC, &Item);
Laurence Lundblade67bd5512018-11-02 21:44:06 +0700116 if(Item.uDataType != QCBOR_TYPE_DOUBLE || !isnan(Item.val.dfnum)) {
Laurence Lundblade7d40d812018-09-30 02:44:01 -0700117 return -5;
Laurence Lundblade68a13352018-09-23 02:19:54 -0700118 }
119
120 QCBORDecode_GetNext(&DC, &Item);
Laurence Lundblade67bd5512018-11-02 21:44:06 +0700121 if(Item.uDataType != QCBOR_TYPE_DOUBLE || Item.val.dfnum != 1.0F) {
Laurence Lundblade7d40d812018-09-30 02:44:01 -0700122 return -6;
Laurence Lundblade68a13352018-09-23 02:19:54 -0700123 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800124
Laurence Lundblade68a13352018-09-23 02:19:54 -0700125 QCBORDecode_GetNext(&DC, &Item);
Laurence Lundblade67bd5512018-11-02 21:44:06 +0700126 if(Item.uDataType != QCBOR_TYPE_DOUBLE || Item.val.dfnum != 0.333251953125F) {
Laurence Lundblade7d40d812018-09-30 02:44:01 -0700127 return -7;
Laurence Lundblade68a13352018-09-23 02:19:54 -0700128 }
129
130 QCBORDecode_GetNext(&DC, &Item);
Laurence Lundblade67bd5512018-11-02 21:44:06 +0700131 if(Item.uDataType != QCBOR_TYPE_DOUBLE || Item.val.dfnum != 65504.0F) {
Laurence Lundblade7d40d812018-09-30 02:44:01 -0700132 return -8;
Laurence Lundblade68a13352018-09-23 02:19:54 -0700133 }
134
135 QCBORDecode_GetNext(&DC, &Item);
Laurence Lundblade67bd5512018-11-02 21:44:06 +0700136 if(Item.uDataType != QCBOR_TYPE_DOUBLE || Item.val.dfnum != INFINITY) {
Laurence Lundblade7d40d812018-09-30 02:44:01 -0700137 return -9;
Laurence Lundblade68a13352018-09-23 02:19:54 -0700138 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800139
Laurence Lundblade68a13352018-09-23 02:19:54 -0700140 QCBORDecode_GetNext(&DC, &Item); // TODO: check this
Laurence Lundblade67bd5512018-11-02 21:44:06 +0700141 if(Item.uDataType != QCBOR_TYPE_DOUBLE || Item.val.dfnum != 0.0000000596046448F) {
Laurence Lundblade7d40d812018-09-30 02:44:01 -0700142 return -10;
Laurence Lundblade68a13352018-09-23 02:19:54 -0700143 }
144
145 QCBORDecode_GetNext(&DC, &Item); // TODO: check this
Laurence Lundblade67bd5512018-11-02 21:44:06 +0700146 if(Item.uDataType != QCBOR_TYPE_DOUBLE || Item.val.dfnum != 0.0000609755516F) {
Laurence Lundblade7d40d812018-09-30 02:44:01 -0700147 return -11;
Laurence Lundblade68a13352018-09-23 02:19:54 -0700148 }
149
150 QCBORDecode_GetNext(&DC, &Item); // TODO check this
Laurence Lundblade67bd5512018-11-02 21:44:06 +0700151 if(Item.uDataType != QCBOR_TYPE_DOUBLE || Item.val.dfnum != 0.0000610351563F) {
Laurence Lundblade7d40d812018-09-30 02:44:01 -0700152 return -12;
Laurence Lundblade68a13352018-09-23 02:19:54 -0700153 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800154
155 QCBORDecode_GetNext(&DC, &Item);
Laurence Lundblade67bd5512018-11-02 21:44:06 +0700156 if(Item.uDataType != QCBOR_TYPE_DOUBLE || Item.val.dfnum != 0) {
Laurence Lundblade7d40d812018-09-30 02:44:01 -0700157 return -13;
Laurence Lundblade68a13352018-09-23 02:19:54 -0700158 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800159
Laurence Lundblade68a13352018-09-23 02:19:54 -0700160 QCBORDecode_GetNext(&DC, &Item);
Laurence Lundblade67bd5512018-11-02 21:44:06 +0700161 if(Item.uDataType != QCBOR_TYPE_DOUBLE || Item.val.dfnum != -2.0F) {
Laurence Lundblade7d40d812018-09-30 02:44:01 -0700162 return -14;
163 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800164
Laurence Lundblade67bd5512018-11-02 21:44:06 +0700165 // TODO: double check these four tests
166 QCBORDecode_GetNext(&DC, &Item); // qNaN
Laurence Lundbladeee851742020-01-08 08:37:05 -0800167 if(Item.uDataType != QCBOR_TYPE_DOUBLE ||
168 UsefulBufUtil_CopyDoubleToUint64(Item.val.dfnum) != 0x7ff8000000000000ULL) {
Laurence Lundblade7d40d812018-09-30 02:44:01 -0700169 return -15;
170 }
Laurence Lundblade67bd5512018-11-02 21:44:06 +0700171 QCBORDecode_GetNext(&DC, &Item); // sNaN
Laurence Lundbladeee851742020-01-08 08:37:05 -0800172 if(Item.uDataType != QCBOR_TYPE_DOUBLE ||
173 UsefulBufUtil_CopyDoubleToUint64(Item.val.dfnum) != 0x7ff0000000000001ULL) {
Laurence Lundblade7d40d812018-09-30 02:44:01 -0700174 return -16;
175 }
Laurence Lundblade67bd5512018-11-02 21:44:06 +0700176 QCBORDecode_GetNext(&DC, &Item); // qNaN with payload 0x0f
Laurence Lundbladeee851742020-01-08 08:37:05 -0800177 if(Item.uDataType != QCBOR_TYPE_DOUBLE ||
178 UsefulBufUtil_CopyDoubleToUint64(Item.val.dfnum) != 0x7ff800000000000fULL) {
Laurence Lundblade7d40d812018-09-30 02:44:01 -0700179 return -17;
180 }
Laurence Lundblade67bd5512018-11-02 21:44:06 +0700181 QCBORDecode_GetNext(&DC, &Item); // sNaN with payload 0x0f
Laurence Lundbladeee851742020-01-08 08:37:05 -0800182 if(Item.uDataType != QCBOR_TYPE_DOUBLE ||
183 UsefulBufUtil_CopyDoubleToUint64(Item.val.dfnum) != 0x7ff000000000000fULL) {
Laurence Lundblade7d40d812018-09-30 02:44:01 -0700184 return -18;
Laurence Lundblade68a13352018-09-23 02:19:54 -0700185 }
Laurence Lundblade67bd5512018-11-02 21:44:06 +0700186
Laurence Lundblade68a13352018-09-23 02:19:54 -0700187 if(QCBORDecode_Finish(&DC)) {
Laurence Lundblade7d40d812018-09-30 02:44:01 -0700188 return -19;
Laurence Lundblade68a13352018-09-23 02:19:54 -0700189 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800190
Laurence Lundblade68a13352018-09-23 02:19:54 -0700191 return 0;
192}
Laurence Lundbladed711fb22018-09-26 14:35:22 -0700193
194
Laurence Lundbladed711fb22018-09-26 14:35:22 -0700195
196
Laurence Lundbladec5fef682020-01-25 11:38:45 -0800197int32_t HalfPrecisionAgainstRFCCodeTest()
Laurence Lundbladed711fb22018-09-26 14:35:22 -0700198{
Laurence Lundblade7d40d812018-09-30 02:44:01 -0700199 for(uint32_t uHalfP = 0; uHalfP < 0xffff; uHalfP += 60) {
Laurence Lundbladed711fb22018-09-26 14:35:22 -0700200 unsigned char x[2];
Laurence Lundbladec5fef682020-01-25 11:38:45 -0800201 x[1] = (uint8_t)(uHalfP & 0xff);
202 x[0] = (uint8_t)(uHalfP >> 8); // uHalfP is always less than 0xffff
Laurence Lundbladed711fb22018-09-26 14:35:22 -0700203 double d = decode_half(x);
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800204
Laurence Lundbladed711fb22018-09-26 14:35:22 -0700205 // Contruct the CBOR for the half-precision float by hand
Laurence Lundblade4fe9f312018-10-22 10:22:39 +0530206 UsefulBuf_MAKE_STACK_UB(__xx, 3);
Laurence Lundbladed711fb22018-09-26 14:35:22 -0700207 UsefulOutBuf UOB;
208 UsefulOutBuf_Init(&UOB, __xx);
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800209
Laurence Lundbladec5fef682020-01-25 11:38:45 -0800210 const uint8_t uHalfPrecInitialByte = (uint8_t)(HALF_PREC_FLOAT + (CBOR_MAJOR_TYPE_SIMPLE << 5)); // 0xf9
Laurence Lundbladed711fb22018-09-26 14:35:22 -0700211 UsefulOutBuf_AppendByte(&UOB, uHalfPrecInitialByte); // The initial byte for a half-precision float
212 UsefulOutBuf_AppendUint16(&UOB, (uint16_t)uHalfP);
213
Laurence Lundbladeee851742020-01-08 08:37:05 -0800214 // Now parse the hand-constructed CBOR. This will invoke the
215 // conversion to a float
Laurence Lundbladed711fb22018-09-26 14:35:22 -0700216 QCBORDecodeContext DC;
217 QCBORDecode_Init(&DC, UsefulOutBuf_OutUBuf(&UOB), 0);
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800218
Laurence Lundbladed711fb22018-09-26 14:35:22 -0700219 QCBORItem Item;
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800220
Laurence Lundbladed711fb22018-09-26 14:35:22 -0700221 QCBORDecode_GetNext(&DC, &Item);
Laurence Lundblade67bd5512018-11-02 21:44:06 +0700222 if(Item.uDataType != QCBOR_TYPE_DOUBLE) {
Laurence Lundbladed711fb22018-09-26 14:35:22 -0700223 return -1;
224 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800225
Laurence Lundbladeee851742020-01-08 08:37:05 -0800226 //printf("%04x QCBOR:%15.15f RFC: %15.15f (%8x)\n",
227 // uHalfP, Item.val.fnum, d , UsefulBufUtil_CopyFloatToUint32(d));
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800228
Laurence Lundblade7d40d812018-09-30 02:44:01 -0700229 if(isnan(d)) {
230 // The RFC code uses the native instructions which may or may not
231 // handle sNaN, qNaN and NaN payloads correctly. This test just
232 // makes sure it is a NaN and doesn't worry about the type of NaN
Laurence Lundblade67bd5512018-11-02 21:44:06 +0700233 if(!isnan(Item.val.dfnum)) {
Laurence Lundblade7d40d812018-09-30 02:44:01 -0700234 return -3;
235 }
236 } else {
Laurence Lundblade67bd5512018-11-02 21:44:06 +0700237 if(Item.val.dfnum != d) {
Laurence Lundblade7d40d812018-09-30 02:44:01 -0700238 return -2;
239 }
Laurence Lundbladed711fb22018-09-26 14:35:22 -0700240 }
241 }
242 return 0;
243}
244
245
246/*
Laurence Lundbladebb474be2018-10-22 11:53:21 +0530247 {"zero": 0.0,
248 "negative zero": -0.0,
249 "infinitity": Infinity,
250 "negative infinitity": -Infinity,
251 "NaN": NaN,
252 "one": 1.0,
253 "one third": 0.333251953125,
254 "largest half-precision": 65504.0,
255 "largest half-precision point one": 65504.1,
256 "too-large half-precision": 65536.0,
257 "smallest subnormal": 5.96046448e-8,
258 "smallest normal": 0.00006103515261202119,
259 "biggest subnormal": 0.00006103515625,
260 "subnormal single": 4.00000646641519e-40,
261 3: -2.0,
262 "large single exp": 2.5521177519070385e+38,
263 "too-large single exp": 5.104235503814077e+38,
264 "biggest single with prec": 16777216.0,
265 "first single with prec loss": 16777217.0,
266 1: "fin"}
Laurence Lundbladed711fb22018-09-26 14:35:22 -0700267 */
Laurence Lundbladebb474be2018-10-22 11:53:21 +0530268static const uint8_t spExpectedSmallest[] = {
269 0xB4, 0x64, 0x7A, 0x65, 0x72, 0x6F, 0xF9, 0x00, 0x00, 0x6D,
270 0x6E, 0x65, 0x67, 0x61, 0x74, 0x69, 0x76, 0x65, 0x20, 0x7A,
271 0x65, 0x72, 0x6F, 0xF9, 0x80, 0x00, 0x6A, 0x69, 0x6E, 0x66,
272 0x69, 0x6E, 0x69, 0x74, 0x69, 0x74, 0x79, 0xF9, 0x7C, 0x00,
273 0x73, 0x6E, 0x65, 0x67, 0x61, 0x74, 0x69, 0x76, 0x65, 0x20,
274 0x69, 0x6E, 0x66, 0x69, 0x6E, 0x69, 0x74, 0x69, 0x74, 0x79,
275 0xF9, 0xFC, 0x00, 0x63, 0x4E, 0x61, 0x4E, 0xF9, 0x7E, 0x00,
276 0x63, 0x6F, 0x6E, 0x65, 0xF9, 0x3C, 0x00, 0x69, 0x6F, 0x6E,
277 0x65, 0x20, 0x74, 0x68, 0x69, 0x72, 0x64, 0xF9, 0x35, 0x55,
278 0x76, 0x6C, 0x61, 0x72, 0x67, 0x65, 0x73, 0x74, 0x20, 0x68,
279 0x61, 0x6C, 0x66, 0x2D, 0x70, 0x72, 0x65, 0x63, 0x69, 0x73,
280 0x69, 0x6F, 0x6E, 0xF9, 0x7B, 0xFF, 0x78, 0x20, 0x6C, 0x61,
281 0x72, 0x67, 0x65, 0x73, 0x74, 0x20, 0x68, 0x61, 0x6C, 0x66,
282 0x2D, 0x70, 0x72, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6F, 0x6E,
283 0x20, 0x70, 0x6F, 0x69, 0x6E, 0x74, 0x20, 0x6F, 0x6E, 0x65,
284 0xFB, 0x40, 0xEF, 0xFC, 0x03, 0x33, 0x33, 0x33, 0x33, 0x78,
285 0x18, 0x74, 0x6F, 0x6F, 0x2D, 0x6C, 0x61, 0x72, 0x67, 0x65,
286 0x20, 0x68, 0x61, 0x6C, 0x66, 0x2D, 0x70, 0x72, 0x65, 0x63,
287 0x69, 0x73, 0x69, 0x6F, 0x6E, 0xFA, 0x47, 0x80, 0x00, 0x00,
288 0x72, 0x73, 0x6D, 0x61, 0x6C, 0x6C, 0x65, 0x73, 0x74, 0x20,
289 0x73, 0x75, 0x62, 0x6E, 0x6F, 0x72, 0x6D, 0x61, 0x6C, 0xFB,
290 0x3E, 0x70, 0x00, 0x00, 0x00, 0x1C, 0x5F, 0x68, 0x6F, 0x73,
291 0x6D, 0x61, 0x6C, 0x6C, 0x65, 0x73, 0x74, 0x20, 0x6E, 0x6F,
292 0x72, 0x6D, 0x61, 0x6C, 0xFA, 0x38, 0x7F, 0xFF, 0xFF, 0x71,
293 0x62, 0x69, 0x67, 0x67, 0x65, 0x73, 0x74, 0x20, 0x73, 0x75,
294 0x62, 0x6E, 0x6F, 0x72, 0x6D, 0x61, 0x6C, 0xF9, 0x04, 0x00,
295 0x70, 0x73, 0x75, 0x62, 0x6E, 0x6F, 0x72, 0x6D, 0x61, 0x6C,
296 0x20, 0x73, 0x69, 0x6E, 0x67, 0x6C, 0x65, 0xFB, 0x37, 0xC1,
297 0x6C, 0x28, 0x00, 0x00, 0x00, 0x00, 0x03, 0xF9, 0xC0, 0x00,
298 0x70, 0x6C, 0x61, 0x72, 0x67, 0x65, 0x20, 0x73, 0x69, 0x6E,
299 0x67, 0x6C, 0x65, 0x20, 0x65, 0x78, 0x70, 0xFA, 0x7F, 0x40,
300 0x00, 0x00, 0x74, 0x74, 0x6F, 0x6F, 0x2D, 0x6C, 0x61, 0x72,
301 0x67, 0x65, 0x20, 0x73, 0x69, 0x6E, 0x67, 0x6C, 0x65, 0x20,
302 0x65, 0x78, 0x70, 0xFB, 0x47, 0xF8, 0x00, 0x00, 0x00, 0x00,
303 0x00, 0x00, 0x78, 0x18, 0x62, 0x69, 0x67, 0x67, 0x65, 0x73,
304 0x74, 0x20, 0x73, 0x69, 0x6E, 0x67, 0x6C, 0x65, 0x20, 0x77,
305 0x69, 0x74, 0x68, 0x20, 0x70, 0x72, 0x65, 0x63, 0xFA, 0x4B,
306 0x80, 0x00, 0x00, 0x78, 0x1B, 0x66, 0x69, 0x72, 0x73, 0x74,
307 0x20, 0x73, 0x69, 0x6E, 0x67, 0x6C, 0x65, 0x20, 0x77, 0x69,
308 0x74, 0x68, 0x20, 0x70, 0x72, 0x65, 0x63, 0x20, 0x6C, 0x6F,
309 0x73, 0x73, 0xFB, 0x41, 0x70, 0x00, 0x00, 0x10, 0x00, 0x00,
310 0x00, 0x01, 0x63, 0x66, 0x69, 0x6E
Laurence Lundbladed711fb22018-09-26 14:35:22 -0700311};
312
313
Laurence Lundbladec5fef682020-01-25 11:38:45 -0800314int32_t DoubleAsSmallestTest()
Laurence Lundbladed711fb22018-09-26 14:35:22 -0700315{
Laurence Lundblade4fe9f312018-10-22 10:22:39 +0530316 UsefulBuf_MAKE_STACK_UB(EncodedHalfsMem, 420);
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800317
Laurence Lundblade067035b2018-11-28 17:35:25 -0800318#define QCBOREncode_AddDoubleAsSmallestToMap QCBOREncode_AddDoubleToMap
319#define QCBOREncode_AddDoubleAsSmallestToMapN QCBOREncode_AddDoubleToMapN
320
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800321
Laurence Lundbladed711fb22018-09-26 14:35:22 -0700322 QCBOREncodeContext EC;
323 QCBOREncode_Init(&EC, EncodedHalfsMem);
324 // These are mostly from https://en.wikipedia.org/wiki/Half-precision_floating-point_format
325 QCBOREncode_OpenMap(&EC);
326 // 64 # text(4)
327 // 7A65726F # "zero"
328 // F9 0000 # primitive(0)
329 QCBOREncode_AddDoubleAsSmallestToMap(&EC, "zero", 0.00);
330
331 // 64 # text(4)
332 // 7A65726F # "negative zero"
333 // F9 8000 # primitive(0)
334 QCBOREncode_AddDoubleAsSmallestToMap(&EC, "negative zero", -0.00);
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800335
Laurence Lundbladed711fb22018-09-26 14:35:22 -0700336 // 6A # text(10)
337 // 696E66696E6974697479 # "infinitity"
338 // F9 7C00 # primitive(31744)
339 QCBOREncode_AddDoubleAsSmallestToMap(&EC, "infinitity", INFINITY);
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800340
Laurence Lundbladed711fb22018-09-26 14:35:22 -0700341 // 73 # text(19)
342 // 6E6567617469766520696E66696E6974697479 # "negative infinitity"
343 // F9 FC00 # primitive(64512)
344 QCBOREncode_AddDoubleAsSmallestToMap(&EC, "negative infinitity", -INFINITY);
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800345
Laurence Lundbladed711fb22018-09-26 14:35:22 -0700346 // 63 # text(3)
347 // 4E614E # "NaN"
348 // F9 7E00 # primitive(32256)
349 QCBOREncode_AddDoubleAsSmallestToMap(&EC, "NaN", NAN);
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800350
Laurence Lundbladed711fb22018-09-26 14:35:22 -0700351 // TODO: test a few NaN variants
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800352
Laurence Lundbladed711fb22018-09-26 14:35:22 -0700353 // 63 # text(3)
354 // 6F6E65 # "one"
355 // F9 3C00 # primitive(15360)
356 QCBOREncode_AddDoubleAsSmallestToMap(&EC, "one", 1.0);
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800357
Laurence Lundbladed711fb22018-09-26 14:35:22 -0700358 // 69 # text(9)
359 // 6F6E65207468697264 # "one third"
360 // F9 3555 # primitive(13653)
361 QCBOREncode_AddDoubleAsSmallestToMap(&EC, "one third", 0.333251953125);
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800362
Laurence Lundbladed711fb22018-09-26 14:35:22 -0700363 // 76 # text(22)
Laurence Lundbladeee851742020-01-08 08:37:05 -0800364 // 6C6172676573742068616C662D707265636973696F6E # "largest half-precision"
Laurence Lundbladed711fb22018-09-26 14:35:22 -0700365 // F9 7BFF # primitive(31743)
366 QCBOREncode_AddDoubleAsSmallestToMap(&EC, "largest half-precision",65504.0);
367
368 // 76 # text(22)
Laurence Lundbladeee851742020-01-08 08:37:05 -0800369 // 6C6172676573742068616C662D707265636973696F6E # "largest half-precision"
Laurence Lundbladed711fb22018-09-26 14:35:22 -0700370 // F9 7BFF # primitive(31743)
371 QCBOREncode_AddDoubleAsSmallestToMap(&EC, "largest half-precision point one",65504.1);
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800372
Laurence Lundbladeee851742020-01-08 08:37:05 -0800373 // Float 65536.0F is 0x47800000 in hex. It has an exponent of 16, which
374 // is larger than 15, the largest half-precision exponent
Laurence Lundbladed711fb22018-09-26 14:35:22 -0700375 // 78 18 # text(24)
376 // 746F6F2D6C617267652068616C662D707265636973696F6E # "too-large half-precision"
377 // FA 47800000 # primitive(31743)
378 QCBOREncode_AddDoubleAsSmallestToMap(&EC, "too-large half-precision", 65536.0);
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800379
Laurence Lundbladed711fb22018-09-26 14:35:22 -0700380 // The smallest possible half-precision subnormal, but digitis are lost converting
381 // to half, so this turns into a double
382 // 72 # text(18)
383 // 736D616C6C657374207375626E6F726D616C # "smallest subnormal"
384 // FB 3E700000001C5F68 # primitive(4499096027744984936)
385 QCBOREncode_AddDoubleAsSmallestToMap(&EC, "smallest subnormal", 0.0000000596046448);
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800386
Laurence Lundbladed711fb22018-09-26 14:35:22 -0700387 // The smallest possible half-precision snormal, but digitis are lost converting
388 // to half, so this turns into a single TODO: confirm this is right
389 // 6F # text(15)
390 // 736D616C6C657374206E6F726D616C # "smallest normal"
391 // FA 387FFFFF # primitive(947912703)
392 // in hex single is 0x387fffff, exponent -15, significand 7fffff
393 QCBOREncode_AddDoubleAsSmallestToMap(&EC, "smallest normal", 0.0000610351526F);
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800394
Laurence Lundbladed711fb22018-09-26 14:35:22 -0700395 // 71 # text(17)
396 // 62696767657374207375626E6F726D616C # "biggest subnormal"
397 // F9 0400 # primitive(1024)
398 // in hex single is 0x38800000, exponent -14, significand 0
399 QCBOREncode_AddDoubleAsSmallestToMap(&EC, "biggest subnormal", 0.0000610351563F);
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800400
Laurence Lundbladed711fb22018-09-26 14:35:22 -0700401 // 70 # text(16)
402 // 7375626E6F726D616C2073696E676C65 # "subnormal single"
403 // FB 37C16C2800000000 # primitive(4017611261645684736)
404 QCBOREncode_AddDoubleAsSmallestToMap(&EC, "subnormal single", 4e-40F);
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800405
Laurence Lundbladed711fb22018-09-26 14:35:22 -0700406 // 03 # unsigned(3)
407 // F9 C000 # primitive(49152)
408 QCBOREncode_AddDoubleAsSmallestToMapN(&EC, 3, -2.0);
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800409
Laurence Lundbladed711fb22018-09-26 14:35:22 -0700410 // 70 # text(16)
411 // 6C617267652073696E676C6520657870 # "large single exp"
412 // FA 7F400000 # primitive(2134900736)
413 // (0x01LL << (DOUBLE_NUM_SIGNIFICAND_BITS-1)) | ((127LL + DOUBLE_EXPONENT_BIAS) << DOUBLE_EXPONENT_SHIFT);
414 QCBOREncode_AddDoubleAsSmallestToMap(&EC, "large single exp", 2.5521177519070385E+38); // Exponent fits single
415
416 // 74 # text(20)
417 // 746F6F2D6C617267652073696E676C6520657870 # "too-large single exp"
418 // FB 47F8000000000000 # primitive(5185894970917126144)
419 // (0x01LL << (DOUBLE_NUM_SIGNIFICAND_BITS-1)) | ((128LL + DOUBLE_EXPONENT_BIAS) << DOUBLE_EXPONENT_SHIFT);
Laurence Lundbladeee851742020-01-08 08:37:05 -0800420 // Exponent too large for single
421 QCBOREncode_AddDoubleAsSmallestToMap(&EC, "too-large single exp", 5.104235503814077E+38);
Laurence Lundbladed711fb22018-09-26 14:35:22 -0700422
423 // 66 # text(6)
424 // 646664666465 # "dfdfde"
425 // FA 4B800000 # primitive(1266679808)
Laurence Lundbladeee851742020-01-08 08:37:05 -0800426 // Single with no precision loss
427 QCBOREncode_AddDoubleAsSmallestToMap(&EC, "biggest single with prec", 16777216);
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800428
Laurence Lundbladed711fb22018-09-26 14:35:22 -0700429 // 78 18 # text(24)
430 // 626967676573742073696E676C6520776974682070726563 # "biggest single with prec"
431 // FA 4B800000 # primitive(1266679808)
Laurence Lundbladeee851742020-01-08 08:37:05 -0800432 // Double becuase of precision loss
433 QCBOREncode_AddDoubleAsSmallestToMap(&EC, "first single with prec loss", 16777217);
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800434
Laurence Lundbladed711fb22018-09-26 14:35:22 -0700435 // Just a convenient marker when cutting and pasting encoded CBOR
436 QCBOREncode_AddSZStringToMapN(&EC, 1, "fin");
437
438 QCBOREncode_CloseMap(&EC);
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800439
Laurence Lundblade781fd822018-10-01 09:37:52 -0700440 UsefulBufC EncodedHalfs;
Laurence Lundblade29497c02020-07-11 15:44:03 -0700441 QCBORError uErr = QCBOREncode_Finish(&EC, &EncodedHalfs);
442 if(uErr) {
Laurence Lundbladed711fb22018-09-26 14:35:22 -0700443 return -1;
444 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800445
Laurence Lundbladebb474be2018-10-22 11:53:21 +0530446 if(UsefulBuf_Compare(EncodedHalfs, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spExpectedSmallest))) {
Laurence Lundbladed711fb22018-09-26 14:35:22 -0700447 return -3;
448 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800449
Laurence Lundbladed711fb22018-09-26 14:35:22 -0700450 return 0;
Laurence Lundblade570fab52018-10-13 18:28:27 +0800451}
Laurence Lundblade585127a2020-07-15 03:25:24 -0700452#endif /* QCBOR_DISABLE_PREFERRED_FLOAT */
Laurence Lundbladed711fb22018-09-26 14:35:22 -0700453
454
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700455/*
456[0.0, 3.14, 0.0, NaN, Infinity, 0.0, 3.140000104904175, 0.0, NaN, Infinity,
457 {100: 0.0, 101: 3.1415926, "euler": 2.718281828459045, 105: 0.0,
458 102: 0.0, 103: 3.141592502593994, "euler2": 2.7182817459106445, 106: 0.0}]
459 */
Laurence Lundblade585127a2020-07-15 03:25:24 -0700460#ifndef QCBOR_DISABLE_PREFERRED_FLOAT
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700461static const uint8_t spExpectedFloats[] = {
462 0x8B,
463 0xF9, 0x00, 0x00,
464 0xFB, 0x40, 0x09, 0x1E, 0xB8, 0x51, 0xEB, 0x85, 0x1F,
465 0xFB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
466 0xFB, 0x7F, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
467 0xFB, 0x7F, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
468 0xF9, 0x00, 0x00,
469 0xFA, 0x40, 0x48, 0xF5, 0xC3,
470 0xFA, 0x00, 0x00, 0x00, 0x00,
471 0xFA, 0x7F, 0xC0, 0x00, 0x00,
472 0xFA, 0x7F, 0x80, 0x00, 0x00,
473 0xA8,
474 0x18, 0x64,
475 0xF9, 0x00, 0x00,
476 0x18, 0x65,
477 0xFB, 0x40, 0x09, 0x21, 0xFB, 0x4D, 0x12, 0xD8, 0x4A,
478 0x65, 0x65, 0x75, 0x6C, 0x65, 0x72,
479 0xFB, 0x40, 0x05, 0xBF, 0x0A, 0x8B, 0x14, 0x57, 0x69,
480 0x18, 0x69,
481 0xFB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
482 0x18, 0x66,
483 0xF9, 0x00, 0x00,
484 0x18, 0x67,
485 0xFA, 0x40, 0x49, 0x0F, 0xDA,
486 0x66, 0x65, 0x75, 0x6C, 0x65, 0x72, 0x32,
487 0xFA, 0x40, 0x2D, 0xF8, 0x54,
488 0x18, 0x6A,
489 0xFA, 0x00, 0x00, 0x00, 0x00};
Laurence Lundblade585127a2020-07-15 03:25:24 -0700490#else
491static const uint8_t spExpectedFloats[] = {
492 0x8B,
493 0xFB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
494 0xFB, 0x40, 0x09, 0x1E, 0xB8, 0x51, 0xEB, 0x85, 0x1F,
495 0xFB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
496 0xFB, 0x7F, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
497 0xFB, 0x7F, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
498 0xFA, 0x00, 0x00, 0x00, 0x00,
499 0xFA, 0x40, 0x48, 0xF5, 0xC3,
500 0xFA, 0x00, 0x00, 0x00, 0x00,
501 0xFA, 0x7F, 0xC0, 0x00, 0x00,
502 0xFA, 0x7F, 0x80, 0x00, 0x00,
503 0xA8,
504 0x18, 0x64,
505 0xFB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
506 0x18, 0x65,
507 0xFB, 0x40, 0x09, 0x21, 0xFB, 0x4D, 0x12, 0xD8, 0x4A,
508 0x65, 0x65, 0x75, 0x6C, 0x65, 0x72,
509 0xFB, 0x40, 0x05, 0xBF, 0x0A, 0x8B, 0x14, 0x57, 0x69,
510 0x18, 0x69,
511 0xFB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
512 0x18, 0x66,
513 0xFA, 0x00, 0x00, 0x00, 0x00,
514 0x18, 0x67,
515 0xFA, 0x40, 0x49, 0x0F, 0xDA,
516 0x66, 0x65, 0x75, 0x6C, 0x65, 0x72, 0x32,
517 0xFA, 0x40, 0x2D, 0xF8, 0x54,
518 0x18, 0x6A,
519 0xFA, 0x00, 0x00, 0x00, 0x00};
520#endif /* QCBOR_DISABLE_PREFERRED_FLOAT */
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700521
522int32_t GeneralFloatEncodeTests()
523{
524 UsefulBuf_MAKE_STACK_UB(OutBuffer, sizeof(spExpectedFloats));
525
526 QCBOREncodeContext EC;
527 QCBOREncode_Init(&EC, OutBuffer);
528 QCBOREncode_OpenArray(&EC);
529
530 QCBOREncode_AddDouble(&EC, 0.0);
531 QCBOREncode_AddDouble(&EC, 3.14);
532 QCBOREncode_AddDoubleNoPreferred(&EC, 0.0);
533 QCBOREncode_AddDoubleNoPreferred(&EC, NAN);
534 QCBOREncode_AddDoubleNoPreferred(&EC, INFINITY);
535
536 QCBOREncode_AddFloat(&EC, 0.0);
537 QCBOREncode_AddFloat(&EC, 3.14f);
538 QCBOREncode_AddFloatNoPreferred(&EC, 0.0f);
539 QCBOREncode_AddFloatNoPreferred(&EC, NAN);
540 QCBOREncode_AddFloatNoPreferred(&EC, INFINITY);
541
542 QCBOREncode_OpenMap(&EC);
543
544 QCBOREncode_AddDoubleToMapN(&EC, 100, 0.0);
545 QCBOREncode_AddDoubleToMapN(&EC, 101, 3.1415926);
546 QCBOREncode_AddDoubleToMap(&EC, "euler", 2.71828182845904523536);
547 QCBOREncode_AddDoubleNoPreferredToMapN(&EC, 105, 0.0);
548
549 QCBOREncode_AddFloatToMapN(&EC, 102, 0.0f);
550 QCBOREncode_AddFloatToMapN(&EC, 103, 3.1415926f);
551 QCBOREncode_AddFloatToMap(&EC, "euler2", 2.71828182845904523536f);
552 QCBOREncode_AddFloatNoPreferredToMapN(&EC, 106, 0.0f);
553
554 QCBOREncode_CloseMap(&EC);
555 QCBOREncode_CloseArray(&EC);
556
557 UsefulBufC Encoded;
558 QCBORError uErr = QCBOREncode_Finish(&EC, &Encoded);
559 if(uErr) {
Laurence Lundblade585127a2020-07-15 03:25:24 -0700560 return -1;
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700561 }
562
563 if(UsefulBuf_Compare(Encoded, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spExpectedFloats))) {
Laurence Lundblade585127a2020-07-15 03:25:24 -0700564 return -3;
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700565 }
566
567 return 0;
568}
569
570
Laurence Lundbladed711fb22018-09-26 14:35:22 -0700571
Laurence Lundblade7d40d812018-09-30 02:44:01 -0700572#ifdef NAN_EXPERIMENT
573/*
574 Code for checking what the double to float cast does with
575 NaNs. Not run as part of tests. Keep it around to
576 be able to check various platforms and CPUs.
577 */
578
579#define DOUBLE_NUM_SIGNIFICAND_BITS (52)
580#define DOUBLE_NUM_EXPONENT_BITS (11)
581#define DOUBLE_NUM_SIGN_BITS (1)
582
583#define DOUBLE_SIGNIFICAND_SHIFT (0)
584#define DOUBLE_EXPONENT_SHIFT (DOUBLE_NUM_SIGNIFICAND_BITS)
585#define DOUBLE_SIGN_SHIFT (DOUBLE_NUM_SIGNIFICAND_BITS + DOUBLE_NUM_EXPONENT_BITS)
586
587#define DOUBLE_SIGNIFICAND_MASK (0xfffffffffffffULL) // The lower 52 bits
588#define DOUBLE_EXPONENT_MASK (0x7ffULL << DOUBLE_EXPONENT_SHIFT) // 11 bits of exponent
589#define DOUBLE_SIGN_MASK (0x01ULL << DOUBLE_SIGN_SHIFT) // 1 bit of sign
590#define DOUBLE_QUIET_NAN_BIT (0x01ULL << (DOUBLE_NUM_SIGNIFICAND_BITS-1))
591
592
593static int NaNExperiments() {
594 double dqNaN = UsefulBufUtil_CopyUint64ToDouble(DOUBLE_EXPONENT_MASK | DOUBLE_QUIET_NAN_BIT);
595 double dsNaN = UsefulBufUtil_CopyUint64ToDouble(DOUBLE_EXPONENT_MASK | 0x01);
596 double dqNaNPayload = UsefulBufUtil_CopyUint64ToDouble(DOUBLE_EXPONENT_MASK | DOUBLE_QUIET_NAN_BIT | 0xf00f);
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800597
Laurence Lundblade7d40d812018-09-30 02:44:01 -0700598 float f1 = (float)dqNaN;
599 float f2 = (float)dsNaN;
600 float f3 = (float)dqNaNPayload;
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800601
602
Laurence Lundblade7d40d812018-09-30 02:44:01 -0700603 uint32_t uqNaN = UsefulBufUtil_CopyFloatToUint32((float)dqNaN);
604 uint32_t usNaN = UsefulBufUtil_CopyFloatToUint32((float)dsNaN);
605 uint32_t uqNaNPayload = UsefulBufUtil_CopyFloatToUint32((float)dqNaNPayload);
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800606
Laurence Lundblade7d40d812018-09-30 02:44:01 -0700607 // Result of this on x86 is that every NaN is a qNaN. The intel
608 // CVTSD2SS instruction ignores the NaN payload and even converts
609 // a sNaN to a qNaN.
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800610
Laurence Lundblade7d40d812018-09-30 02:44:01 -0700611 return 0;
612}
613#endif
614
615
Laurence Lundbladed711fb22018-09-26 14:35:22 -0700616