blob: 815c9f52e8a22232d333938eb871db6638330879 [file] [log] [blame]
xueliang.zhong9ce340f2019-01-22 17:46:09 +00001/*
2 * Copyright (C) 2018 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17import libcore.util.FP16;
18
19public class Main {
20 public Main() {
21 }
22
23 public static int TestFP16ToFloatRawIntBits(short half) {
24 float f = FP16.toFloat(half);
25 // Since in this test class we need to check the integer representing of
26 // the actual float NaN values, the floatToRawIntBits() is used instead of
27 // floatToIntBits().
28 return Float.floatToRawIntBits(f);
29 }
30
Vladimir Marko7f958e32019-10-24 09:03:58 +000031 public static void assertEquals(short expected, short calculated) {
32 if (expected != calculated) {
33 throw new Error("Expected: " + expected + ", Calculated: " + calculated);
xueliang.zhong9ce340f2019-01-22 17:46:09 +000034 }
35 }
Vladimir Marko7f958e32019-10-24 09:03:58 +000036 public static void assertEquals(float expected, float calculated) {
37 if (expected != calculated) {
38 throw new Error("Expected: " + expected + ", Calculated: " + calculated);
xueliang.zhong9ce340f2019-01-22 17:46:09 +000039 }
40 }
41
Usama Arif64bac152019-10-28 12:11:21 +000042 public static void testHalfToFloatToHalfConversions(){
43 // Test FP16 to float and back to Half for all possible Short values
xueliang.zhong9ce340f2019-01-22 17:46:09 +000044 for (short h = Short.MIN_VALUE; h < Short.MAX_VALUE; h++) {
45 if (FP16.isNaN(h)) {
46 // NaN inputs are tested below.
47 continue;
48 }
Vladimir Marko7f958e32019-10-24 09:03:58 +000049 assertEquals(h, FP16.toHalf(FP16.toFloat(h)));
xueliang.zhong9ce340f2019-01-22 17:46:09 +000050 }
Usama Arif64bac152019-10-28 12:11:21 +000051 }
Vladimir Marko7f958e32019-10-24 09:03:58 +000052
Usama Arif64bac152019-10-28 12:11:21 +000053 public static void testToHalf(){
Vladimir Marko7f958e32019-10-24 09:03:58 +000054 // These asserts check some known values and edge cases for FP16.toHalf
55 // and have been inspired by the cts HalfTest.
56 // Zeroes, NaN and infinities
57 assertEquals(FP16.POSITIVE_ZERO, FP16.toHalf(0.0f));
58 assertEquals(FP16.NEGATIVE_ZERO, FP16.toHalf(-0.0f));
59 assertEquals(FP16.NaN, FP16.toHalf(Float.NaN));
60 assertEquals(FP16.POSITIVE_INFINITY, FP16.toHalf(Float.POSITIVE_INFINITY));
61 assertEquals(FP16.NEGATIVE_INFINITY, FP16.toHalf(Float.NEGATIVE_INFINITY));
62 // Known values
63 assertEquals((short) 0x3c01, FP16.toHalf(1.0009765625f));
64 assertEquals((short) 0xc000, FP16.toHalf(-2.0f));
65 assertEquals((short) 0x0400, FP16.toHalf(6.10352e-5f));
66 assertEquals((short) 0x7bff, FP16.toHalf(65504.0f));
67 assertEquals((short) 0x3555, FP16.toHalf(1.0f / 3.0f));
68 // Subnormals
69 assertEquals((short) 0x03ff, FP16.toHalf(6.09756e-5f));
70 assertEquals(FP16.MIN_VALUE, FP16.toHalf(5.96046e-8f));
71 assertEquals((short) 0x83ff, FP16.toHalf(-6.09756e-5f));
72 assertEquals((short) 0x8001, FP16.toHalf(-5.96046e-8f));
73 // Subnormals (flushed to +/-0)
74 assertEquals(FP16.POSITIVE_ZERO, FP16.toHalf(5.96046e-9f));
75 assertEquals(FP16.NEGATIVE_ZERO, FP16.toHalf(-5.96046e-9f));
76 // Test for values that overflow the mantissa bits into exp bits
77 assertEquals(0x1000, FP16.toHalf(Float.intBitsToFloat(0x39fff000)));
78 assertEquals(0x0400, FP16.toHalf(Float.intBitsToFloat(0x387fe000)));
79 // Floats with absolute value above +/-65519 are rounded to +/-inf
80 // when using round-to-even
81 assertEquals(0x7bff, FP16.toHalf(65519.0f));
82 assertEquals(0x7bff, FP16.toHalf(65519.9f));
83 assertEquals(FP16.POSITIVE_INFINITY, FP16.toHalf(65520.0f));
84 assertEquals(FP16.NEGATIVE_INFINITY, FP16.toHalf(-65520.0f));
85 // Check if numbers are rounded to nearest even when they
86 // cannot be accurately represented by Half
87 assertEquals(0x6800, FP16.toHalf(2049.0f));
88 assertEquals(0x6c00, FP16.toHalf(4098.0f));
89 assertEquals(0x7000, FP16.toHalf(8196.0f));
90 assertEquals(0x7400, FP16.toHalf(16392.0f));
91 assertEquals(0x7800, FP16.toHalf(32784.0f));
92
Usama Arif64bac152019-10-28 12:11:21 +000093 }
94
95 public static void testToFloat(){
xueliang.zhong9ce340f2019-01-22 17:46:09 +000096 // FP16 SNaN/QNaN inputs to float
97 // The most significant bit of mantissa:
98 // V
99 // 0xfc01: 1 11111 0000000001 (signaling NaN)
100 // 0xfdff: 1 11111 0111111111 (signaling NaN)
101 // 0xfe00: 1 11111 1000000000 (quiet NaN)
102 // 0xffff: 1 11111 1111111111 (quiet NaN)
103 // This test is inspired by Java implementation of android.util.Half.toFloat(),
104 // where the implementation performs SNaN->QNaN conversion.
105 assert(Float.isNaN(FP16.toFloat((short)0xfc01)));
106 assert(Float.isNaN(FP16.toFloat((short)0xfdff)));
107 assert(Float.isNaN(FP16.toFloat((short)0xfe00)));
108 assert(Float.isNaN(FP16.toFloat((short)0xffff)));
109 assertEquals(0xffc02000, TestFP16ToFloatRawIntBits((short)(0xfc01))); // SNaN->QNaN
110 assertEquals(0xffffe000, TestFP16ToFloatRawIntBits((short)(0xfdff))); // SNaN->QNaN
111 assertEquals(0xffc00000, TestFP16ToFloatRawIntBits((short)(0xfe00))); // QNaN->QNaN
112 assertEquals(0xffffe000, TestFP16ToFloatRawIntBits((short)(0xffff))); // QNaN->QNaN
113 }
Usama Arif64bac152019-10-28 12:11:21 +0000114
Usama Arifb9f02c22019-10-25 17:37:33 +0100115 public static void testFloor() {
116 // These tests have been taken from the cts HalfTest
117 assertEquals(FP16.POSITIVE_INFINITY, FP16.floor(FP16.POSITIVE_INFINITY));
118 assertEquals(FP16.NEGATIVE_INFINITY, FP16.floor(FP16.NEGATIVE_INFINITY));
119 assertEquals(FP16.POSITIVE_ZERO, FP16.floor(FP16.POSITIVE_ZERO));
120 assertEquals(FP16.NEGATIVE_ZERO, FP16.floor(FP16.NEGATIVE_ZERO));
121 assertEquals(FP16.NaN, FP16.floor(FP16.NaN));
122 assertEquals(FP16.LOWEST_VALUE, FP16.floor(FP16.LOWEST_VALUE));
123 assertEquals(FP16.POSITIVE_ZERO, FP16.floor(FP16.MIN_NORMAL));
124 assertEquals(FP16.POSITIVE_ZERO, FP16.floor((short) 0x3ff));
125 assertEquals(FP16.POSITIVE_ZERO, FP16.floor(FP16.toHalf(0.2f)));
126 assertEquals(-1.0f, FP16.toFloat(FP16.floor(FP16.toHalf(-0.2f))));
127 assertEquals(-1.0f, FP16.toFloat(FP16.floor(FP16.toHalf(-0.7f))));
128 assertEquals(FP16.POSITIVE_ZERO, FP16.floor(FP16.toHalf(0.7f)));
129 assertEquals(124.0f, FP16.toFloat(FP16.floor(FP16.toHalf(124.7f))));
130 assertEquals(-125.0f, FP16.toFloat(FP16.floor(FP16.toHalf(-124.7f))));
131 assertEquals(124.0f, FP16.toFloat(FP16.floor(FP16.toHalf(124.2f))));
132 assertEquals(-125.0f, FP16.toFloat(FP16.floor(FP16.toHalf(-124.2f))));
133 // floor for NaN values
134 assertEquals((short) 0x7e01, FP16.floor((short) 0x7c01));
135 assertEquals((short) 0x7f00, FP16.floor((short) 0x7d00));
136 assertEquals((short) 0xfe01, FP16.floor((short) 0xfc01));
137 assertEquals((short) 0xff00, FP16.floor((short) 0xfd00));
138 }
139
Usama Arif64bac152019-10-28 12:11:21 +0000140 public static void main(String args[]) {
141 testHalfToFloatToHalfConversions();
142 testToHalf();
143 testToFloat();
Usama Arifb9f02c22019-10-25 17:37:33 +0100144 testFloor();
Usama Arif64bac152019-10-28 12:11:21 +0000145 }
xueliang.zhong9ce340f2019-01-22 17:46:09 +0000146}