Round to nearest even instead of to nearest 0.5 up
According to IEEE_754-1985 and in the updated IEEE 754-2008 standard,
the default rounding mode is roundTiesToEven. This is also the mode used in
hardware (Arm and Intel) floating point conversion instruction.
This commit replaces the rounding when converting from float to half from
"to nearest 0.5 up" to ties to even.
The test for checking if the correct rounding mode is used has been added to
android.util.cts.HalfTest in another patch.
Armv8.2 implementation (FCVT)
__ Fcvt(h0, s1);
__ Fmov(w0, h0);
float = 2048.0f, half = 0x6800
float = 2049.0f, half = 0x6800
float = 2050.0f, half = 0x6801
float = 2051.0f, half = 0x6802
float = 2052.0f, half = 0x6802
float = 2053.0f, half = 0x6802
X86 implementation (VCVTPS2PH)
short x86_toHalf(float f)
{
__v4sf v = {f, 0, 0, 0};
__v8hi r = __builtin_ia32_vcvtps2ph(v, 0);
return r[0];
}
float = 2048.0f, half = 0x6800
float = 2049.0f, half = 0x6800
float = 2050.0f, half = 0x6801
float = 2051.0f, half = 0x6802
float = 2052.0f, half = 0x6802
float = 2053.0f, half = 0x6802
Java implementation WITH this patch
android.util.Half.toHalf(short);
float = 2048.0f, half = 0x6800
float = 2049.0f, half = 0x6800 // Correctly rounded to even
float = 2050.0f, half = 0x6801
float = 2051.0f, half = 0x6802
float = 2052.0f, half = 0x6802
float = 2053.0f, half = 0x6802 // Correctly rounded to even
FP16.toHalf Java implementation WITHOUT this patch
android.util.Half.toHalf(short);
float = 2048.0f, half = 0x6800
float = 2049.0f, half = 0x6801 // rounded to nearest 0.5 which is not IEEE behaviour
float = 2050.0f, half = 0x6801
float = 2051.0f, half = 0x6802
float = 2052.0f, half = 0x6802
float = 2053.0f, half = 0x6803 // rounded to nearest 0.5 which is not IEEE behaviour
Test: cts-tradefed run singleCommand cts-dev --module CtsUtilTestCases --test android.util.cts.HalfTest
Change-Id: I6b1f1e39d3d53f9339b8488ab9961cf1fd91ce19
Signed-off-by: Pranav Vashi <neobuddy89@gmail.com>
1 file changed