blob: 4ad4a9a16aff5edcc42745b50640b9103b23d8c2 [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 Lundblade2aa0b572020-07-16 19:48:42 -070013
14#include "float_tests.h"
Laurence Lundblade585127a2020-07-15 03:25:24 -070015#include "qcbor/qcbor_encode.h"
16#include <math.h> // For INFINITY and NAN and isnan()
17
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -070018#ifndef QCBOR_DISABLE_PREFERRED_FLOAT
Laurence Lundblade9682a532020-06-06 18:33:04 -070019
Laurence Lundblade844bb5c2020-03-01 17:27:25 -080020#include "qcbor/qcbor_decode.h"
Laurence Lundbladed711fb22018-09-26 14:35:22 -070021#include "half_to_double_from_rfc7049.h"
Laurence Lundblade68a13352018-09-23 02:19:54 -070022
Laurence Lundblade2d85ce42018-10-12 14:12:47 +080023
Laurence Lundblade2d85ce42018-10-12 14:12:47 +080024
Laurence Lundbladebb474be2018-10-22 11:53:21 +053025static const uint8_t spExpectedHalf[] = {
Laurence Lundblade7d40d812018-09-30 02:44:01 -070026 0xB1,
Laurence Lundblade68a13352018-09-23 02:19:54 -070027 0x64,
28 0x7A, 0x65, 0x72, 0x6F,
29 0xF9, 0x00, 0x00, // 0.000
30 0x6A,
31 0x69, 0x6E, 0x66, 0x69, 0x6E, 0x69, 0x74, 0x69, 0x74, 0x79,
32 0xF9, 0x7C, 0x00, // Infinity
33 0x73,
Laurence Lundbladeee851742020-01-08 08:37:05 -080034 0x6E, 0x65, 0x67, 0x61, 0x74, 0x69, 0x76, 0x65, 0x20, 0x69, 0x6E,
35 0x66, 0x69, 0x6E, 0x69, 0x74, 0x69, 0x74, 0x79,
Laurence Lundblade68a13352018-09-23 02:19:54 -070036 0xF9, 0xFC, 0x00, // -Inifinity
37 0x63,
38 0x4E, 0x61, 0x4E,
39 0xF9, 0x7E, 0x00, // NaN
40 0x63,
41 0x6F, 0x6E, 0x65,
42 0xF9, 0x3C, 0x00, // 1.0
43 0x69,
44 0x6F, 0x6E, 0x65, 0x20, 0x74, 0x68, 0x69, 0x72, 0x64,
45 0xF9, 0x35, 0x55, // 0.333251953125
46 0x76,
Laurence Lundbladeee851742020-01-08 08:37:05 -080047 0x6C, 0x61, 0x72, 0x67, 0x65, 0x73, 0x74, 0x20, 0x68, 0x61, 0x6C,
48 0x66, 0x2D, 0x70, 0x72, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6F, 0x6E,
Laurence Lundblade68a13352018-09-23 02:19:54 -070049 0xF9, 0x7B, 0xFF, // 65504.0
Laurence Lundbladeee851742020-01-08 08:37:05 -080050 0x78, 0x18,
51 0x74, 0x6F, 0x6F, 0x2D, 0x6C, 0x61, 0x72, 0x67, 0x65, 0x20, 0x68,
52 0x61, 0x6C, 0x66, 0x2D, 0x70, 0x72, 0x65, 0x63, 0x69, 0x73, 0x69,
53 0x6F, 0x6E,
Laurence Lundblade68a13352018-09-23 02:19:54 -070054 0xF9, 0x7C, 0x00, // Infinity
55 0x72,
Laurence Lundbladeee851742020-01-08 08:37:05 -080056 0x73, 0x6D, 0x61, 0x6C, 0x6C, 0x65, 0x73, 0x74, 0x20, 0x73, 0x75,
57 0x62, 0x6E, 0x6F, 0x72, 0x6D, 0x61, 0x6C,
Laurence Lundblade68a13352018-09-23 02:19:54 -070058 0xF9, 0x00, 0x01, // 0.000000059604
59 0x6F,
Laurence Lundbladeee851742020-01-08 08:37:05 -080060 0x73, 0x6D, 0x61, 0x6C, 0x6C, 0x65, 0x73, 0x74, 0x20, 0x6E, 0x6F,
61 0x72, 0x6D, 0x61, 0x6C,
Laurence Lundblade68a13352018-09-23 02:19:54 -070062 0xF9, 0x03, 0xFF, // 0.0000609755516
63 0x71,
Laurence Lundbladeee851742020-01-08 08:37:05 -080064 0x62, 0x69, 0x67, 0x67, 0x65, 0x73, 0x74, 0x20, 0x73, 0x75, 0x62,
65 0x6E, 0x6F, 0x72, 0x6D, 0x61, 0x6C,
Laurence Lundblade68a13352018-09-23 02:19:54 -070066 0xF9, 0x04, 0x00, // 0.000061988
67 0x70,
Laurence Lundbladeee851742020-01-08 08:37:05 -080068 0x73, 0x75, 0x62, 0x6E, 0x6F, 0x72, 0x6D, 0x61, 0x6C, 0x20, 0x73,
69 0x69, 0x6E, 0x67, 0x6C, 0x65,
Laurence Lundblade68a13352018-09-23 02:19:54 -070070 0xF9, 0x00, 0x00,
71 0x03,
Laurence Lundblade7d40d812018-09-30 02:44:01 -070072 0xF9, 0xC0, 0x00, // -2
73 0x04,
74 0xF9, 0x7E, 0x00, // qNaN
75 0x05,
76 0xF9, 0x7C, 0x01, // sNaN
77 0x06,
78 0xF9, 0x7E, 0x0F, // qNaN with payload 0x0f
79 0x07,
80 0xF9, 0x7C, 0x0F, // sNaN with payload 0x0f
Laurence Lundblade3aee3a32018-12-17 16:17:45 -080081
Laurence Lundblade68a13352018-09-23 02:19:54 -070082};
83
84
Laurence Lundbladec5fef682020-01-25 11:38:45 -080085int32_t HalfPrecisionDecodeBasicTests()
Laurence Lundblade68a13352018-09-23 02:19:54 -070086{
Laurence Lundbladebb474be2018-10-22 11:53:21 +053087 UsefulBufC HalfPrecision = UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spExpectedHalf);
Laurence Lundblade3aee3a32018-12-17 16:17:45 -080088
Laurence Lundblade68a13352018-09-23 02:19:54 -070089 QCBORDecodeContext DC;
90 QCBORDecode_Init(&DC, HalfPrecision, 0);
Laurence Lundblade3aee3a32018-12-17 16:17:45 -080091
Laurence Lundblade68a13352018-09-23 02:19:54 -070092 QCBORItem Item;
93
94 QCBORDecode_GetNext(&DC, &Item);
95 if(Item.uDataType != QCBOR_TYPE_MAP) {
96 return -1;
97 }
98
99 QCBORDecode_GetNext(&DC, &Item);
Laurence Lundblade67bd5512018-11-02 21:44:06 +0700100 if(Item.uDataType != QCBOR_TYPE_DOUBLE || Item.val.dfnum != 0.0F) {
Laurence Lundblade7d40d812018-09-30 02:44:01 -0700101 return -2;
Laurence Lundblade68a13352018-09-23 02:19:54 -0700102 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800103
Laurence Lundblade68a13352018-09-23 02:19:54 -0700104 QCBORDecode_GetNext(&DC, &Item);
Laurence Lundblade67bd5512018-11-02 21:44:06 +0700105 if(Item.uDataType != QCBOR_TYPE_DOUBLE || Item.val.dfnum != INFINITY) {
Laurence Lundblade7d40d812018-09-30 02:44:01 -0700106 return -3;
Laurence Lundblade68a13352018-09-23 02:19:54 -0700107 }
108
109 QCBORDecode_GetNext(&DC, &Item);
Laurence Lundblade67bd5512018-11-02 21:44:06 +0700110 if(Item.uDataType != QCBOR_TYPE_DOUBLE || Item.val.dfnum != -INFINITY) {
Laurence Lundblade7d40d812018-09-30 02:44:01 -0700111 return -4;
Laurence Lundblade68a13352018-09-23 02:19:54 -0700112 }
113
Laurence Lundbladeee851742020-01-08 08:37:05 -0800114 // TODO, is this really converting right? It is carrying payload, but
115 // this confuses things.
116 QCBORDecode_GetNext(&DC, &Item);
Laurence Lundblade67bd5512018-11-02 21:44:06 +0700117 if(Item.uDataType != QCBOR_TYPE_DOUBLE || !isnan(Item.val.dfnum)) {
Laurence Lundblade7d40d812018-09-30 02:44:01 -0700118 return -5;
Laurence Lundblade68a13352018-09-23 02:19:54 -0700119 }
120
121 QCBORDecode_GetNext(&DC, &Item);
Laurence Lundblade67bd5512018-11-02 21:44:06 +0700122 if(Item.uDataType != QCBOR_TYPE_DOUBLE || Item.val.dfnum != 1.0F) {
Laurence Lundblade7d40d812018-09-30 02:44:01 -0700123 return -6;
Laurence Lundblade68a13352018-09-23 02:19:54 -0700124 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800125
Laurence Lundblade68a13352018-09-23 02:19:54 -0700126 QCBORDecode_GetNext(&DC, &Item);
Laurence Lundblade67bd5512018-11-02 21:44:06 +0700127 if(Item.uDataType != QCBOR_TYPE_DOUBLE || Item.val.dfnum != 0.333251953125F) {
Laurence Lundblade7d40d812018-09-30 02:44:01 -0700128 return -7;
Laurence Lundblade68a13352018-09-23 02:19:54 -0700129 }
130
131 QCBORDecode_GetNext(&DC, &Item);
Laurence Lundblade67bd5512018-11-02 21:44:06 +0700132 if(Item.uDataType != QCBOR_TYPE_DOUBLE || Item.val.dfnum != 65504.0F) {
Laurence Lundblade7d40d812018-09-30 02:44:01 -0700133 return -8;
Laurence Lundblade68a13352018-09-23 02:19:54 -0700134 }
135
136 QCBORDecode_GetNext(&DC, &Item);
Laurence Lundblade67bd5512018-11-02 21:44:06 +0700137 if(Item.uDataType != QCBOR_TYPE_DOUBLE || Item.val.dfnum != INFINITY) {
Laurence Lundblade7d40d812018-09-30 02:44:01 -0700138 return -9;
Laurence Lundblade68a13352018-09-23 02:19:54 -0700139 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800140
Laurence Lundblade68a13352018-09-23 02:19:54 -0700141 QCBORDecode_GetNext(&DC, &Item); // TODO: check this
Laurence Lundblade67bd5512018-11-02 21:44:06 +0700142 if(Item.uDataType != QCBOR_TYPE_DOUBLE || Item.val.dfnum != 0.0000000596046448F) {
Laurence Lundblade7d40d812018-09-30 02:44:01 -0700143 return -10;
Laurence Lundblade68a13352018-09-23 02:19:54 -0700144 }
145
146 QCBORDecode_GetNext(&DC, &Item); // TODO: check this
Laurence Lundblade67bd5512018-11-02 21:44:06 +0700147 if(Item.uDataType != QCBOR_TYPE_DOUBLE || Item.val.dfnum != 0.0000609755516F) {
Laurence Lundblade7d40d812018-09-30 02:44:01 -0700148 return -11;
Laurence Lundblade68a13352018-09-23 02:19:54 -0700149 }
150
151 QCBORDecode_GetNext(&DC, &Item); // TODO check this
Laurence Lundblade67bd5512018-11-02 21:44:06 +0700152 if(Item.uDataType != QCBOR_TYPE_DOUBLE || Item.val.dfnum != 0.0000610351563F) {
Laurence Lundblade7d40d812018-09-30 02:44:01 -0700153 return -12;
Laurence Lundblade68a13352018-09-23 02:19:54 -0700154 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800155
156 QCBORDecode_GetNext(&DC, &Item);
Laurence Lundblade67bd5512018-11-02 21:44:06 +0700157 if(Item.uDataType != QCBOR_TYPE_DOUBLE || Item.val.dfnum != 0) {
Laurence Lundblade7d40d812018-09-30 02:44:01 -0700158 return -13;
Laurence Lundblade68a13352018-09-23 02:19:54 -0700159 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800160
Laurence Lundblade68a13352018-09-23 02:19:54 -0700161 QCBORDecode_GetNext(&DC, &Item);
Laurence Lundblade67bd5512018-11-02 21:44:06 +0700162 if(Item.uDataType != QCBOR_TYPE_DOUBLE || Item.val.dfnum != -2.0F) {
Laurence Lundblade7d40d812018-09-30 02:44:01 -0700163 return -14;
164 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800165
Laurence Lundblade67bd5512018-11-02 21:44:06 +0700166 // TODO: double check these four tests
167 QCBORDecode_GetNext(&DC, &Item); // qNaN
Laurence Lundbladeee851742020-01-08 08:37:05 -0800168 if(Item.uDataType != QCBOR_TYPE_DOUBLE ||
169 UsefulBufUtil_CopyDoubleToUint64(Item.val.dfnum) != 0x7ff8000000000000ULL) {
Laurence Lundblade7d40d812018-09-30 02:44:01 -0700170 return -15;
171 }
Laurence Lundblade67bd5512018-11-02 21:44:06 +0700172 QCBORDecode_GetNext(&DC, &Item); // sNaN
Laurence Lundbladeee851742020-01-08 08:37:05 -0800173 if(Item.uDataType != QCBOR_TYPE_DOUBLE ||
174 UsefulBufUtil_CopyDoubleToUint64(Item.val.dfnum) != 0x7ff0000000000001ULL) {
Laurence Lundblade7d40d812018-09-30 02:44:01 -0700175 return -16;
176 }
Laurence Lundblade67bd5512018-11-02 21:44:06 +0700177 QCBORDecode_GetNext(&DC, &Item); // qNaN with payload 0x0f
Laurence Lundbladeee851742020-01-08 08:37:05 -0800178 if(Item.uDataType != QCBOR_TYPE_DOUBLE ||
179 UsefulBufUtil_CopyDoubleToUint64(Item.val.dfnum) != 0x7ff800000000000fULL) {
Laurence Lundblade7d40d812018-09-30 02:44:01 -0700180 return -17;
181 }
Laurence Lundblade67bd5512018-11-02 21:44:06 +0700182 QCBORDecode_GetNext(&DC, &Item); // sNaN with payload 0x0f
Laurence Lundbladeee851742020-01-08 08:37:05 -0800183 if(Item.uDataType != QCBOR_TYPE_DOUBLE ||
184 UsefulBufUtil_CopyDoubleToUint64(Item.val.dfnum) != 0x7ff000000000000fULL) {
Laurence Lundblade7d40d812018-09-30 02:44:01 -0700185 return -18;
Laurence Lundblade68a13352018-09-23 02:19:54 -0700186 }
Laurence Lundblade67bd5512018-11-02 21:44:06 +0700187
Laurence Lundblade68a13352018-09-23 02:19:54 -0700188 if(QCBORDecode_Finish(&DC)) {
Laurence Lundblade7d40d812018-09-30 02:44:01 -0700189 return -19;
Laurence Lundblade68a13352018-09-23 02:19:54 -0700190 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800191
Laurence Lundblade68a13352018-09-23 02:19:54 -0700192 return 0;
193}
Laurence Lundbladed711fb22018-09-26 14:35:22 -0700194
195
Laurence Lundbladed711fb22018-09-26 14:35:22 -0700196
197
Laurence Lundbladec5fef682020-01-25 11:38:45 -0800198int32_t HalfPrecisionAgainstRFCCodeTest()
Laurence Lundbladed711fb22018-09-26 14:35:22 -0700199{
Laurence Lundblade7d40d812018-09-30 02:44:01 -0700200 for(uint32_t uHalfP = 0; uHalfP < 0xffff; uHalfP += 60) {
Laurence Lundbladed711fb22018-09-26 14:35:22 -0700201 unsigned char x[2];
Laurence Lundbladec5fef682020-01-25 11:38:45 -0800202 x[1] = (uint8_t)(uHalfP & 0xff);
203 x[0] = (uint8_t)(uHalfP >> 8); // uHalfP is always less than 0xffff
Laurence Lundbladed711fb22018-09-26 14:35:22 -0700204 double d = decode_half(x);
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800205
Laurence Lundbladed711fb22018-09-26 14:35:22 -0700206 // Contruct the CBOR for the half-precision float by hand
Laurence Lundblade4fe9f312018-10-22 10:22:39 +0530207 UsefulBuf_MAKE_STACK_UB(__xx, 3);
Laurence Lundbladed711fb22018-09-26 14:35:22 -0700208 UsefulOutBuf UOB;
209 UsefulOutBuf_Init(&UOB, __xx);
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800210
Laurence Lundbladec5fef682020-01-25 11:38:45 -0800211 const uint8_t uHalfPrecInitialByte = (uint8_t)(HALF_PREC_FLOAT + (CBOR_MAJOR_TYPE_SIMPLE << 5)); // 0xf9
Laurence Lundbladed711fb22018-09-26 14:35:22 -0700212 UsefulOutBuf_AppendByte(&UOB, uHalfPrecInitialByte); // The initial byte for a half-precision float
213 UsefulOutBuf_AppendUint16(&UOB, (uint16_t)uHalfP);
214
Laurence Lundbladeee851742020-01-08 08:37:05 -0800215 // Now parse the hand-constructed CBOR. This will invoke the
216 // conversion to a float
Laurence Lundbladed711fb22018-09-26 14:35:22 -0700217 QCBORDecodeContext DC;
218 QCBORDecode_Init(&DC, UsefulOutBuf_OutUBuf(&UOB), 0);
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800219
Laurence Lundbladed711fb22018-09-26 14:35:22 -0700220 QCBORItem Item;
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800221
Laurence Lundbladed711fb22018-09-26 14:35:22 -0700222 QCBORDecode_GetNext(&DC, &Item);
Laurence Lundblade67bd5512018-11-02 21:44:06 +0700223 if(Item.uDataType != QCBOR_TYPE_DOUBLE) {
Laurence Lundbladed711fb22018-09-26 14:35:22 -0700224 return -1;
225 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800226
Laurence Lundbladeee851742020-01-08 08:37:05 -0800227 //printf("%04x QCBOR:%15.15f RFC: %15.15f (%8x)\n",
228 // uHalfP, Item.val.fnum, d , UsefulBufUtil_CopyFloatToUint32(d));
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800229
Laurence Lundblade7d40d812018-09-30 02:44:01 -0700230 if(isnan(d)) {
231 // The RFC code uses the native instructions which may or may not
232 // handle sNaN, qNaN and NaN payloads correctly. This test just
233 // makes sure it is a NaN and doesn't worry about the type of NaN
Laurence Lundblade67bd5512018-11-02 21:44:06 +0700234 if(!isnan(Item.val.dfnum)) {
Laurence Lundblade7d40d812018-09-30 02:44:01 -0700235 return -3;
236 }
237 } else {
Laurence Lundblade67bd5512018-11-02 21:44:06 +0700238 if(Item.val.dfnum != d) {
Laurence Lundblade7d40d812018-09-30 02:44:01 -0700239 return -2;
240 }
Laurence Lundbladed711fb22018-09-26 14:35:22 -0700241 }
242 }
243 return 0;
244}
245
246
247/*
Laurence Lundbladebb474be2018-10-22 11:53:21 +0530248 {"zero": 0.0,
249 "negative zero": -0.0,
250 "infinitity": Infinity,
251 "negative infinitity": -Infinity,
252 "NaN": NaN,
253 "one": 1.0,
254 "one third": 0.333251953125,
255 "largest half-precision": 65504.0,
256 "largest half-precision point one": 65504.1,
257 "too-large half-precision": 65536.0,
258 "smallest subnormal": 5.96046448e-8,
259 "smallest normal": 0.00006103515261202119,
260 "biggest subnormal": 0.00006103515625,
261 "subnormal single": 4.00000646641519e-40,
262 3: -2.0,
263 "large single exp": 2.5521177519070385e+38,
264 "too-large single exp": 5.104235503814077e+38,
265 "biggest single with prec": 16777216.0,
266 "first single with prec loss": 16777217.0,
267 1: "fin"}
Laurence Lundbladed711fb22018-09-26 14:35:22 -0700268 */
Laurence Lundbladebb474be2018-10-22 11:53:21 +0530269static const uint8_t spExpectedSmallest[] = {
270 0xB4, 0x64, 0x7A, 0x65, 0x72, 0x6F, 0xF9, 0x00, 0x00, 0x6D,
271 0x6E, 0x65, 0x67, 0x61, 0x74, 0x69, 0x76, 0x65, 0x20, 0x7A,
272 0x65, 0x72, 0x6F, 0xF9, 0x80, 0x00, 0x6A, 0x69, 0x6E, 0x66,
273 0x69, 0x6E, 0x69, 0x74, 0x69, 0x74, 0x79, 0xF9, 0x7C, 0x00,
274 0x73, 0x6E, 0x65, 0x67, 0x61, 0x74, 0x69, 0x76, 0x65, 0x20,
275 0x69, 0x6E, 0x66, 0x69, 0x6E, 0x69, 0x74, 0x69, 0x74, 0x79,
276 0xF9, 0xFC, 0x00, 0x63, 0x4E, 0x61, 0x4E, 0xF9, 0x7E, 0x00,
277 0x63, 0x6F, 0x6E, 0x65, 0xF9, 0x3C, 0x00, 0x69, 0x6F, 0x6E,
278 0x65, 0x20, 0x74, 0x68, 0x69, 0x72, 0x64, 0xF9, 0x35, 0x55,
279 0x76, 0x6C, 0x61, 0x72, 0x67, 0x65, 0x73, 0x74, 0x20, 0x68,
280 0x61, 0x6C, 0x66, 0x2D, 0x70, 0x72, 0x65, 0x63, 0x69, 0x73,
281 0x69, 0x6F, 0x6E, 0xF9, 0x7B, 0xFF, 0x78, 0x20, 0x6C, 0x61,
282 0x72, 0x67, 0x65, 0x73, 0x74, 0x20, 0x68, 0x61, 0x6C, 0x66,
283 0x2D, 0x70, 0x72, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6F, 0x6E,
284 0x20, 0x70, 0x6F, 0x69, 0x6E, 0x74, 0x20, 0x6F, 0x6E, 0x65,
285 0xFB, 0x40, 0xEF, 0xFC, 0x03, 0x33, 0x33, 0x33, 0x33, 0x78,
286 0x18, 0x74, 0x6F, 0x6F, 0x2D, 0x6C, 0x61, 0x72, 0x67, 0x65,
287 0x20, 0x68, 0x61, 0x6C, 0x66, 0x2D, 0x70, 0x72, 0x65, 0x63,
288 0x69, 0x73, 0x69, 0x6F, 0x6E, 0xFA, 0x47, 0x80, 0x00, 0x00,
289 0x72, 0x73, 0x6D, 0x61, 0x6C, 0x6C, 0x65, 0x73, 0x74, 0x20,
290 0x73, 0x75, 0x62, 0x6E, 0x6F, 0x72, 0x6D, 0x61, 0x6C, 0xFB,
291 0x3E, 0x70, 0x00, 0x00, 0x00, 0x1C, 0x5F, 0x68, 0x6F, 0x73,
292 0x6D, 0x61, 0x6C, 0x6C, 0x65, 0x73, 0x74, 0x20, 0x6E, 0x6F,
293 0x72, 0x6D, 0x61, 0x6C, 0xFA, 0x38, 0x7F, 0xFF, 0xFF, 0x71,
294 0x62, 0x69, 0x67, 0x67, 0x65, 0x73, 0x74, 0x20, 0x73, 0x75,
295 0x62, 0x6E, 0x6F, 0x72, 0x6D, 0x61, 0x6C, 0xF9, 0x04, 0x00,
296 0x70, 0x73, 0x75, 0x62, 0x6E, 0x6F, 0x72, 0x6D, 0x61, 0x6C,
297 0x20, 0x73, 0x69, 0x6E, 0x67, 0x6C, 0x65, 0xFB, 0x37, 0xC1,
298 0x6C, 0x28, 0x00, 0x00, 0x00, 0x00, 0x03, 0xF9, 0xC0, 0x00,
299 0x70, 0x6C, 0x61, 0x72, 0x67, 0x65, 0x20, 0x73, 0x69, 0x6E,
300 0x67, 0x6C, 0x65, 0x20, 0x65, 0x78, 0x70, 0xFA, 0x7F, 0x40,
301 0x00, 0x00, 0x74, 0x74, 0x6F, 0x6F, 0x2D, 0x6C, 0x61, 0x72,
302 0x67, 0x65, 0x20, 0x73, 0x69, 0x6E, 0x67, 0x6C, 0x65, 0x20,
303 0x65, 0x78, 0x70, 0xFB, 0x47, 0xF8, 0x00, 0x00, 0x00, 0x00,
304 0x00, 0x00, 0x78, 0x18, 0x62, 0x69, 0x67, 0x67, 0x65, 0x73,
305 0x74, 0x20, 0x73, 0x69, 0x6E, 0x67, 0x6C, 0x65, 0x20, 0x77,
306 0x69, 0x74, 0x68, 0x20, 0x70, 0x72, 0x65, 0x63, 0xFA, 0x4B,
307 0x80, 0x00, 0x00, 0x78, 0x1B, 0x66, 0x69, 0x72, 0x73, 0x74,
308 0x20, 0x73, 0x69, 0x6E, 0x67, 0x6C, 0x65, 0x20, 0x77, 0x69,
309 0x74, 0x68, 0x20, 0x70, 0x72, 0x65, 0x63, 0x20, 0x6C, 0x6F,
310 0x73, 0x73, 0xFB, 0x41, 0x70, 0x00, 0x00, 0x10, 0x00, 0x00,
311 0x00, 0x01, 0x63, 0x66, 0x69, 0x6E
Laurence Lundbladed711fb22018-09-26 14:35:22 -0700312};
313
314
Laurence Lundbladec5fef682020-01-25 11:38:45 -0800315int32_t DoubleAsSmallestTest()
Laurence Lundbladed711fb22018-09-26 14:35:22 -0700316{
Laurence Lundblade4fe9f312018-10-22 10:22:39 +0530317 UsefulBuf_MAKE_STACK_UB(EncodedHalfsMem, 420);
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800318
Laurence Lundblade067035b2018-11-28 17:35:25 -0800319#define QCBOREncode_AddDoubleAsSmallestToMap QCBOREncode_AddDoubleToMap
320#define QCBOREncode_AddDoubleAsSmallestToMapN QCBOREncode_AddDoubleToMapN
321
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800322
Laurence Lundbladed711fb22018-09-26 14:35:22 -0700323 QCBOREncodeContext EC;
324 QCBOREncode_Init(&EC, EncodedHalfsMem);
325 // These are mostly from https://en.wikipedia.org/wiki/Half-precision_floating-point_format
326 QCBOREncode_OpenMap(&EC);
327 // 64 # text(4)
328 // 7A65726F # "zero"
329 // F9 0000 # primitive(0)
330 QCBOREncode_AddDoubleAsSmallestToMap(&EC, "zero", 0.00);
331
332 // 64 # text(4)
333 // 7A65726F # "negative zero"
334 // F9 8000 # primitive(0)
335 QCBOREncode_AddDoubleAsSmallestToMap(&EC, "negative zero", -0.00);
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800336
Laurence Lundbladed711fb22018-09-26 14:35:22 -0700337 // 6A # text(10)
338 // 696E66696E6974697479 # "infinitity"
339 // F9 7C00 # primitive(31744)
340 QCBOREncode_AddDoubleAsSmallestToMap(&EC, "infinitity", INFINITY);
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800341
Laurence Lundbladed711fb22018-09-26 14:35:22 -0700342 // 73 # text(19)
343 // 6E6567617469766520696E66696E6974697479 # "negative infinitity"
344 // F9 FC00 # primitive(64512)
345 QCBOREncode_AddDoubleAsSmallestToMap(&EC, "negative infinitity", -INFINITY);
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800346
Laurence Lundbladed711fb22018-09-26 14:35:22 -0700347 // 63 # text(3)
348 // 4E614E # "NaN"
349 // F9 7E00 # primitive(32256)
350 QCBOREncode_AddDoubleAsSmallestToMap(&EC, "NaN", NAN);
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800351
Laurence Lundbladed711fb22018-09-26 14:35:22 -0700352 // TODO: test a few NaN variants
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800353
Laurence Lundbladed711fb22018-09-26 14:35:22 -0700354 // 63 # text(3)
355 // 6F6E65 # "one"
356 // F9 3C00 # primitive(15360)
357 QCBOREncode_AddDoubleAsSmallestToMap(&EC, "one", 1.0);
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800358
Laurence Lundbladed711fb22018-09-26 14:35:22 -0700359 // 69 # text(9)
360 // 6F6E65207468697264 # "one third"
361 // F9 3555 # primitive(13653)
362 QCBOREncode_AddDoubleAsSmallestToMap(&EC, "one third", 0.333251953125);
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800363
Laurence Lundbladed711fb22018-09-26 14:35:22 -0700364 // 76 # text(22)
Laurence Lundbladeee851742020-01-08 08:37:05 -0800365 // 6C6172676573742068616C662D707265636973696F6E # "largest half-precision"
Laurence Lundbladed711fb22018-09-26 14:35:22 -0700366 // F9 7BFF # primitive(31743)
367 QCBOREncode_AddDoubleAsSmallestToMap(&EC, "largest half-precision",65504.0);
368
369 // 76 # text(22)
Laurence Lundbladeee851742020-01-08 08:37:05 -0800370 // 6C6172676573742068616C662D707265636973696F6E # "largest half-precision"
Laurence Lundbladed711fb22018-09-26 14:35:22 -0700371 // F9 7BFF # primitive(31743)
372 QCBOREncode_AddDoubleAsSmallestToMap(&EC, "largest half-precision point one",65504.1);
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800373
Laurence Lundbladeee851742020-01-08 08:37:05 -0800374 // Float 65536.0F is 0x47800000 in hex. It has an exponent of 16, which
375 // is larger than 15, the largest half-precision exponent
Laurence Lundbladed711fb22018-09-26 14:35:22 -0700376 // 78 18 # text(24)
377 // 746F6F2D6C617267652068616C662D707265636973696F6E # "too-large half-precision"
378 // FA 47800000 # primitive(31743)
379 QCBOREncode_AddDoubleAsSmallestToMap(&EC, "too-large half-precision", 65536.0);
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800380
Laurence Lundbladed711fb22018-09-26 14:35:22 -0700381 // The smallest possible half-precision subnormal, but digitis are lost converting
382 // to half, so this turns into a double
383 // 72 # text(18)
384 // 736D616C6C657374207375626E6F726D616C # "smallest subnormal"
385 // FB 3E700000001C5F68 # primitive(4499096027744984936)
386 QCBOREncode_AddDoubleAsSmallestToMap(&EC, "smallest subnormal", 0.0000000596046448);
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800387
Laurence Lundbladed711fb22018-09-26 14:35:22 -0700388 // The smallest possible half-precision snormal, but digitis are lost converting
389 // to half, so this turns into a single TODO: confirm this is right
390 // 6F # text(15)
391 // 736D616C6C657374206E6F726D616C # "smallest normal"
392 // FA 387FFFFF # primitive(947912703)
393 // in hex single is 0x387fffff, exponent -15, significand 7fffff
394 QCBOREncode_AddDoubleAsSmallestToMap(&EC, "smallest normal", 0.0000610351526F);
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800395
Laurence Lundbladed711fb22018-09-26 14:35:22 -0700396 // 71 # text(17)
397 // 62696767657374207375626E6F726D616C # "biggest subnormal"
398 // F9 0400 # primitive(1024)
399 // in hex single is 0x38800000, exponent -14, significand 0
400 QCBOREncode_AddDoubleAsSmallestToMap(&EC, "biggest subnormal", 0.0000610351563F);
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800401
Laurence Lundbladed711fb22018-09-26 14:35:22 -0700402 // 70 # text(16)
403 // 7375626E6F726D616C2073696E676C65 # "subnormal single"
404 // FB 37C16C2800000000 # primitive(4017611261645684736)
405 QCBOREncode_AddDoubleAsSmallestToMap(&EC, "subnormal single", 4e-40F);
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800406
Laurence Lundbladed711fb22018-09-26 14:35:22 -0700407 // 03 # unsigned(3)
408 // F9 C000 # primitive(49152)
409 QCBOREncode_AddDoubleAsSmallestToMapN(&EC, 3, -2.0);
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800410
Laurence Lundbladed711fb22018-09-26 14:35:22 -0700411 // 70 # text(16)
412 // 6C617267652073696E676C6520657870 # "large single exp"
413 // FA 7F400000 # primitive(2134900736)
414 // (0x01LL << (DOUBLE_NUM_SIGNIFICAND_BITS-1)) | ((127LL + DOUBLE_EXPONENT_BIAS) << DOUBLE_EXPONENT_SHIFT);
415 QCBOREncode_AddDoubleAsSmallestToMap(&EC, "large single exp", 2.5521177519070385E+38); // Exponent fits single
416
417 // 74 # text(20)
418 // 746F6F2D6C617267652073696E676C6520657870 # "too-large single exp"
419 // FB 47F8000000000000 # primitive(5185894970917126144)
420 // (0x01LL << (DOUBLE_NUM_SIGNIFICAND_BITS-1)) | ((128LL + DOUBLE_EXPONENT_BIAS) << DOUBLE_EXPONENT_SHIFT);
Laurence Lundbladeee851742020-01-08 08:37:05 -0800421 // Exponent too large for single
422 QCBOREncode_AddDoubleAsSmallestToMap(&EC, "too-large single exp", 5.104235503814077E+38);
Laurence Lundbladed711fb22018-09-26 14:35:22 -0700423
424 // 66 # text(6)
425 // 646664666465 # "dfdfde"
426 // FA 4B800000 # primitive(1266679808)
Laurence Lundbladeee851742020-01-08 08:37:05 -0800427 // Single with no precision loss
428 QCBOREncode_AddDoubleAsSmallestToMap(&EC, "biggest single with prec", 16777216);
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800429
Laurence Lundbladed711fb22018-09-26 14:35:22 -0700430 // 78 18 # text(24)
431 // 626967676573742073696E676C6520776974682070726563 # "biggest single with prec"
432 // FA 4B800000 # primitive(1266679808)
Laurence Lundbladeee851742020-01-08 08:37:05 -0800433 // Double becuase of precision loss
434 QCBOREncode_AddDoubleAsSmallestToMap(&EC, "first single with prec loss", 16777217);
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800435
Laurence Lundbladed711fb22018-09-26 14:35:22 -0700436 // Just a convenient marker when cutting and pasting encoded CBOR
437 QCBOREncode_AddSZStringToMapN(&EC, 1, "fin");
438
439 QCBOREncode_CloseMap(&EC);
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800440
Laurence Lundblade781fd822018-10-01 09:37:52 -0700441 UsefulBufC EncodedHalfs;
Laurence Lundblade29497c02020-07-11 15:44:03 -0700442 QCBORError uErr = QCBOREncode_Finish(&EC, &EncodedHalfs);
443 if(uErr) {
Laurence Lundbladed711fb22018-09-26 14:35:22 -0700444 return -1;
445 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800446
Laurence Lundbladebb474be2018-10-22 11:53:21 +0530447 if(UsefulBuf_Compare(EncodedHalfs, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spExpectedSmallest))) {
Laurence Lundbladed711fb22018-09-26 14:35:22 -0700448 return -3;
449 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800450
Laurence Lundbladed711fb22018-09-26 14:35:22 -0700451 return 0;
Laurence Lundblade570fab52018-10-13 18:28:27 +0800452}
Laurence Lundblade585127a2020-07-15 03:25:24 -0700453#endif /* QCBOR_DISABLE_PREFERRED_FLOAT */
Laurence Lundbladed711fb22018-09-26 14:35:22 -0700454
455
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700456/*
457[0.0, 3.14, 0.0, NaN, Infinity, 0.0, 3.140000104904175, 0.0, NaN, Infinity,
458 {100: 0.0, 101: 3.1415926, "euler": 2.718281828459045, 105: 0.0,
459 102: 0.0, 103: 3.141592502593994, "euler2": 2.7182817459106445, 106: 0.0}]
460 */
Laurence Lundblade585127a2020-07-15 03:25:24 -0700461#ifndef QCBOR_DISABLE_PREFERRED_FLOAT
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700462static const uint8_t spExpectedFloats[] = {
463 0x8B,
464 0xF9, 0x00, 0x00,
465 0xFB, 0x40, 0x09, 0x1E, 0xB8, 0x51, 0xEB, 0x85, 0x1F,
466 0xFB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
467 0xFB, 0x7F, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
468 0xFB, 0x7F, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
469 0xF9, 0x00, 0x00,
470 0xFA, 0x40, 0x48, 0xF5, 0xC3,
471 0xFA, 0x00, 0x00, 0x00, 0x00,
472 0xFA, 0x7F, 0xC0, 0x00, 0x00,
473 0xFA, 0x7F, 0x80, 0x00, 0x00,
474 0xA8,
475 0x18, 0x64,
476 0xF9, 0x00, 0x00,
477 0x18, 0x65,
478 0xFB, 0x40, 0x09, 0x21, 0xFB, 0x4D, 0x12, 0xD8, 0x4A,
479 0x65, 0x65, 0x75, 0x6C, 0x65, 0x72,
480 0xFB, 0x40, 0x05, 0xBF, 0x0A, 0x8B, 0x14, 0x57, 0x69,
481 0x18, 0x69,
482 0xFB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
483 0x18, 0x66,
484 0xF9, 0x00, 0x00,
485 0x18, 0x67,
486 0xFA, 0x40, 0x49, 0x0F, 0xDA,
487 0x66, 0x65, 0x75, 0x6C, 0x65, 0x72, 0x32,
488 0xFA, 0x40, 0x2D, 0xF8, 0x54,
489 0x18, 0x6A,
490 0xFA, 0x00, 0x00, 0x00, 0x00};
Laurence Lundblade585127a2020-07-15 03:25:24 -0700491#else
492static const uint8_t spExpectedFloats[] = {
493 0x8B,
494 0xFB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
495 0xFB, 0x40, 0x09, 0x1E, 0xB8, 0x51, 0xEB, 0x85, 0x1F,
496 0xFB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
497 0xFB, 0x7F, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
498 0xFB, 0x7F, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
499 0xFA, 0x00, 0x00, 0x00, 0x00,
500 0xFA, 0x40, 0x48, 0xF5, 0xC3,
501 0xFA, 0x00, 0x00, 0x00, 0x00,
502 0xFA, 0x7F, 0xC0, 0x00, 0x00,
503 0xFA, 0x7F, 0x80, 0x00, 0x00,
504 0xA8,
505 0x18, 0x64,
506 0xFB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
507 0x18, 0x65,
508 0xFB, 0x40, 0x09, 0x21, 0xFB, 0x4D, 0x12, 0xD8, 0x4A,
509 0x65, 0x65, 0x75, 0x6C, 0x65, 0x72,
510 0xFB, 0x40, 0x05, 0xBF, 0x0A, 0x8B, 0x14, 0x57, 0x69,
511 0x18, 0x69,
512 0xFB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
513 0x18, 0x66,
514 0xFA, 0x00, 0x00, 0x00, 0x00,
515 0x18, 0x67,
516 0xFA, 0x40, 0x49, 0x0F, 0xDA,
517 0x66, 0x65, 0x75, 0x6C, 0x65, 0x72, 0x32,
518 0xFA, 0x40, 0x2D, 0xF8, 0x54,
519 0x18, 0x6A,
520 0xFA, 0x00, 0x00, 0x00, 0x00};
521#endif /* QCBOR_DISABLE_PREFERRED_FLOAT */
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700522
523int32_t GeneralFloatEncodeTests()
524{
525 UsefulBuf_MAKE_STACK_UB(OutBuffer, sizeof(spExpectedFloats));
526
527 QCBOREncodeContext EC;
528 QCBOREncode_Init(&EC, OutBuffer);
529 QCBOREncode_OpenArray(&EC);
530
531 QCBOREncode_AddDouble(&EC, 0.0);
532 QCBOREncode_AddDouble(&EC, 3.14);
533 QCBOREncode_AddDoubleNoPreferred(&EC, 0.0);
534 QCBOREncode_AddDoubleNoPreferred(&EC, NAN);
535 QCBOREncode_AddDoubleNoPreferred(&EC, INFINITY);
536
537 QCBOREncode_AddFloat(&EC, 0.0);
538 QCBOREncode_AddFloat(&EC, 3.14f);
539 QCBOREncode_AddFloatNoPreferred(&EC, 0.0f);
540 QCBOREncode_AddFloatNoPreferred(&EC, NAN);
541 QCBOREncode_AddFloatNoPreferred(&EC, INFINITY);
542
543 QCBOREncode_OpenMap(&EC);
544
545 QCBOREncode_AddDoubleToMapN(&EC, 100, 0.0);
546 QCBOREncode_AddDoubleToMapN(&EC, 101, 3.1415926);
547 QCBOREncode_AddDoubleToMap(&EC, "euler", 2.71828182845904523536);
548 QCBOREncode_AddDoubleNoPreferredToMapN(&EC, 105, 0.0);
549
550 QCBOREncode_AddFloatToMapN(&EC, 102, 0.0f);
551 QCBOREncode_AddFloatToMapN(&EC, 103, 3.1415926f);
552 QCBOREncode_AddFloatToMap(&EC, "euler2", 2.71828182845904523536f);
553 QCBOREncode_AddFloatNoPreferredToMapN(&EC, 106, 0.0f);
554
555 QCBOREncode_CloseMap(&EC);
556 QCBOREncode_CloseArray(&EC);
557
558 UsefulBufC Encoded;
559 QCBORError uErr = QCBOREncode_Finish(&EC, &Encoded);
560 if(uErr) {
Laurence Lundblade585127a2020-07-15 03:25:24 -0700561 return -1;
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700562 }
563
564 if(UsefulBuf_Compare(Encoded, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spExpectedFloats))) {
Laurence Lundblade585127a2020-07-15 03:25:24 -0700565 return -3;
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700566 }
567
568 return 0;
569}
570
571
Laurence Lundbladed711fb22018-09-26 14:35:22 -0700572
Laurence Lundblade7d40d812018-09-30 02:44:01 -0700573#ifdef NAN_EXPERIMENT
574/*
575 Code for checking what the double to float cast does with
576 NaNs. Not run as part of tests. Keep it around to
577 be able to check various platforms and CPUs.
578 */
579
580#define DOUBLE_NUM_SIGNIFICAND_BITS (52)
581#define DOUBLE_NUM_EXPONENT_BITS (11)
582#define DOUBLE_NUM_SIGN_BITS (1)
583
584#define DOUBLE_SIGNIFICAND_SHIFT (0)
585#define DOUBLE_EXPONENT_SHIFT (DOUBLE_NUM_SIGNIFICAND_BITS)
586#define DOUBLE_SIGN_SHIFT (DOUBLE_NUM_SIGNIFICAND_BITS + DOUBLE_NUM_EXPONENT_BITS)
587
588#define DOUBLE_SIGNIFICAND_MASK (0xfffffffffffffULL) // The lower 52 bits
589#define DOUBLE_EXPONENT_MASK (0x7ffULL << DOUBLE_EXPONENT_SHIFT) // 11 bits of exponent
590#define DOUBLE_SIGN_MASK (0x01ULL << DOUBLE_SIGN_SHIFT) // 1 bit of sign
591#define DOUBLE_QUIET_NAN_BIT (0x01ULL << (DOUBLE_NUM_SIGNIFICAND_BITS-1))
592
593
594static int NaNExperiments() {
595 double dqNaN = UsefulBufUtil_CopyUint64ToDouble(DOUBLE_EXPONENT_MASK | DOUBLE_QUIET_NAN_BIT);
596 double dsNaN = UsefulBufUtil_CopyUint64ToDouble(DOUBLE_EXPONENT_MASK | 0x01);
597 double dqNaNPayload = UsefulBufUtil_CopyUint64ToDouble(DOUBLE_EXPONENT_MASK | DOUBLE_QUIET_NAN_BIT | 0xf00f);
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800598
Laurence Lundblade7d40d812018-09-30 02:44:01 -0700599 float f1 = (float)dqNaN;
600 float f2 = (float)dsNaN;
601 float f3 = (float)dqNaNPayload;
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800602
603
Laurence Lundblade7d40d812018-09-30 02:44:01 -0700604 uint32_t uqNaN = UsefulBufUtil_CopyFloatToUint32((float)dqNaN);
605 uint32_t usNaN = UsefulBufUtil_CopyFloatToUint32((float)dsNaN);
606 uint32_t uqNaNPayload = UsefulBufUtil_CopyFloatToUint32((float)dqNaNPayload);
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800607
Laurence Lundblade7d40d812018-09-30 02:44:01 -0700608 // Result of this on x86 is that every NaN is a qNaN. The intel
609 // CVTSD2SS instruction ignores the NaN payload and even converts
610 // a sNaN to a qNaN.
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800611
Laurence Lundblade7d40d812018-09-30 02:44:01 -0700612 return 0;
613}
614#endif
615
616
Laurence Lundbladed711fb22018-09-26 14:35:22 -0700617