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