[2/3] Add more tests for trunc.

Message ID 1464139950-31943-2-git-send-email-mattst88@gmail.com
State New, archived
Headers

Commit Message

Matt Turner May 25, 2016, 1:32 a.m. UTC
  Some implementations of truncf(x) add 2**23 to x with the rounding mode
set to truncate before subtracting 2**23 to produce the truncated
result. Unfortunately this doesn't work for odd values of x greater than
2**23, since the result of the addition is inexact and the parity bit is
lost by the rounding step. The same problems apply to implementations of
trunc on other floating-point data types.

2016-05-24  Matt Turner  <mattst88@gmail.com>

        * math/libm-test.inc (trunc_test_data): Add tests for odd
        values.
---
 math/libm-test.inc | 10 ++++++++++
 1 file changed, 10 insertions(+)
  

Comments

Joseph Myers May 25, 2016, 10:46 a.m. UTC | #1
On Tue, 24 May 2016, Matt Turner wrote:

> Some implementations of truncf(x) add 2**23 to x with the rounding mode
> set to truncate before subtracting 2**23 to produce the truncated
> result. Unfortunately this doesn't work for odd values of x greater than
> 2**23, since the result of the addition is inexact and the parity bit is
> lost by the rounding step. The same problems apply to implementations of
> trunc on other floating-point data types.

I think the same tests should be added for all of ceil, floor, round, 
trunc if not already present.

> +    TEST_f_f (trunc, 0x1p63 + 1, 0x1p63 + 1, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
>      TEST_f_f (trunc, 0x1p64, 0x1p64, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
>      TEST_f_f (trunc, 0x1p65, 0x1p65, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
>      TEST_f_f (trunc, 0x1p105, 0x1p105, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
> +    TEST_f_f (trunc, 0x1p105 + 1, 0x1p105 + 1, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
>      TEST_f_f (trunc, 0x1p106, 0x1p106, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
>      TEST_f_f (trunc, 0x1p107, 0x1p107, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
>      TEST_f_f (trunc, 0x1p112, 0x1p112, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
> +    TEST_f_f (trunc, 0x1p112 + 1, 0x1p112 + 1, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),

These need to suffix the constants with 'L' so that they actually test 
what's intended for long double.  And doing arithmetic like that in 
libm-test.inc makes manipulation to change suffixes, as in 
<https://sourceware.org/ml/libc-alpha/2016-05/msg00474.html>, harder.  So 
I think it's better to write all the constants explicitly without 
arithmetic (0x1.000002p23L, 0x1.0000000000001p52L, 
0x1.0000000000000002p63L, 0x1.000000000000000000000000008p105L, 
0x1.0000000000000000000000000001p112L).
  

Patch

diff --git a/math/libm-test.inc b/math/libm-test.inc
index f1ba7dd..84c119a 100644
--- a/math/libm-test.inc
+++ b/math/libm-test.inc
@@ -11413,18 +11413,23 @@  static const struct test_f_f_data trunc_test_data[] =
     TEST_f_f (trunc, 1, 1, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
     TEST_f_f (trunc, 2, 2, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
     TEST_f_f (trunc, 0x1p23, 0x1p23, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_f_f (trunc, 0x1p23 + 1, 0x1p23 + 1, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
     TEST_f_f (trunc, 0x1p24, 0x1p24, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
     TEST_f_f (trunc, 0x1p25, 0x1p25, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
     TEST_f_f (trunc, 0x1p52, 0x1p52, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_f_f (trunc, 0x1p52 + 1, 0x1p52 + 1, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
     TEST_f_f (trunc, 0x1p53, 0x1p53, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
     TEST_f_f (trunc, 0x1p54, 0x1p54, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
     TEST_f_f (trunc, 0x1p63, 0x1p63, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_f_f (trunc, 0x1p63 + 1, 0x1p63 + 1, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
     TEST_f_f (trunc, 0x1p64, 0x1p64, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
     TEST_f_f (trunc, 0x1p65, 0x1p65, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
     TEST_f_f (trunc, 0x1p105, 0x1p105, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_f_f (trunc, 0x1p105 + 1, 0x1p105 + 1, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
     TEST_f_f (trunc, 0x1p106, 0x1p106, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
     TEST_f_f (trunc, 0x1p107, 0x1p107, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
     TEST_f_f (trunc, 0x1p112, 0x1p112, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_f_f (trunc, 0x1p112 + 1, 0x1p112 + 1, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
     TEST_f_f (trunc, 0x1p113, 0x1p113, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
     TEST_f_f (trunc, 0x1p114, 0x1p114, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
     TEST_f_f (trunc, max_value, max_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
@@ -11433,18 +11438,23 @@  static const struct test_f_f_data trunc_test_data[] =
     TEST_f_f (trunc, -1, -1, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
     TEST_f_f (trunc, -2, -2, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
     TEST_f_f (trunc, -0x1p23, -0x1p23, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_f_f (trunc, -0x1p23 - 1, -0x1p23 - 1, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
     TEST_f_f (trunc, -0x1p24, -0x1p24, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
     TEST_f_f (trunc, -0x1p25, -0x1p25, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
     TEST_f_f (trunc, -0x1p52, -0x1p52, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_f_f (trunc, -0x1p52 - 1, -0x1p52 - 1, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
     TEST_f_f (trunc, -0x1p53, -0x1p53, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
     TEST_f_f (trunc, -0x1p54, -0x1p54, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
     TEST_f_f (trunc, -0x1p63, -0x1p63, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_f_f (trunc, -0x1p63 - 1, -0x1p63 - 1, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
     TEST_f_f (trunc, -0x1p64, -0x1p64, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
     TEST_f_f (trunc, -0x1p65, -0x1p65, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
     TEST_f_f (trunc, -0x1p105, -0x1p105, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_f_f (trunc, -0x1p105 - 1, -0x1p105 - 1, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
     TEST_f_f (trunc, -0x1p106, -0x1p106, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
     TEST_f_f (trunc, -0x1p107, -0x1p107, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
     TEST_f_f (trunc, -0x1p112, -0x1p112, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_f_f (trunc, -0x1p112 - 1, -0x1p112 - 1, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
     TEST_f_f (trunc, -0x1p113, -0x1p113, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
     TEST_f_f (trunc, -0x1p114, -0x1p114, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
     TEST_f_f (trunc, -max_value, -max_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),