1 /*
2 * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23
24 /*
25 * @test
26 * @bug 4860891 4826732 4780454 4939441 4826652
27 * @summary Tests for IEEE 754[R] recommended functions and similar methods
28 * @author Joseph D. Darcy
29 */
30
31 import sun.misc.FpUtils;
32 import sun.misc.DoubleConsts;
33 import sun.misc.FloatConsts;
34
35 public class IeeeRecommendedTests {
36 private IeeeRecommendedTests(){}
37
38 static final float NaNf = Float.NaN;
39 static final double NaNd = Double.NaN;
40 static final float infinityF = Float.POSITIVE_INFINITY;
41 static final double infinityD = Double.POSITIVE_INFINITY;
42
43 static final float Float_MAX_VALUEmm = 0x1.fffffcP+127f;
44 static final float Float_MAX_SUBNORMAL = 0x0.fffffeP-126f;
45 static final float Float_MAX_SUBNORMALmm = 0x0.fffffcP-126f;
46
47 static final double Double_MAX_VALUEmm = 0x1.ffffffffffffeP+1023;
48 static final double Double_MAX_SUBNORMAL = 0x0.fffffffffffffP-1022;
49 static final double Double_MAX_SUBNORMALmm = 0x0.ffffffffffffeP-1022;
50
51 // Initialize shared random number generator
691 -3.0f,
692 -1.0f,
693 -FloatConsts.MIN_NORMAL,
694 -Float_MAX_SUBNORMALmm,
695 -Float_MAX_SUBNORMAL,
696 -Float.MIN_VALUE,
697 -0.0f,
698 +0.0f,
699 Float.MIN_VALUE,
700 Float_MAX_SUBNORMALmm,
701 Float_MAX_SUBNORMAL,
702 FloatConsts.MIN_NORMAL,
703 1.0f,
704 3.0f,
705 Float_MAX_VALUEmm,
706 Float.MAX_VALUE
707 };
708
709 for(int i = 0; i < testCases.length; i++) {
710 // isNaN
711 failures+=Tests.test("FpUtils.isNaN(float)", testCases[i],
712 FpUtils.isNaN(testCases[i]), (i ==0));
713
714 // isFinite
715 failures+=Tests.test("Float.isFinite(float)", testCases[i],
716 Float.isFinite(testCases[i]), (i >= 3));
717
718 // isInfinite
719 failures+=Tests.test("FpUtils.isInfinite(float)", testCases[i],
720 FpUtils.isInfinite(testCases[i]), (i==1 || i==2));
721
722 // isUnorderd
723 for(int j = 0; j < testCases.length; j++) {
724 failures+=Tests.test("FpUtils.isUnordered(float, float)", testCases[i],testCases[j],
725 FpUtils.isUnordered(testCases[i],testCases[j]), (i==0 || j==0));
726 }
727 }
728
729 return failures;
730 }
731
732 public static int testDoubleBooleanMethods() {
733 int failures = 0;
734 boolean result = false;
735
736 double testCases [] = {
737 NaNd,
738 -infinityD,
739 infinityD,
740 -Double.MAX_VALUE,
741 -3.0d,
742 -1.0d,
743 -DoubleConsts.MIN_NORMAL,
744 -Double_MAX_SUBNORMALmm,
745 -Double_MAX_SUBNORMAL,
746 -Double.MIN_VALUE,
747 -0.0d,
748 +0.0d,
749 Double.MIN_VALUE,
750 Double_MAX_SUBNORMALmm,
751 Double_MAX_SUBNORMAL,
752 DoubleConsts.MIN_NORMAL,
753 1.0d,
754 3.0d,
755 Double_MAX_VALUEmm,
756 Double.MAX_VALUE
757 };
758
759 for(int i = 0; i < testCases.length; i++) {
760 // isNaN
761 failures+=Tests.test("FpUtils.isNaN(double)", testCases[i],
762 FpUtils.isNaN(testCases[i]), (i ==0));
763
764 // isFinite
765 failures+=Tests.test("Double.isFinite(double)", testCases[i],
766 Double.isFinite(testCases[i]), (i >= 3));
767
768 // isInfinite
769 failures+=Tests.test("FpUtils.isInfinite(double)", testCases[i],
770 FpUtils.isInfinite(testCases[i]), (i==1 || i==2));
771
772 // isUnorderd
773 for(int j = 0; j < testCases.length; j++) {
774 failures+=Tests.test("FpUtils.isUnordered(double, double)", testCases[i],testCases[j],
775 FpUtils.isUnordered(testCases[i],testCases[j]), (i==0 || j==0));
776 }
777 }
778
779 return failures;
780 }
781
782 /* ******************** copySign tests******************************** */
783
784 public static int testFloatCopySign() {
785 int failures = 0;
786
787 // testCases[0] are logically positive numbers;
788 // testCases[1] are negative numbers.
789 float testCases [][] = {
790 {+0.0f,
791 Float.MIN_VALUE,
792 Float_MAX_SUBNORMALmm,
793 Float_MAX_SUBNORMAL,
794 FloatConsts.MIN_NORMAL,
795 1.0f,
1006 -1,
1007 0,
1008 1,
1009 2,
1010 3,
1011 FloatConsts.MAX_EXPONENT-1,
1012 FloatConsts.MAX_EXPONENT
1013 };
1014
1015 int [] manyScalingFactors = {
1016 Integer.MIN_VALUE,
1017 Integer.MIN_VALUE+1,
1018 -MAX_SCALE -1,
1019 -MAX_SCALE,
1020 -MAX_SCALE+1,
1021
1022 2*FloatConsts.MIN_EXPONENT-1, // -253
1023 2*FloatConsts.MIN_EXPONENT, // -252
1024 2*FloatConsts.MIN_EXPONENT+1, // -251
1025
1026 FpUtils.ilogb(Float.MIN_VALUE)-1, // -150
1027 FpUtils.ilogb(Float.MIN_VALUE), // -149
1028 -FloatConsts.MAX_EXPONENT, // -127
1029 FloatConsts.MIN_EXPONENT, // -126
1030
1031 -2,
1032 -1,
1033 0,
1034 1,
1035 2,
1036
1037 FloatConsts.MAX_EXPONENT-1, // 126
1038 FloatConsts.MAX_EXPONENT, // 127
1039 FloatConsts.MAX_EXPONENT+1, // 128
1040
1041 2*FloatConsts.MAX_EXPONENT-1, // 253
1042 2*FloatConsts.MAX_EXPONENT, // 254
1043 2*FloatConsts.MAX_EXPONENT+1, // 255
1044
1045 MAX_SCALE-1,
1046 MAX_SCALE,
1047 MAX_SCALE+1,
1083 scaleFactor,
1084 value*powerOfTwoF(scaleFactor));
1085 }
1086 }
1087
1088 // Create 2^MAX_EXPONENT
1089 float twoToTheMaxExp = 1.0f; // 2^0
1090 for(int i = 0; i < FloatConsts.MAX_EXPONENT; i++)
1091 twoToTheMaxExp *=2.0f;
1092
1093 // Scale-up subnormal values until they all overflow
1094 for(int i=0; i < subnormalTestCases.length; i++) {
1095 float scale = 1.0f; // 2^j
1096 float value = subnormalTestCases[i];
1097
1098 for(int j=FloatConsts.MAX_EXPONENT*2; j < MAX_SCALE; j++) { // MAX_SCALE -1 should cause overflow
1099 int scaleFactor = j;
1100
1101 failures+=testScalbCase(value,
1102 scaleFactor,
1103 (FpUtils.ilogb(value) +j > FloatConsts.MAX_EXPONENT ) ?
1104 Math.copySign(infinityF, value) : // overflow
1105 // calculate right answer
1106 twoToTheMaxExp*(twoToTheMaxExp*(scale*value)) );
1107 scale*=2.0f;
1108 }
1109 }
1110
1111 // Scale down a large number until it underflows. By scaling
1112 // down MAX_NORMALmm, the first subnormal result will be exact
1113 // but the next one will round -- all those results can be
1114 // checked by halving a separate value in the loop. Actually,
1115 // we can keep halving and checking until the product is zero
1116 // since:
1117 //
1118 // 1. If the scalb of MAX_VALUEmm is subnormal and *not* exact
1119 // it will round *up*
1120 //
1121 // 2. When rounding first occurs in the expected product, it
1122 // too rounds up, to 2^-MAX_EXPONENT.
1123 //
1213 -1,
1214 0,
1215 1,
1216 2,
1217 3,
1218 DoubleConsts.MAX_EXPONENT-1,
1219 DoubleConsts.MAX_EXPONENT
1220 };
1221
1222 int [] manyScalingFactors = {
1223 Integer.MIN_VALUE,
1224 Integer.MIN_VALUE+1,
1225 -MAX_SCALE -1,
1226 -MAX_SCALE,
1227 -MAX_SCALE+1,
1228
1229 2*DoubleConsts.MIN_EXPONENT-1, // -2045
1230 2*DoubleConsts.MIN_EXPONENT, // -2044
1231 2*DoubleConsts.MIN_EXPONENT+1, // -2043
1232
1233 FpUtils.ilogb(Double.MIN_VALUE)-1, // -1076
1234 FpUtils.ilogb(Double.MIN_VALUE), // -1075
1235 -DoubleConsts.MAX_EXPONENT, // -1023
1236 DoubleConsts.MIN_EXPONENT, // -1022
1237
1238 -2,
1239 -1,
1240 0,
1241 1,
1242 2,
1243
1244 DoubleConsts.MAX_EXPONENT-1, // 1022
1245 DoubleConsts.MAX_EXPONENT, // 1023
1246 DoubleConsts.MAX_EXPONENT+1, // 1024
1247
1248 2*DoubleConsts.MAX_EXPONENT-1, // 2045
1249 2*DoubleConsts.MAX_EXPONENT, // 2046
1250 2*DoubleConsts.MAX_EXPONENT+1, // 2047
1251
1252 MAX_SCALE-1,
1253 MAX_SCALE,
1254 MAX_SCALE+1,
1290 scaleFactor,
1291 value*powerOfTwoD(scaleFactor));
1292 }
1293 }
1294
1295 // Create 2^MAX_EXPONENT
1296 double twoToTheMaxExp = 1.0; // 2^0
1297 for(int i = 0; i < DoubleConsts.MAX_EXPONENT; i++)
1298 twoToTheMaxExp *=2.0;
1299
1300 // Scale-up subnormal values until they all overflow
1301 for(int i=0; i < subnormalTestCases.length; i++) {
1302 double scale = 1.0; // 2^j
1303 double value = subnormalTestCases[i];
1304
1305 for(int j=DoubleConsts.MAX_EXPONENT*2; j < MAX_SCALE; j++) { // MAX_SCALE -1 should cause overflow
1306 int scaleFactor = j;
1307
1308 failures+=testScalbCase(value,
1309 scaleFactor,
1310 (FpUtils.ilogb(value) +j > DoubleConsts.MAX_EXPONENT ) ?
1311 Math.copySign(infinityD, value) : // overflow
1312 // calculate right answer
1313 twoToTheMaxExp*(twoToTheMaxExp*(scale*value)) );
1314 scale*=2.0;
1315 }
1316 }
1317
1318 // Scale down a large number until it underflows. By scaling
1319 // down MAX_NORMALmm, the first subnormal result will be exact
1320 // but the next one will round -- all those results can be
1321 // checked by halving a separate value in the loop. Actually,
1322 // we can keep halving and checking until the product is zero
1323 // since:
1324 //
1325 // 1. If the scalb of MAX_VALUEmm is subnormal and *not* exact
1326 // it will round *up*
1327 //
1328 // 2. When rounding first occurs in the expected product, it
1329 // too rounds up, to 2^-MAX_EXPONENT.
1330 //
|
1 /*
2 * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23
24 /*
25 * @test
26 * @bug 4860891 4826732 4780454 4939441 4826652 8033416
27 * @summary Tests for IEEE 754[R] recommended functions and similar methods
28 * @author Joseph D. Darcy
29 */
30
31 import sun.misc.DoubleConsts;
32 import sun.misc.FloatConsts;
33
34 public class IeeeRecommendedTests {
35 private IeeeRecommendedTests(){}
36
37 static final float NaNf = Float.NaN;
38 static final double NaNd = Double.NaN;
39 static final float infinityF = Float.POSITIVE_INFINITY;
40 static final double infinityD = Double.POSITIVE_INFINITY;
41
42 static final float Float_MAX_VALUEmm = 0x1.fffffcP+127f;
43 static final float Float_MAX_SUBNORMAL = 0x0.fffffeP-126f;
44 static final float Float_MAX_SUBNORMALmm = 0x0.fffffcP-126f;
45
46 static final double Double_MAX_VALUEmm = 0x1.ffffffffffffeP+1023;
47 static final double Double_MAX_SUBNORMAL = 0x0.fffffffffffffP-1022;
48 static final double Double_MAX_SUBNORMALmm = 0x0.ffffffffffffeP-1022;
49
50 // Initialize shared random number generator
690 -3.0f,
691 -1.0f,
692 -FloatConsts.MIN_NORMAL,
693 -Float_MAX_SUBNORMALmm,
694 -Float_MAX_SUBNORMAL,
695 -Float.MIN_VALUE,
696 -0.0f,
697 +0.0f,
698 Float.MIN_VALUE,
699 Float_MAX_SUBNORMALmm,
700 Float_MAX_SUBNORMAL,
701 FloatConsts.MIN_NORMAL,
702 1.0f,
703 3.0f,
704 Float_MAX_VALUEmm,
705 Float.MAX_VALUE
706 };
707
708 for(int i = 0; i < testCases.length; i++) {
709 // isNaN
710 failures+=Tests.test("Float.isNaN(float)", testCases[i],
711 Float.isNaN(testCases[i]), (i ==0));
712
713 // isFinite
714 failures+=Tests.test("Float.isFinite(float)", testCases[i],
715 Float.isFinite(testCases[i]), (i >= 3));
716
717 // isInfinite
718 failures+=Tests.test("Float.isInfinite(float)", testCases[i],
719 Float.isInfinite(testCases[i]), (i==1 || i==2));
720
721 // isUnorderd
722 for(int j = 0; j < testCases.length; j++) {
723 failures+=Tests.test("Tests.isUnordered(float, float)", testCases[i],testCases[j],
724 Tests.isUnordered(testCases[i],testCases[j]), (i==0 || j==0));
725 }
726 }
727
728 return failures;
729 }
730
731 public static int testDoubleBooleanMethods() {
732 int failures = 0;
733 boolean result = false;
734
735 double testCases [] = {
736 NaNd,
737 -infinityD,
738 infinityD,
739 -Double.MAX_VALUE,
740 -3.0d,
741 -1.0d,
742 -DoubleConsts.MIN_NORMAL,
743 -Double_MAX_SUBNORMALmm,
744 -Double_MAX_SUBNORMAL,
745 -Double.MIN_VALUE,
746 -0.0d,
747 +0.0d,
748 Double.MIN_VALUE,
749 Double_MAX_SUBNORMALmm,
750 Double_MAX_SUBNORMAL,
751 DoubleConsts.MIN_NORMAL,
752 1.0d,
753 3.0d,
754 Double_MAX_VALUEmm,
755 Double.MAX_VALUE
756 };
757
758 for(int i = 0; i < testCases.length; i++) {
759 // isNaN
760 failures+=Tests.test("Double.isNaN(double)", testCases[i],
761 Double.isNaN(testCases[i]), (i ==0));
762
763 // isFinite
764 failures+=Tests.test("Double.isFinite(double)", testCases[i],
765 Double.isFinite(testCases[i]), (i >= 3));
766
767 // isInfinite
768 failures+=Tests.test("Double.isInfinite(double)", testCases[i],
769 Double.isInfinite(testCases[i]), (i==1 || i==2));
770
771 // isUnorderd
772 for(int j = 0; j < testCases.length; j++) {
773 failures+=Tests.test("Tests.isUnordered(double, double)", testCases[i],testCases[j],
774 Tests.isUnordered(testCases[i],testCases[j]), (i==0 || j==0));
775 }
776 }
777
778 return failures;
779 }
780
781 /* ******************** copySign tests******************************** */
782
783 public static int testFloatCopySign() {
784 int failures = 0;
785
786 // testCases[0] are logically positive numbers;
787 // testCases[1] are negative numbers.
788 float testCases [][] = {
789 {+0.0f,
790 Float.MIN_VALUE,
791 Float_MAX_SUBNORMALmm,
792 Float_MAX_SUBNORMAL,
793 FloatConsts.MIN_NORMAL,
794 1.0f,
1005 -1,
1006 0,
1007 1,
1008 2,
1009 3,
1010 FloatConsts.MAX_EXPONENT-1,
1011 FloatConsts.MAX_EXPONENT
1012 };
1013
1014 int [] manyScalingFactors = {
1015 Integer.MIN_VALUE,
1016 Integer.MIN_VALUE+1,
1017 -MAX_SCALE -1,
1018 -MAX_SCALE,
1019 -MAX_SCALE+1,
1020
1021 2*FloatConsts.MIN_EXPONENT-1, // -253
1022 2*FloatConsts.MIN_EXPONENT, // -252
1023 2*FloatConsts.MIN_EXPONENT+1, // -251
1024
1025 FloatConsts.MIN_EXPONENT - FloatConsts.SIGNIFICAND_WIDTH,
1026 FloatConsts.MIN_SUB_EXPONENT,
1027 -FloatConsts.MAX_EXPONENT, // -127
1028 FloatConsts.MIN_EXPONENT, // -126
1029
1030 -2,
1031 -1,
1032 0,
1033 1,
1034 2,
1035
1036 FloatConsts.MAX_EXPONENT-1, // 126
1037 FloatConsts.MAX_EXPONENT, // 127
1038 FloatConsts.MAX_EXPONENT+1, // 128
1039
1040 2*FloatConsts.MAX_EXPONENT-1, // 253
1041 2*FloatConsts.MAX_EXPONENT, // 254
1042 2*FloatConsts.MAX_EXPONENT+1, // 255
1043
1044 MAX_SCALE-1,
1045 MAX_SCALE,
1046 MAX_SCALE+1,
1082 scaleFactor,
1083 value*powerOfTwoF(scaleFactor));
1084 }
1085 }
1086
1087 // Create 2^MAX_EXPONENT
1088 float twoToTheMaxExp = 1.0f; // 2^0
1089 for(int i = 0; i < FloatConsts.MAX_EXPONENT; i++)
1090 twoToTheMaxExp *=2.0f;
1091
1092 // Scale-up subnormal values until they all overflow
1093 for(int i=0; i < subnormalTestCases.length; i++) {
1094 float scale = 1.0f; // 2^j
1095 float value = subnormalTestCases[i];
1096
1097 for(int j=FloatConsts.MAX_EXPONENT*2; j < MAX_SCALE; j++) { // MAX_SCALE -1 should cause overflow
1098 int scaleFactor = j;
1099
1100 failures+=testScalbCase(value,
1101 scaleFactor,
1102 (Tests.ilogb(value) +j > FloatConsts.MAX_EXPONENT ) ?
1103 Math.copySign(infinityF, value) : // overflow
1104 // calculate right answer
1105 twoToTheMaxExp*(twoToTheMaxExp*(scale*value)) );
1106 scale*=2.0f;
1107 }
1108 }
1109
1110 // Scale down a large number until it underflows. By scaling
1111 // down MAX_NORMALmm, the first subnormal result will be exact
1112 // but the next one will round -- all those results can be
1113 // checked by halving a separate value in the loop. Actually,
1114 // we can keep halving and checking until the product is zero
1115 // since:
1116 //
1117 // 1. If the scalb of MAX_VALUEmm is subnormal and *not* exact
1118 // it will round *up*
1119 //
1120 // 2. When rounding first occurs in the expected product, it
1121 // too rounds up, to 2^-MAX_EXPONENT.
1122 //
1212 -1,
1213 0,
1214 1,
1215 2,
1216 3,
1217 DoubleConsts.MAX_EXPONENT-1,
1218 DoubleConsts.MAX_EXPONENT
1219 };
1220
1221 int [] manyScalingFactors = {
1222 Integer.MIN_VALUE,
1223 Integer.MIN_VALUE+1,
1224 -MAX_SCALE -1,
1225 -MAX_SCALE,
1226 -MAX_SCALE+1,
1227
1228 2*DoubleConsts.MIN_EXPONENT-1, // -2045
1229 2*DoubleConsts.MIN_EXPONENT, // -2044
1230 2*DoubleConsts.MIN_EXPONENT+1, // -2043
1231
1232 DoubleConsts.MIN_EXPONENT, // -1022
1233 DoubleConsts.MIN_EXPONENT - DoubleConsts.SIGNIFICAND_WIDTH,
1234 DoubleConsts.MIN_SUB_EXPONENT,
1235 -DoubleConsts.MAX_EXPONENT, // -1023
1236 DoubleConsts.MIN_EXPONENT, // -1022
1237
1238 -2,
1239 -1,
1240 0,
1241 1,
1242 2,
1243
1244 DoubleConsts.MAX_EXPONENT-1, // 1022
1245 DoubleConsts.MAX_EXPONENT, // 1023
1246 DoubleConsts.MAX_EXPONENT+1, // 1024
1247
1248 2*DoubleConsts.MAX_EXPONENT-1, // 2045
1249 2*DoubleConsts.MAX_EXPONENT, // 2046
1250 2*DoubleConsts.MAX_EXPONENT+1, // 2047
1251
1252 MAX_SCALE-1,
1253 MAX_SCALE,
1254 MAX_SCALE+1,
1290 scaleFactor,
1291 value*powerOfTwoD(scaleFactor));
1292 }
1293 }
1294
1295 // Create 2^MAX_EXPONENT
1296 double twoToTheMaxExp = 1.0; // 2^0
1297 for(int i = 0; i < DoubleConsts.MAX_EXPONENT; i++)
1298 twoToTheMaxExp *=2.0;
1299
1300 // Scale-up subnormal values until they all overflow
1301 for(int i=0; i < subnormalTestCases.length; i++) {
1302 double scale = 1.0; // 2^j
1303 double value = subnormalTestCases[i];
1304
1305 for(int j=DoubleConsts.MAX_EXPONENT*2; j < MAX_SCALE; j++) { // MAX_SCALE -1 should cause overflow
1306 int scaleFactor = j;
1307
1308 failures+=testScalbCase(value,
1309 scaleFactor,
1310 (Tests.ilogb(value) +j > DoubleConsts.MAX_EXPONENT ) ?
1311 Math.copySign(infinityD, value) : // overflow
1312 // calculate right answer
1313 twoToTheMaxExp*(twoToTheMaxExp*(scale*value)) );
1314 scale*=2.0;
1315 }
1316 }
1317
1318 // Scale down a large number until it underflows. By scaling
1319 // down MAX_NORMALmm, the first subnormal result will be exact
1320 // but the next one will round -- all those results can be
1321 // checked by halving a separate value in the loop. Actually,
1322 // we can keep halving and checking until the product is zero
1323 // since:
1324 //
1325 // 1. If the scalb of MAX_VALUEmm is subnormal and *not* exact
1326 // it will round *up*
1327 //
1328 // 2. When rounding first occurs in the expected product, it
1329 // too rounds up, to 2^-MAX_EXPONENT.
1330 //
|