xref: /illumos-gate/usr/src/cmd/ast/libshell/common/tests/sun_solaris_cr_6789247_printf_hexfloat_rounding.sh (revision 3aa6c13072f3d4792a18693e916aed260a496c1f)
1#
2# CDDL HEADER START
3#
4# The contents of this file are subject to the terms of the
5# Common Development and Distribution License (the "License").
6# You may not use this file except in compliance with the License.
7#
8# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9# or http://www.opensolaris.org/os/licensing.
10# See the License for the specific language governing permissions
11# and limitations under the License.
12#
13# When distributing Covered Code, include this CDDL HEADER in each
14# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15# If applicable, add the following below this CDDL HEADER, with the
16# fields enclosed by brackets "[]" replaced with your own identifying
17# information: Portions Copyright [yyyy] [name of copyright owner]
18#
19# CDDL HEADER END
20#
21
22#
23# Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
24#
25
26#
27# This test checks whether arithmetric math correctly supports
28# negative zero values
29#
30# This was reported as CR #6789247 ("libast/ksh93 1-digit hexfloat base conversion rounds incorrectly"):
31# ---- snip ----
32# Description
33#   [The same issue was described in http://mail.opensolaris.org/pipermail/ksh93-integration-discuss/2008-December/006737.html]
34#   This is basically a spin-off of http://bugs.opensolaris.org/view_bug.do?bug_id=6773712 ("1-digit hex fp
35#   base conversion of long double rounds incorrectly").
36#   The bug description for Solaris libc says this:
37#   > The first line of output from this program is correct.  The second line
38#   > is not.
39#   >
40#   > leviathan% cat a.c
41#   > #include <stdio.h>
42#   >
43#   > int main()
44#   > {
45#   >     printf("%.0a\n", 1.5);
46#   >     printf("%.0La\n", 1.5L);
47#   >     return 0;
48#   > }
49#   > leviathan% cc -o a a.c
50#   > leviathan% a
51#   > 0x1p+1
52#   > 0x1p+0
53#   > leviathan%
54#   If I compile the testcase with libast on Solaris 11/B84 SPARC (which
55#   matches ast-open.2008-11-04) I get this:
56#   -- snip --
57#   $ cc -xc99=%all -I/usr/include/ast -last a.c -o a &&
58#   ./a
59#   0x1p+00
60#   0x1p+00
61#   -- snip --
62#   ... which seems to be incorrect per the bugs comment above and should
63#   be:
64#   -- snip --
65#   0x1p+1
66#   0x1p+1
67#   -- snip --
68#   ksh93 has the same problem:
69#   $ ksh93 -c 'float r=1.5 ; printf "%.0a\n" r'
70#   0x1p+00
71# Steps to Reproduce
72#    Compile and run testcase like this:
73#    -- snip --
74#    $ cc -xc99=%all -I/usr/include/ast -last a.c -o a &&
75#    ./a
76#    -- snip --
77# Expected Result
78#    0x1p+1
79#    0x1p+1
80# Actual Result
81#    0x1p+00
82#    0x1p+00
83# ---- snip ----
84#
85
86# test setup
87function err_exit
88{
89	print -u2 -n "\t"
90	print -u2 -r ${Command}[$1]: "${@:2}"
91	(( Errors < 127 && Errors++ ))
92}
93alias err_exit='err_exit $LINENO'
94
95set -o nounset
96Command=${0##*/}
97integer Errors=0
98
99
100float r
101float result
102typeset str
103
104# Test #001/a - check whether the result of a rounded 1.5 is 2.0
105r=1.5
106result=$(printf "%.0a\n" r) || err_exit "printf returned non-zero exit code"
107(( result == 2.0 )) || err_exit "result expected to be 2.0, got ${result}"
108
109
110# Test #001/b - same as test #001/a but uses "%.0A\n" instead of "%.0a\n"
111r=1.5
112result=$(printf "%.0A\n" r) || err_exit "printf returned non-zero exit code"
113(( result == 2.0 )) || err_exit "result expected to be 2.0, got ${result}"
114
115
116# Test #002/a - check whether the hexfloat string value matches the expected pattern
117r=1.5
118str=$(printf "%.0a\n" r) || err_exit "printf returned non-zero exit code"
119[[ "${str}" == ~(Glri)0x0*1p\+0*1 ]] || err_exit "str expected to match ~(Glri)0x0*1p\+0*1, got |${str}|"
120
121
122# Test #002/b - same as test #002/a but uses "%.0A\n" instead of "%.0a\n"
123r=1.5
124str=$(printf "%.0A\n" r) || err_exit "printf returned non-zero exit code"
125[[ "${str}" == ~(Glri)0x0*1p\+0*1 ]] || err_exit "str expected to match ~(Glri)0x0*1p\+0*1, got |${str}|"
126
127
128# tests done
129exit $((Errors))
130