sun_solaris_cr_6855875_typeset_hexfloat_has_too_few_digits.sh revision 34f9b3eef6fdadbda0a846aa4d68691ac40eace5
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz# CDDL HEADER START
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz# The contents of this file are subject to the terms of the
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz# Common Development and Distribution License (the "License").
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz# You may not use this file except in compliance with the License.
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz# See the License for the specific language governing permissions
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz# and limitations under the License.
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz# When distributing Covered Code, include this CDDL HEADER in each
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz# If applicable, add the following below this CDDL HEADER, with the
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz# fields enclosed by brackets "[]" replaced with your own identifying
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz# information: Portions Copyright [yyyy] [name of copyright owner]
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz# CDDL HEADER END
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz# Use is subject to license terms.
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz# This test checks whether arithmetric math correctly
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz# converts a IEEE 754-2008 floating-point value to the C99 hexfloat format
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz# and back _without_ using digits.
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz# This was reported as CR #6855875 ("typeset -X x ; print $x # does not
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz# print sufficient digits to restore value"):
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz# ------------ snip ------------
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz# $ typeset -X varname # was added to ksh93 to get a reliable way
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz# (using the C99 "hexfloat" format (see printf(3c)'s "%a" format)) to
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz# serialise a IEEE754-2008 floating-point value to a string and later feed
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz# it back into a application _without_ loosing any precision (normal
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz# base10 floating-point values (e.g. used by $ typeset -E/-F-G #) cause
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz# rounding errors since IEEE754-2008 |long double| uses base2).
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz# However $ typeset -l -X x ; ... ; print $x # currently does not print
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz# sufficient number of digits to restore the full |long double| value as
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz# expected, instead some digits are missing, resulting in an unwanted
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz# $ ksh93 -c 'typeset -l -X y y_ascii; (( y=sin(90) )) ; y_ascii=$y ; (( y
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz# == y_ascii )) || print "no match,\n\t$(printf "%a\n" y)\n!=\n\t$(printf
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz# "%a\n" y_ascii)"'
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz# 0x1.c9b9ee41cb8665c7890a136ace6bp-01
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz# 0x1.c9b9ee41cc000000000000000000p-01
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz# Steps to Reproduce
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz# [See description]
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz# Expected Result
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz# [See description]
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz# Actual Result
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz# [See description]
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz# Error Message(s)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz# typeset -l -X y y_ascii
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz# (( y=sin(90) ))
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz# y_ascii=$y # convert y to string and store it in "y_ascii"
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz# if (( y == y_ascii )) ; then
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz# print "no match,\n\t$(printf "%a\n" y)\n!=\n\t$(printf "%a\n"
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz# 1. Manually increase the number of digits via typeset
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz# -X<numdigits>
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz# 2. Use $ printf "%a" varname #
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz# ------------ snip ------------
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz# declare variables
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainztypeset -l -X y # hexfloat
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz# create array of test values
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainztest_values+=( 0 -0 +0 ) # (nan -nan inf -inf) are excluded since nan!=nan is always "true"
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz# run the tests
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainzfor (( i=0 ; i < ${#test_values[@]} ; i++ )) ; do
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz # convert floating-point value to string (using the hexfloat format) and store it in "str"
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz (( y == y_restored1 )) || err_exit "no match,"$'\n\t'"$(printf "%a\n" y)"$'\n'"!="$'\n\t'"$(printf "%a\n" y_restored1)"
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz (( y == y_restored2 )) || err_exit "no match,"$'\n\t'"$(printf "%a\n" y)"$'\n'"!="$'\n\t'"$(printf "%a\n" y_restored2)"
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz (( y == y_restored3 )) || err_exit "no match,"$'\n\t'"$(printf "%a\n" y)"$'\n'"!="$'\n\t'"$(printf "%a\n" y_restored3)"
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz # convert it back (using arithmetric expression)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz (( y == y_restored1 )) || err_exit "no match,"$'\n\t'"$(printf "%a\n" y)"$'\n'"!="$'\n\t'"$(printf "%a\n" y_restored1)"
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz (( y == y_restored2 )) || err_exit "no match,"$'\n\t'"$(printf "%a\n" y)"$'\n'"!="$'\n\t'"$(printf "%a\n" y_restored2)"
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz (( y == y_restored3 )) || err_exit "no match,"$'\n\t'"$(printf "%a\n" y)"$'\n'"!="$'\n\t'"$(printf "%a\n" y_restored3)"
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz # we exit if we get more than 8 errors (126 would be the maximum)