--- /dev/null
+!! This file contains precision and range independent test vectors for
+!! the operation addition/subtraction (+). The first character in each
+!! test vector refers to the origin of the test vector
+!!
+!! 2: Jerome Coonen Version <2>
+!! 3: Jerome Coonen Version <3>
+!! @Phdthesis{
+!! author = {Coonen, J.T.},
+!! title = {Contributions to a proposed standard for binary
+!! floating-point arithmetic},
+!! school = {University of California, Berkeley},
+!! year = {1984}}
+!!
+!! H: precision independent encoding of UCB/<H>ough test vector
+!! @Unpublished{
+!! author = {David G. Hough and others},
+!! title = {{UCBTEST}, a suite of programs for testing certain
+!! difficult cases of {IEEE} 754 floating-point arithmetic},
+!! year = {1988},
+!! note = {Restricted public domain software from
+!! http://netlib.bell-labs.com/netlib/fp/index.html}}
+!!
+!! A: Verdonk-Cuyt-Verschaeren (University of <A>ntwerp)
+!! @Article{
+!! author = {Verdonk, B. and Cuyt, A. and Verschaeren, D.},
+!! title = {A precision- and range-independent tool for testing
+!! floating-point arithmetic {I}: basic operations,
+!! square root and remainder},
+!! journal = {ACM TOMS},
+!! volume = {27},
+!! number = {1},
+!! pages = {92-118},
+!! year = {2001}}
+!! note = {Under revision}}
+!!
+!! This file is part of the tool IeeeCC754 or IEEE 754 Compliance Checker.
+!! It is a precision and range independent tool to test whether
+!! an implementation of floating-point arithmetic (in hardware or
+!! software) is compliant with the principles of the IEEE 754-854
+!! floating-point standards. You can find out more about the testing
+!! tool IeeeCC754 and the syntax and semantics of the test vectors
+!! at
+!! http://win-www.uia.ac.be/u/cant/ieeecc754.html
+!!
+!! Last updated:
+!! $Date$
+!!
+!! Contact:
+!! Brigitte.Verdonk@ua.ac.be
+!! Department of Mathematics and Computer Science
+!! University of Antwerp (UIA)
+!! Universiteitsplein 1
+!! B2610 Antwerp, BELGIUM
+!!!! first some easy cases
+2+ ALL 1 1 OK 2
+!! c0a00000 00000000 c0a00000 00000000 c0b00000 00000000
+H+ ALL -1 -1 OK -2
+2+ ALL 1 2 OK 3
+!! c0a00000 00000000 c0b00000 00000000 c0b80000 00000000
+H+ ALL -1 -2 OK -3
+2+ ALL 2 2 OK 4
+2+ ALL 1 7 OK 8
+A+ ALL -1 -7 OK -8
+2+ ALL 5 -1 OK 4
+A+ ALL -5 1 OK -4
+2+ ALL 2 -5 OK -3
+A+ ALL -2 5 OK 3
+!! 40a00000 00000000 c0b00000 00000000 c0a00000 00000000
+H+ ALL 2 -4 OK -2
+!! 40b00000 00000000 c0a00000 00000000 40a00000 00000000
+H+ ALL 4 -2 OK 2
+!! c0a00000 00000000 40b00000 00000000 40a00000 00000000
+!! c0b00000 00000000 40a00000 00000000 c0a00000 00000000
+
+!! Special representations
+
+! Zero vs Zero -- watch signs and rounding modes.
+2+ =0> 0 -0 OK 0
+2+ < 0 -0 OK -0
+2+ ALL 0 0 OK 0
+2+ ALL -0 -0 OK -0
+!! Zero vs denormalized
+2+ ALL 0 Td1 OK Td1
+2+ ALL -0 Td1 OK Td1
+2+ ALL 0 -Td1 OK -Td1
+2+ ALL -0 -Td1 OK -Td1
+2+ ALL 0i3 0 OK 0i3
+2+ ALL 0i3 -0 OK 0i3
+2+ ALL -0i3 0 OK -0i3
+2+ ALL -0i3 -0 OK -0i3
+!! Zero vs normal -- watch that sign of 0 is meaningless
+2+ ALL -0 -T OK -T
+2+ ALL T 0 OK T
+2+ ALL 0 -T OK -T
+2+ ALL 0 Hm1 OK Hm1
+2+ ALL -0 Hm1 OK Hm1
+2+ ALL -Hm1 0 OK -Hm1
+2+ ALL -Hm1 -0 OK -Hm1
+2+ ALL 1 -0 OK 1
+2+ ALL -1 -0 OK -1
+2+ ALL 0 1 OK 1
+2+ ALL 5 -0 OK 5
+2+ ALL 5 +0 OK 5
+! Infinity vs 0.
+2+ ALL H 0 OK H
+2+ ALL H -0 OK H
+2+ ALL -H 0 OK -H
+2+ ALL -H -0 OK -H
+!! NaN versus 0
+2+ ALL Q 0 OK Q
+2+ ALL Q -0 OK Q
+! 2+ ALL S 0 i Q
+! 2+ ALL S -0 i Q
+! 2+ ALL 0 S i Q
+! 2+ ALL -0 S i Q
+! Infinity vs Infinity.
+2+ ALL H H OK H ok - affine sum
+2+ ALL -H -H OK -H
+2+ ALL -H H i Q different signs
+! Infinity vs denormalized.
+2+ ALL H Td1 OK H
+2+ ALL -H Td1 OK -H
+2+ ALL H -Td1 OK H
+2+ ALL -H -Td1 OK -H
+2+ ALL 0i3 H OK H
+2+ ALL 0i3 -H OK -H
+2+ ALL -0i3 H OK H
+2+ ALL -0i3 -H OK -H
+! Infinity vs huge.
+2+ ALL H Hm1 OK H
+2+ ALL H -Hm1 OK H
+2+ ALL -H Hm1 OK -H
+2+ ALL -H -Hm1 OK -H
+!! Infinity vs NaN
+2+ ALL Q H OK Q
+2+ ALL Q -H OK Q
+! 2+ ALL S H i Q
+! 2+ ALL S -H i Q
+! 2+ ALL H S i Q
+! 2+ ALL -H S i Q
+!! NaN versus NaN
+2+ ALL Q Q OK Q
+! 2+ ALL Q S i Q
+! 2+ ALL S Q i Q
+! 2+ ALL S S i Q
+!! NaN versus denormal
+2+ ALL Td1 Q OK Q
+2+ ALL -Td1 Q OK Q
+2+ ALL Q 0i1 OK Q
+2+ ALL Q -0i1 OK Q
+! 2+ ALL Td1 S i Q
+! 2+ ALL -Td1 S i Q
+! 2+ ALL S Td1 i Q
+! 2+ ALL S -Td1 i Q
+! 2+ ALL S 0i1 i Q
+! 2+ ALL S -0i1 i Q
+! 2+ ALL 0i1 S i Q
+! 2+ ALL -0i1 S i Q
+!! NaN versus normal
+2+ ALL Q 1 OK Q
+2+ ALL Q -1 OK Q
+2+ ALL Q Hd1 OK Q
+2+ ALL Q -Hd1 OK Q
+! 2+ ALL S 1 i Q
+! 2+ ALL S -1 i Q
+! 2+ ALL 1 S i Q
+! 2+ ALL -1 S i Q
+! 2+ ALL S Hd1 i Q
+! 2+ ALL S -Hd1 i Q
+! 2+ ALL Hd1 S i Q
+! 2+ ALL -Hd1 S i Q
+
+!! Exceptions
+
+!! invalid, only for operations involving SNaNs, see above
+!! inexact, overflow
+!! leading bits => carry
+2+ => Hm1 Hm1 xo H
+2+ 0< Hm1 Hm1 xo Hd1
+2+ =< -Hm1 -Hm1 xo -H
+2+ 0> -Hm1 -Hm1 xo -Hd1
+2+ => Hd2 Hd2 xo H
+2+ 0< Hd2 Hd2 xo Hd1
+2+ =< -Hd2 -Hd2 xo -H
+2+ 0> -Hd2 -Hd2 xo -Hd1
+2+ => Hd2 Hd1 xo H
+2+ 0< Hd2 Hd1 xo Hd1
+2+ =< -Hd2 -Hd1 xo -H
+2+ 0> -Hd2 -Hd1 xo -Hd1
+2+ => Hm1i1 Hm1 xo H
+2+ 0< Hm1i1 Hm1 xo Hd1
+2+ =< -Hm1i1 -Hm1 xo -H
+2+ 0> -Hm1i1 -Hm1 xo -Hd1
+A+ => Hd1 Hmtp1 xo H
+A+ 0< Hd1 Hmtp1 xo Hd1
+A+ =< -Hd1 -Hmtp1 xo -H
+A+ 0> -Hd1 -Hmtp1 xo -Hd1
+!! Result = Max. normal, round bit = 0, sticky bit = 0(...1...)
+2+ =0< Hd1 1 x Hd1
+2+ > Hd1 1 xo H
+!! 3ff00000 00000000 7fefffff ffffffff 7fefffff ffffffff
+2+ =0> -Hd1 -1 x -Hd1
+2+ < -Hd1 -1 xo -H
+!! bff00000 00000000 ffefffff ffffffff ffefffff ffffffff
+!! bff00000 00000000 ffefffff ffffffff fff00000 00000000
+2+ =0< 0i1 Hd1 x Hd1
+2+ > 0i1 Hd1 xo H
+2+ =0> -0i1 -Hd1 x -Hd1
+2+ < -0i1 -Hd1 xo -H
+!! Result = Max. normal, round bit = 0, sticky bit = 1(0000...)
+A+ =0< Hd1 Hmtm2 x Hd1
+A+ > Hd1 Hmtm2 xo H
+A+ =0> -Hd1 -Hmtm2 x -Hd1
+A+ < -Hd1 -Hmtm2 xo -H
+!! Result = Max. normal, round bit = 0, sticky bit = 1(...1...)
+A+ =0< Hd1 Hmtm2i1 x Hd1
+A+ > Hd1 Hmtm2i1 xo H
+A+ =0> -Hd1 -Hmtm2i1 x -Hd1
+A+ < -Hd1 -Hmtm2i1 xo -H
+!! Result = Max. normal, round bit = 1, sticky bit = 0 => round to even
+2+ => Hm1d1 Hm1 xo H
+2+ 0< Hm1d1 Hm1 x Hd1
+2+ =< -Hm1d1 -Hm1 xo -H
+2+ 0> -Hm1d1 -Hm1 x -Hd1
+!! Result = Max. normal, round bit = 1, sticky bit = 1(0000...)
+A+ => Hd1 3pB0mtm1 xo H
+A+ 0< Hd1 3pB0mtm1 x Hd1
+A+ =< -Hd1 -3pB0mtm1 xo -H
+A+ 0> -Hd1 -3pB0mtm1 x -Hd1
+!! Result = Max. normal, round bit = 1, sticky bit = 0(...1...)
+A+ => Hd1 Hmtm1i1 xo H
+A+ 0< Hd1 Hmtm1i1 x Hd1
+A+ =< -Hd1 -Hmtm1i1 xo -H
+A+ 0> -Hd1 -Hmtm1i1 x -Hd1
+!! Result = Max. normal, round bit = 1, sticky bit = 1(...1...)
+A+ => Hd1 3pB0mtm1i1 xo H
+A+ 0< Hd1 3pB0mtm1i1 x Hd1
+A+ =< -Hd1 -3pB0mtm1i1 xo -H
+A+ 0> -Hd1 -3pB0mtm1i1 x -Hd1
+!! Exp. Z = U - 1, Result <= Max. normal, no overflow
+2+ =0< Hm1 1 x Hm1
+2+ > Hm1 1 x Hm1i1
+2+ =0> -Hm1 -1 x -Hm1
+2+ < -Hm1 -1 x -Hm1i1
+2+ =0< Hm1d1 1 x Hm1d1
+2+ > Hm1d1 1 x Hm1
+2+ =0< Hd2 1 x Hd2
+2+ > Hd2 1 x Hd1
+2+ =0> -Hd2 -1 x -Hd2
+2+ < -Hd2 -1 x -Hd1
+!! bff00000 00000000 ffeffffff fffffffe ffefffff fffffffe
+!! bff00000 00000000 ffeffffff fffffffe ffefffff ffffffff
+2+ =0< 0i1 Hm1 x Hm1
+2+ > 0i1 Hm1 x Hm1i1
+2+ =0> -0i1 -Hm1 x -Hm1
+2+ < -0i1 -Hm1 x -Hm1i1
+2+ =0< 0i1 Hm1d1 x Hm1d1
+2+ > 0i1 Hm1d1 x Hm1
+2+ =0> -0i1 -Hm1d1 x -Hm1d1
+2+ < -0i1 -Hm1d1 x -Hm1
+2+ =0< 0i1 Hd2 x Hd2
+2+ > 0i1 Hd2 x Hd1
+2+ =0> -0i1 -Hd2 x -Hd2
+2+ < -0i1 -Hd2 x -Hd1
+!! Result <= Max. normal, no overflow
+A+ ALL Hm1 Hmt OK Hm1i1
+A+ ALL -Hm1 -Hmt OK -Hm1i1
+2+ ALL Hm1d2 Hm1d2 OK Hd2
+2+ ALL -Hm1d2 -Hm1d2 OK -Hd2
+! Double an innocent number.
+2+ ALL 3 3 OK 6
+2+ ALL T T OK Tp1
+2+ ALL Hm2 Hm2 OK Hm1
+!! underflow cannot occur
+! Double a tiny number
+2+ ALL Td1 Td1 OK Tp1d2
+2+ ALL -Td1 -Td1 OK -Tp1d2
+2+ ALL 0i4 0i4 OK 0i8
+2+ ALL -0i4 -0i4 OK -0i8
+2+ ALL 0i1 0i1 OK 0i2
+2+ ALL -0i1 -0i1 OK -0i2
+!! inexact, see rounding below
+
+!! Exact rounding
+
+!! round bit = 0, sticky bit = 0(...1...) => inexact, round down
+!! normals
+A+ =0< 1i1 8 x 9
+A+ > 1i1 8 x 9i1
+A+ =0> -1i1 -8 x -9
+A+ < -1i1 -8 x -9i1
+A+ =0< 1ptp2 1 x 1ptp2
+A+ > 1ptp2 1 x 1ptp2i1
+A+ =0> -1ptp2 -1 x -1ptp2
+A+ < -1ptp2 -1 x -1ptp2i1
+!! bff00000 00000000 ffe00000 00000000 ffe00000 00000000
+!! bff00000 00000000 ffe00000 00000000 ffe00000 00000001
+! Medium vs denormal.
+A+ =0< Tp3 0i1 x Tp3
+A+ > Tp3 0i1 x Tp3i1
+A+ =0> -Tp3 -0i1 x -Tp3
+A+ < -Tp3 -0i1 x -Tp3i1
+2+ =0< 0i1 1 x 1
+2+ > 0i1 1 x 1i1
+2+ =0> -0i1 -1 x -1
+2+ < -0i1 -1 x -1i1
+!! bff00000 0000000 80000000 00000001 bff00000 00000000
+!! bff00000 0000000 80000000 00000001 bff00000 00000001
+2+ =0< 0i1 1d1 x 1d1
+2+ > 0i1 1d1 x 1
+2+ =0> -0i1 -1d1 x -1d1
+2+ < -0i1 -1d1 x -1
+2+ =0< 0i1 2d1 x 2d1
+2+ > 0i1 2d1 x 2
+2+ =0> -0i1 -2d1 x -2d1
+2+ < -0i1 -2d1 x -2
+2+ =0< 0i1 2d2 x 2d2
+2+ > 0i1 2d2 x 2d1
+2+ =0> -0i1 -2d2 x -2d2
+2+ < -0i1 -2d2 x -2d1
+!! after carry propagation
+!! 3fefffff ffffffff 3cb00800 00000000 3ff00000 00000000
+H+ =0< 8ptd1 11 x 8pt
+!! 3fefffff ffffffff 3cb00800 00000000 3ff00000 00000001
+H+ > 8ptd1 11 x 8pti1
+!! bfefffff ffffffff bcb00800 00000000 bff00000 00000000
+H+ =0> -8ptd1 -11 x -8pt
+!! bfefffff ffffffff bcb00800 00000000 bff00000 00000001
+H+ < -8ptd1 -11 x -8pti1
+!! subtract
+!! normal operands
+A+ > 7pt -7 x 7pt
+A+ =0< 7pt -7 x 7ptd1
+A+ < 7 -7pt x -7pt
+A+ =0> 7 -7pt x -7ptd1
+!! denormal operand
+A+ > Tp4 -0i7 x Tp4
+A+ =0< Tp4 -0i7 x Tp4d1
+A+ < -Tp4 0i7 x -Tp4
+A+ =0> -Tp4 0i7 x -Tp4d1
+!! round bit = 0, sticky bit = 1(0000...) => inexact, round down
+!! normal operands
+A+ =0< 1i1 4 x 5
+A+ > 1i1 4 x 5i1
+A+ =0> -1i1 -4 x -5
+A+ < -1i1 -4 x -5i1
+A+ =0< 1ptp1 1 x 1ptp1
+A+ > 1ptp1 1 x 1ptp1i1
+A+ =0> -1ptp1 -1 x -1ptp1
+A+ < -1ptp1 -1 x -1ptp1i1
+!! after carry propagation
+A+ =0< 10 8ptd1 x 8pt
+A+ > 10 8ptd1 x 8pti1
+A+ =0> -10 -8ptd1 x -8pt
+A+ < -10 -8ptd1 x -8pti1
+!! subtract
+!! normal operands
+A+ =0< 4 -3mt x 4d1
+A+ > 4 -3mt x 4
+A+ =0> 3 -4pt x -4ptd1
+A+ < 3 -4pt x -4pt
+A+ =0> -4 +3mt x -4d1
+A+ < -4 +3mt x -4
+A+ =0< -3 4pt x 4ptd1
+A+ > -3 4pt x 4pt
+!! denormal operand
+A+ =0< Tp3 -0i3 x Tp3d1
+A+ > Tp3 -0i3 x Tp3
+A+ =0> -Tp3 0i3 x -Tp3d1
+A+ < -Tp3 0i3 x -Tp3
+!! round bit = 0, sticky bit = 1 => inexact, round down
+A+ =0< 1i3 8 x 9
+A+ > 1i3 8 x 9i1
+A+ =0> -1i3 -8 x -9
+A+ < -1i3 -8 x -9i1
+2+ > 4d1 1u1d1 x 4
+2+ 0=< 4d1 1u1d1 x 4d1
+2+ < -4d1 -1u1d1 x -4
+2+ 0=> -4d1 -1u1d1 x -4d1
+!! denormal
+A+ =0< Tp3 0i3 x Tp3
+A+ > Tp3 0i3 x Tp3i1
+A+ =0> -0i3 -Tp3 x -Tp3
+A+ < -0i3 -Tp3 x -Tp3i1
+!! after carry propagation
+A+ =0< 14 8ptd1 x 8pt
+A+ > 14 8ptd1 x 8pti1
+A+ =0> -14 -8ptd1 x -8pt
+A+ < -14 -8ptd1 x -8pti1
+!! subtract
+!! normal operands
+A+ =0< 8 -5mt x 8d1
+A+ > 8 -5mt x 8
+A+ =0> 5 -8pt x -8ptd1
+A+ < 5 -8pt x -8pt
+A+ =0> -8 +5mt x -8d1
+A+ < -8 +5mt x -8
+A+ =0< -5 8pt x 8ptd1
+A+ > -5 8pt x 8pt
+!! denormal operand
+A+ =0< Tp4 -0i5 x Tp4d1
+A+ > Tp4 -0i5 x Tp4
+A+ =0> -Tp4 0i5 x -Tp4d1
+A+ < -Tp4 0i5 x -Tp4
+!! round bit = 1, sticky bit = 0
+!! half-way cases, round to even
+!! even result
+!! normal operands
+A+ =0< 1u1 2 x 2
+A+ > 1u1 2 x 2i1
+A+ =0> -1u1 -2 x -2
+A+ < -1u1 -2 x -2i1
+!! denormal
+A+ =0< 0i1 Tp1 x Tp1
+A+ > 0i1 Tp1 x Tp1i1
+A+ =0> -0i1 -Tp1 x -Tp1
+A+ < -0i1 -Tp1 x -Tp1i1
+!! after carry propagation
+2+ =0< 1i1 1 x 2
+2+ > 1i1 1 x 2i1
+2+ =0> -1i1 -1 x -2
+2+ < -1i1 -1 x -2i1
+!! bff00000 00000000 bff00000 00000001 c0000000 00000000
+!! bff00000 00000000 bff00000 00000001 c0000000 00000001
+2+ =0< Hm2i1 Hm2 x Hm1
+2+ > Hm2i1 Hm2 x Hm1i1
+2+ =0< 2 2i1 x 4
+2+ > 2 2i1 x 4i1
+2+ =0< Hm1d2 Hm1d1 x Hd2
+2+ > Hm1d2 Hm1d1 x Hd1
+2+ =0> -Hm2i1 -Hm2 x -Hm1
+2+ < -Hm2i1 -Hm2 x -Hm1i1
+2+ =0> -2 -2i1 x -4
+2+ < -2 -2i1 x -4i1
+2+ =0> -Hm1d2 -Hm1d1 x -Hd2
+2+ < -Hm1d2 -Hm1d1 x -Hd1
+!! subtract
+!! normal operands
+A+ =0< 1i1 -1u1m1 x 1
+A+ > 1i1 -1u1m1 x 1i1
+A+ =0> 1u1m1 -1i1 x -1
+A+ < 1u1m1 -1i1 x -1i1
+!! denormal
+A+ =0< Tp1i1 -0i1 x Tp1
+A+ > Tp1i1 -0i1 x Tp1i1
+A+ =0> -Tp1i1 0i1 x -Tp1
+A+ < -Tp1i1 0i1 x -Tp1i1
+!! odd result
+!! normal operands
+A+ => 1u1 4d1 x 4
+A+ 0< 1u1 4d1 x 4d1
+A+ =< -1u1 -4d1 x -4
+A+ 0> -1u1 -4d1 x -4d1
+!! denormal
+A+ => 0i1 Tp1i1 x Tp1i2
+A+ 0< 0i1 Tp1i1 x Tp1i1
+A+ =< -0i1 -Tp1i1 x -Tp1i2
+A+ 0> -0i1 -Tp1i1 x -Tp1i1
+!! after carry propagation
+2+ => 1 1i3 x 2i2
+2+ 0< 1 1i3 x 2i1
+2+ => 2i1 2i2 x 4i2
+2+ 0< 2i1 2i2 x 4i1
+2+ =< -1 -1i3 x -2i2
+2+ 0> -1 -1i3 x -2i1
+2+ =< -2i1 -2i2 x -4i2
+2+ 0> -2i1 -2i2 x -4i1
+A+ => 1u1 2i1 x 2i2
+A+ 0< 1u1 2i1 x 2i1
+A+ =< -1u1 -2i1 x -2i2
+A+ 0> -1u1 -2i1 x -2i1
+!! subtract
+!! normal operands
+A+ => 2i2 -1u1 x 2i2
+A+ 0< 2i2 -1u1 x 2i1
+A+ =< 1u1 -2i2 x -2i2
+A+ 0> 1u1 -2i2 x -2i1
+!! denormal
+A+ => Tp2i2 -0i1 x Tp2i2
+A+ 0< Tp2i2 -0i1 x Tp2i1
+A+ =< -Tp2i2 0i1 x -Tp2i2
+A+ 0> -Tp2i2 0i1 x -Tp2i1
+!! round bit = 1, sticky bit = 1(0000...) => inexact, round up
+!! normals
+A+ => 1i3 4 x 5i1
+A+ 0< 4 1i3 x 5
+A+ =< -1i3 -4 x -5i1
+A+ 0> -1i3 -4 x -5
+A+ => 3 3pt x 3pti1
+A+ 0< 3 3pt x 3pt
+A+ =< -3 -3pt x -3pti1
+A+ 0> -3 -3pt x -3pt
+!! denormal
+A+ => 0i3 Tp2 x Tp2i1
+A+ 0< 0i3 Tp2 x Tp2
+A+ =< -0i3 -Tp2 x -Tp2i1
+A+ 0> -0i3 -Tp2 x -Tp2
+!! after carry propagation
+A+ => 2d1 5mt x 2i1
+A+ 0< 2d1 5mt x 2
+A+ =< -2d1 -5mt x -2i1
+A+ 0> -2d1 -5mt x -2
+!! subtract
+!! normals
+A+ => 4pt -1 x 4pt
+A+ 0< 4pt -1 x 4ptd1
+A+ =< 1 -4pt x -4pt
+A+ 0> 1 -4pt x -4ptd1
+!! denormal
+A+ => Tp3 -0i1 x Tp3
+A+ 0< Tp3 -0i1 x Tp3d1
+A+ =< -Tp3 0i1 x -Tp3
+A+ 0> -Tp3 0i1 x -Tp3d1
+!! round bit = 1, sticky bit = 0(...1...) => inexact, round up
+!! normals
+A+ => 1i5 8 x 9i1
+A+ 0< 1i5 8 x 9
+A+ =< -1i5 -8 x -9i1
+A+ 0> -1i5 -8 x -9
+A+ => 5 4pt x 4pti1
+A+ 0< 5 4pt x 4pt
+A+ =< -5 -4pt x -4pti1
+A+ 0> -5 -4pt x -4pt
+!! denormal
+A+ => 0i5 Tp3 x Tp3i1
+A+ 0< 0i5 Tp3 x Tp3
+A+ =< -0i5 -Tp3 x -Tp3i1
+A+ 0> -0i5 -Tp3 x -Tp3
+!! after carry propagation
+A+ => 2d1 4mti1 x 2i1
+A+ 0< 2d1 4mti1 x 2
+A+ =< -2d1 -4mti1 x -2i1
+A+ 0> -2d1 -4mti1 x -2
+!! subtract
+!! normal operands
+A+ => 6ptp1 -3 x 6ptp1
+A+ 0< 6ptp1 -3 x 6ptp1d1
+A+ =< 3 -6ptp1 x -6ptp1
+A+ 0> 3 -6ptp1 x -6ptp1d1
+!! denormal operand
+A+ => Tp4 -0i3 x Tp4
+A+ 0< Tp4 -0i3 x Tp4d1
+A+ =< -Tp4 0i3 x -Tp4
+A+ 0> -Tp4 0i3 x -Tp4d1
+!! round bit = 1, sticky bit = 1(...1...) => inexact, round up
+!! normal
+A+ >= 1i7 8 x 9i1
+A+ 0< 1i7 8 x 9
+A+ =< -1i7 -8 x -9i1
+A+ 0> -1i7 -8 x -9
+A+ => 7 7pt x 7pti1
+A+ 0< 7 7pt x 7pt
+A+ =< -7 -7pt x -7pti1
+A+ 0> -7 -7pt x -7pt
+!! denormal
+A+ => 0i7 Tp3 x Tp3i1
+A+ 0< 0i7 Tp3 x Tp3
+A+ =< -0i7 -Tp3 x -Tp3i1
+A+ 0> -0i7 -Tp3 x -Tp3
+!! after carry propagation
+A+ => 2d1 5mti1 x 2i1
+A+ 0< 2d1 5mti1 x 2
+A+ =< -2d1 -5mti1 x -2i1
+A+ 0> -2d1 -5mti1 x -2
+!! subtract
+! Magnitude subtract when an operand is in the sticky bit.
+! The interesting cases will arise when directed rounding
+! forces a nonzero cancellation.
+! Huge and medium.
+2+ => Hm1 -1 x Hm1
+2+ 0< Hm1 -1 x Hm1d1
+!! bff00000 00000000 7fe00000 000000000 7fe00000 00000000
+!! bff00000 00000000 7fe00000 000000000 7fdfffff ffffffff
+2+ =< -Hm1 1 x -Hm1
+2+ 0> -Hm1 1 x -Hm1d1
+!! 3ff00000 00000000 ffe00000 00000000 ffe00000 00000000
+!! 3ff00000 00000000 ffe00000 00000000 ffdfffff ffffffff
+2+ => Hm1d1 -1 x Hm1d1
+2+ 0< Hm1d1 -1 x Hm1d2
+!! bff00000 00000000 7fdfffff ffffffff 7fdfffff ffffffff
+!! bff00000 00000000 7fdfffff ffffffff 7fdfffff fffffffe
+2+ =< -Hm1d1 1 x -Hm1d1
+2+ 0> -Hm1d1 1 x -Hm1d2
+!! 3ff00000 00000000 ffdfffff ffffffff ffdfffff ffffffff
+!! 3ff00000 00000000 ffdfffff ffffffff ffdfffff fffffffe
+2+ => Hd1 -1 x Hd1
+2+ 0< Hd1 -1 x Hd2
+!! bff00000 00000000 7fefffff ffffffff 7fefffff ffffffff
+!! bff00000 00000000 7fefffff ffffffff 7fefffff fffffffe
+2+ =< -Hd1 1 x -Hd1
+2+ 0> -Hd1 1 x -Hd2
+!! 3ff00000 00000000 ffefffff ffffffff ffefffff ffffffff
+!! 3ff00000 00000000 ffefffff ffffffff ffefffff fffffffe
+2+ => Hd2 -1 x Hd2
+2+ 0< Hd2 -1 x Hd3
+!! bff00000 00000000 7fefffff fffffffe 7fefffff fffffffe
+!! bff00000 00000000 7fefffff fffffffe 7fefffff fffffffd
+2+ =< -Hd2 1 x -Hd2
+2+ 0> -Hd2 1 x -Hd3
+!! 3ff00000 00000000 ffefffff fffffffe ffefffff fffffffe
+!! 3ff00000 00000000 ffefffff fffffffe ffefffff fffffffd
+! Huge and tiny.
+2+ => Hd1 -0i1 x Hd1
+2+ 0< Hd1 -0i1 x Hd2
+2+ =< -Hd1 0i1 x -Hd1
+2+ 0> -Hd1 0i1 x -Hd2
+2+ => -0i3 Hm1 x Hm1
+2+ 0< -0i3 Hm1 x Hm1d1
+2+ =< 0i3 -Hm1 x -Hm1
+2+ 0> 0i3 -Hm1 x -Hm1d1
+! Medium and tiny.
+2+ => 1d1 -0i1 x 1d1
+2+ 0< 1d1 -0i1 x 1d2
+2+ =< -2d1 0i1 x -2d1
+2+ 0> -2d1 0i1 x -2d2
+2+ => -0i3 3 x 3
+2+ 0< -0i3 3 x 3d1
+!! 40080000 00000000 80000000 00000003 40080000 00000000
+!! 40080000 00000000 80000000 00000003 4007ffff ffffffff
+2+ =< 0i3 -5 x -5
+2+ 0> 0i3 -5 x -5d1
+!! c0140000 00000000 00000000 00000003 c0140000 00000000
+!! c0140000 00000000 00000000 00000003 c013ffff ffffffff
+
+!! cancellation
+
+! Cancellation to 0 -- to plus 0.
+2+ =0> 2 -2 OK 0
+2+ =0> 5 -5 OK 0
+2+ =0> Hm1 -Hm1 OK 0
+2+ =0> -Hm1d2 Hm1d2 OK 0
+2+ =0> 1 -1 OK 0
+2+ =0> -3 3 OK 0
+2+ =0> T -T OK 0
+2+ =0> Td4 -Td4 OK 0
+2+ =0> -Td1 Td1 OK 0 no underflow
+2+ =0> 0i1 -0i1 OK 0
+2+ =0> Hd1 -Hd1 OK 0
+! Cancellation to 0 -- to minus 0.
+2+ < 2 -2 OK -0
+2+ < 5 -5 OK -0
+2+ < Hm1 -Hm1 OK -0
+2+ < -Hm1d2 Hm1d2 OK -0
+2+ < 1 -1 OK -0
+2+ < -3 3 OK -0
+2+ < T -T OK -0
+2+ < Td4 -Td4 OK -0
+2+ < -Td1 Td1 OK -0 no underflow
+2+ < 0i1 -0i1 OK -0
+2+ < Hd1 -Hd1 OK -0
+
+!! normalization
+
+! Cancel forcing normalization of LSB (no rounding errors).
+2+ ALL 1i1 -1 OK 1u1
+!! bff00000 00000000 3ff000000 00000001 3cb00000 00000000
+2+ ALL Hm1i1 -Hm1 OK Hm1u1
+2+ ALL Ti1 -T OK Tu1
+2+ ALL -2 2i1 OK 2u1
+2+ ALL -Hm2 Hm2i1 OK Hm2u1
+2+ ALL -1i1 1 OK -1u1
+!! 3ff00000 00000000 bff000000 00000001 bcb00000 00000000
+2+ ALL -Hm1i1 Hm1 OK -Hm1u1
+2+ ALL -Ti1 T OK -Tu1
+2+ ALL 2 -2i1 OK -2u1
+2+ ALL Hm2 -Hm2i1 OK -Hm2u1
+2+ ALL 0i2 -0i1 OK Tu1
+2+ ALL -1i1 1i2 OK 1u1
+2+ ALL -Hm1i1 Hm1i2 OK Hm1u1
+2+ ALL -Ti1 Ti2 OK Tu1
+2+ ALL -0i2 0i1 OK -Tu1
+2+ ALL 1i1 -1i2 OK -1u1
+2+ ALL Hm1i1 -Hm1i2 OK -Hm1u1
+2+ ALL Ti1 -Ti2 OK -Tu1
+2+ ALL -0i3 0i2 OK -Tu1
+2+ ALL 0i3 -0i2 OK Tu1
+2+ ALL 2i4 -2i3 OK 2u1
+2+ ALL Hm2i4 -Hm2i3 OK Hm2u1
+2+ ALL -2i4 2i3 OK -2u1
+2+ ALL -Hm2i4 Hm2i3 OK -Hm2u1
+2+ ALL 4d1 -4d2 OK 3u1
+2+ ALL Hm2d1 -Hm2d2 OK Hm3u1
+2+ ALL Td1 -Td2 OK Tu1
+2+ ALL -Hd2 Hd1 OK Hd1u1
+2+ ALL -4d1 4d2 OK -3u1
+2+ ALL -Hm2d1 Hm2d2 OK -Hm3u1
+2+ ALL -Td1 Td2 OK -Tu1
+2+ ALL Hd2 -Hd1 OK -Hd1u1
+2+ ALL Td3 -Td2 OK -Tu1
+2+ ALL -Td3 Td2 OK Tu1
+2+ ALL 2d4 -2d3 OK -1u1
+2+ ALL -2d4 2d3 OK 1u1
+2+ ALL Td1 -T OK -Tu1
+2+ ALL 2d1 -2 OK -1u1
+2+ ALL Tp2d1 -Tp2 OK -Tu2
+2+ ALL Hm1d1 -Hm1 OK -Hm2u1
+2+ ALL Tp1d1 -Tp1 OK -Tu1
+2+ ALL -Hm2 Hm2d1 OK -Hm3u1
+2+ ALL 2 -2d1 OK 1u1
+2+ ALL Hm2 -Hm2d1 OK Hm3u1
+2+ ALL Tp1 -Tp1d1 OK Tu1
+2+ ALL Tp2 -Tp2d1 OK Tu2
+2+ ALL -Td1 T OK Tu1
+2+ ALL -Hm1d1 Hm1 OK Hm2u1
+A+ ALL 4d1 -4i1 OK -3u3
+2+ ALL -Hm4i1 Hm4d1 OK -Hm5u3
+2+ ALL -Tp1i1 Tp1d1 OK -Tu3
+2+ ALL -Tp2i1 Tp2d1 OK -Tu6
+A+ ALL -4d1 4i1 OK 3u3
+2+ ALL Hm4i1 -Hm4d1 OK Hm5u3
+2+ ALL Tp1i1 -Tp1d1 OK Tu3
+2+ ALL Tp2i1 -Tp2d1 OK Tu6
+2+ ALL 4d1 -4i2 OK -3u5
+2+ ALL Hm2d1 -Hm2i2 OK -Hm3u5
+2+ ALL Tp1d1 -Tp1i2 OK -Tu5
+2+ ALL -4d1 4i2 OK 3u5
+2+ ALL -Hm2d1 Hm2i2 OK Hm3u5
+2+ ALL -Tp1d1 Tp1i2 OK Tu5
+2+ ALL Tp1d1 -Tp1i4 OK -Tu9
+2+ ALL -Tp1d1 Tp1i4 OK Tu9
+2+ ALL 2i1 -1i1 OK 1i1
+2+ ALL Tp1i1 -Ti1 OK Ti1
+2+ ALL -2i1 1i1 OK -1i1
+2+ ALL -Tp1i1 Ti1 OK -Ti1
+2+ ALL -Hm2i1 Hm1i1 OK Hm2i1
+2+ ALL Hm2i1 -Hm1i1 OK -Hm2i1
+2+ ALL 2i2 -1i1 OK 1i3
+2+ ALL Hm1i2 -Hm2i1 OK Hm2i3
+2+ ALL Tp1i2 -Ti1 OK Ti3
+2+ ALL -2i2 1i1 OK -1i3
+2+ ALL -Hm1i2 Hm2i1 OK -Hm2i3
+2+ ALL -Tp1i2 Ti1 OK -Ti3
+2+ ALL 2i2 -1i3 OK 1i1
+2+ ALL Hm2i2 -Hm3i3 OK Hm3i1
+2+ ALL Tp2i2 -Tp1i3 OK Tp1i1
+2+ ALL -2i2 1i3 OK -1i1
+2+ ALL -Hm2i2 Hm3i3 OK -Hm3i1
+2+ ALL -Tp2i2 Tp1i3 OK -Tp1i1
+!! low and high order bits
+!! 41f00000 00004000 c1f00000 00000000 3f900000 00000000
+H+ ALL 1i2 -1 OK 1mtp2
+A+ ALL -1i2 1 OK -1mtp2
+!! 41f00000 00004000 c1f00000 00000000 3f900000 00000000
+H+ ALL 1i4 -1 OK 1mtp3
+A+ ALL -1i4 1 OK -1mtp3
+!! 41f00000 00004000 c1f00000 00000000 3f900000 00000000
+H+ ALL 1i8 -1 OK 1mtp4
+A+ ALL -1i8 1 OK -1mtp4
+!! 41f00000 00004000 c1f00000 00000000 3f900000 00000000
+H+ ALL 17 -16 OK 1
+A+ ALL -17 +16 OK -1
+A+ ALL 16 -17 OK -1
+!! 41f00000 00004000 c1f00000 00000000 3f900000 00000000
+H+ ALL 9 -8 OK 1
+A+ ALL -9 8 OK -1
+!! 41f00000 00004000 c1f00000 00000000 3f900000 00000000
+H+ ALL 5 -4 OK 1
+A+ ALL -5 4 OK -1
+!! 41f00000 00004000 c1f00000 00000000 3f900000 00000000
+H+ ALL 3 -2 OK 1
+A+ ALL -3 2 OK -1
+
+! Cases to test shifting in addition
+
+3+ =0< 2 1i1 x 3
+3+ > 2 1i1 x 3i1
+3+ =0< 10 1i1 x 11
+3+ > 10 1i1 x 11i1
+3+ =0< 19 1i1 x 20
+3+ > 19 1i1 x 20i1
+3+ =0< 32 1i1 x 33
+3+ > 32 1i1 x 33i1
+3+ =0< 65 1i1 x 66
+3+ > 65 1i1 x 66i1
+3+ =0< 133 1i1 x 134
+3+ > 133 1i1 x 134i1
+3+ =0< 260 1i1 x 261
+3+ > 260 1i1 x 261i1
+3+ =0< 533 1i1 x 534
+3+ > 533 1i1 x 534i1
+3+ =0< 1029 1i1 x 1030
+3+ > 1029 1i1 x 1030i1
+3+ =0< 2048 1i1 x 2049
+3+ > 2048 1i1 x 2049i1
+3+ =0< 4097 1i1 x 4098
+3+ > 4097 1i1 x 4098i1
+3+ =0< 8193 1i1 x 8194
+3+ > 8193 1i1 x 8194i1
+3+ =0< 16384 1i1 x 16385
+3+ > 16384 1i1 x 16385i1
+3+ =0< 32780 1i1 x 32781
+3+ > 32780 1i1 x 32781i1
+3+ =0< 65555 1i1 x 65556
+3+ > 65555 1i1 x 65556i1
+3+ =0< 131072 1i1 x 131073
+3+ > 131072 1i1 x 131073i1
+3+ =0< 263000 1i1 x 263001
+3+ > 263000 1i1 x 263001i1
+3+ =0< 525000 1i1 x 525001
+3+ > 525000 1i1 x 525001i1
+3+ =0< 1050000 1i1 x 1050001
+3+ > 1050000 1i1 x 1050001i1
+3+ =0< 2092700 1i1 x 2092701
+3+ > 2092700 1i1 x 2092701i1
+3+ =0< 4194305 1i1 x 4194306
+3+ > 4194305 1i1 x 4194306i1
+!! This is 2^23+1, the widest integer for IEEE single precision:
+3+ =0< 8388609 1i1 x 8388610
+3+ > 8388609 1i1 x 8388610i1
+!! 3+ d=0< 16777300 1i1 x 16777301
+!! 3+ d> 16777300 1i1 x 16777301i1
+!! 3+ d=0< 33555000 1i1 x 33555001
+!! 3+ d> 33555000 1i1 x 33555001i1
+!! 3+ d=0< 67108880 1i1 x 67108881
+!! 3+ d> 67108880 1i1 x 67108881i1
+!! 3+ d=0< 134218000 1i1 x 134218001
+!! 3+ d> 134218000 1i1 x 134218001i1
+!! 3+ d=0< 268436000 1i1 x 268436001
+!! 3+ d> 268436000 1i1 x 268436001i1
+!! 3+ d=0< 0x41c0000000800000 1i1 x 0x41c0000001000000
+!! 3+ d> 0x41c0000000800000 1i1 x 0x41c0000001000001
+!! 3+ d=0< 0x41d0000000400000 1i1 x 0x41d0000000800000
+!! 3+ d> 0x41d0000000400000 1i1 x 0x41d0000000800001
+!! 3+ d=0< 0x41e0000000200000 1i1 x 0x41e0000000400000
+!! 3+ d> 0x41e0000000200000 1i1 x 0x41e0000000400001
+!! 3+ d=0< 0x41f0000000100000 1i1 x 0x41f0000000200000
+!! 3+ d> 0x41f0000000100000 1i1 x 0x41f0000000200001
+!! 3+ d=0< 0x4200000000080000 1i1 x 0x4200000000100000
+!! 3+ d> 0x4200000000080000 1i1 x 0x4200000000100001
+!! 3+ d=0< 0x4210000000040000 1i1 x 0x4210000000080000
+!! 3+ d> 0x4210000000040000 1i1 x 0x4210000000080001
+!! 3+ d=0< 0x4220000000020000 1i1 x 0x4220000000040000
+!! 3+ d> 0x4220000000020000 1i1 x 0x4220000000040001
+!! 3+ d=0< 0x4230000000010000 1i1 x 0x4230000000020000
+!! 3+ d> 0x4230000000010000 1i1 x 0x4230000000020001
+!! 3+ d=0< 0x4240000000008000 1i1 x 0x4240000000010000
+!! 3+ d> 0x4240000000008000 1i1 x 0x4240000000010001
+!! 3+ d=0< 0x4250000000004000 1i1 x 0x4250000000008000
+!! 3+ d> 0x4250000000004000 1i1 x 0x4250000000008001
+!! 3+ d=0< 0x4260000000002000 1i1 x 0x4260000000004000
+!! 3+ d> 0x4260000000002000 1i1 x 0x4260000000004001
+!! 3+ d=0< 0x4270000000001000 1i1 x 0x4270000000002000
+!! 3+ d> 0x4270000000001000 1i1 x 0x4270000000002001
+!! 3+ d=0< 0x4280000000000800 1i1 x 0x4280000000001000
+!! 3+ d> 0x4280000000000800 1i1 x 0x4280000000001001
+!! 3+ d=0< 0x4290000000000400 1i1 x 0x4290000000000800
+!! 3+ d> 0x4290000000000400 1i1 x 0x4290000000000801
+!! 3+ d=0< 0x42a0000000000200 1i1 x 0x42a0000000000400
+!! 3+ d> 0x42a0000000000200 1i1 x 0x42a0000000000401
+!! 3+ d=0< 0x42b0000000000100 1i1 x 0x42b0000000000200
+!! 3+ d> 0x42b0000000000100 1i1 x 0x42b0000000000201
+!! 3+ d=0< 0x42c0000000000080 1i1 x 0x42c0000000000100
+!! 3+ d> 0x42c0000000000080 1i1 x 0x42c0000000000101
+!! 3+ d=0< 0x42d0000000000040 1i1 x 0x42d0000000000080
+!! 3+ d> 0x42d0000000000040 1i1 x 0x42d0000000000081
+!! 3+ d=0< 0x42e0000000000020 1i1 x 0x42e0000000000040
+!! 3+ d> 0x42e0000000000020 1i1 x 0x42e0000000000041
+!! 3+ d=0< 0x42f0000000000010 1i1 x 0x42f0000000000020
+!! 3+ d> 0x42f0000000000010 1i1 x 0x42f0000000000021
+!! 3+ d=0< 0x4300000000000008 1i1 x 0x4300000000000010
+!! 3+ d> 0x4300000000000008 1i1 x 0x4300000000000011
+!! 3+ d=0< 0x4310000000000004 1i1 x 0x4310000000000008
+!! 3+ d> 0x4310000000000004 1i1 x 0x4310000000000009
+!! 3+ d=0< 0x4320000000000002 1i1 x 0x4320000000000004
+!! 3+ d> 0x4320000000000002 1i1 x 0x4320000000000005
+!! 3+ d=0< 0x4330000000000001 1i1 x 0x4330000000000002
+!! 3+ d> 0x4330000000000001 1i1 x 0x4330000000000003
+!! 3+ d0< 0x4340000000000001 1i1 x 0x4340000000000001
+!! 3+ d=> 0x4340000000000001 1i1 x 0x4340000000000002
+!! 3+ d=> 0x4340000000000001 1 x 0x4340000000000002
+!! 3+ d=0< 0x4350000000000001 1i1 x 0x4350000000000001
+!! 3+ d> 0x4350000000000001 1i1 x 0x4350000000000002
+A+ =0< 1pt 4i1 x 1pti2
+A+ > 1pt 4i1 x 1pti3
+A+ =0< 1pt 2i1 x 1pti1
+A+ > 1pt 2i1 x 1pti2
+A+ =0> -2 -1i1 x -3
+A+ < -2 -1i1 x -3i1
+A+ =0> -1pt -4i1 x -1pti2
+A+ < -1pt -4i1 x -1pti3
+A+ =0> -1pt -2i1 x -1pti1
+A+ < -1pt -2i1 x -1pti2
+
+!! Pre-arithmetic shifts + carry propagation
+
+!! 40dfffc0 00000000 3ff00000 00000000 40e00000 00000000
+H+ ALL 1p15d(14)1 1 OK 1p15
+!! 3ff00000 00000000 40dfffc0 00000000 40e00000 00000000
+A+ ALL -1p15d(14)1 -1 OK -1p15
+A+ ALL 1ptd1 1 OK 1pt
+A+ ALL -1ptd1 -1 OK -1pt
+A+ ALL 1 15 OK 16
+A+ ALL -1 -15 OK -16
+!! carry, no propagation
+!! 40000000 00000000 40dffec0 00000000 40dfff40 00000000
+H+ ALL 2 1ptd5 OK 1ptd3
+!! 40dffec0 00000000 40000000 00000000 40dfff40 00000000
+A+ ALL -2 -1ptd5 OK -1ptd3
+!! no shifting for denormals
+A+ ALL Td1 0i1 OK T
+A+ ALL -Td1 -0i1 OK -T
+A+ ALL 0i(3)7 0i(3)1 OK T
+A+ ALL -0i(3)7 -0i(3)1 OK -T
+!! no carry
+!! 40000000 00000000 40dfff40 00000000 40dfffc0 00000000
+H+ ALL 2 2p14d(14)1d(13)1 OK 2p14d(14)1
+!! 40dfff40 00000000 40000000 00000000 40dfffc0 00000000
+A+ ALL -2 -2p14d(14)1d(13)1 OK -2p14d(14)1
+A+ ALL 1 1ptd2 OK 1ptd1
+A+ ALL -1 -1ptd2 OK -1ptd1
+!! 40000000 00000000 40dfff40 00000000 40dfffc0 00000000
+H+ ALL 3 1ptd6 OK 1ptd3
+!! 40dfff40 00000000 40000000 00000000 40dfffc0 00000000
+A+ ALL -3 -1ptd6 OK -1ptd3
+!! 40000000 00000000 40dfff40 00000000 40dfffc0 00000000
+H+ ALL 1 14 OK 15
+!! 40dfff40 00000000 40000000 00000000 40dfffc0 00000000
+A+ ALL -1 -14 OK -15
+!! 40000000 00000000 40dfff40 00000000 40dfffc0 00000000
+H+ ALL 2 13 OK 15
+!! 40dfff40 00000000 40000000 00000000 40dfffc0 00000000
+A+ ALL -2 -13 OK -15
+!! no shifting for denormals
+A+ ALL Td2 0i1 OK Td1
+A+ ALL -Td2 -0i1 OK -Td1
+A+ ALL 0i(2)3 0i(3)1 OK 0i(3)7
+A+ ALL -0i(2)3 -0i(3)1 OK -0i(3)7
+
+!! Carry propagation from outward rounding round or sticky bit
+
+!! round bit
+A+ > 2d1 1mt x 2
+A+ < -2d1 -1mt x -2
+!! "first" sticky bit
+A+ > 4d1 1mt x 4
+A+ < -4d1 -1mt x -4
+!! sticky bit
+A+ > 8d1 1mt x 8
+A+ < -8d1 -1mt x -8
+2+ =0> -Hm1d1 -1 x -Hm1d1
+2+ < -Hm1d1 -1 x -Hm1
+!! bff 00000 00000000 ffdfffff ffffffff ffdfffff ffffffff
+!! bff 00000 00000000 ffdfffff ffffffff ffe00000 00000000
--- /dev/null
+!! This file contains precision and range independent test vectors for
+!! the operation divide (/). The first character in each
+!! test vector refers to the origin of the test vector
+!!
+!! 2: Jerome Coonen Version <2>
+!! 3: Jerome Coonen Version <3>
+!! @Phdthesis{
+!! author = {Coonen, J.T.},
+!! title = {Contributions to a proposed standard for binary
+!! floating-point arithmetic},
+!! school = {University of California, Berkeley},
+!! year = {1984}}
+!!
+!! H: precision independent encoding of UCB/<H>ough test vector
+!! @Unpublished{
+!! author = {David G. Hough and others},
+!! title = {{UCBTEST}, a suite of programs for testing certain
+!! difficult cases of {IEEE} 754 floating-point arithmetic},
+!! year = {1988},
+!! note = {Restricted public domain software from
+!! http://netlib.bell-labs.com/netlib/fp/index.html}}
+!!
+!! A: Verdonk-Cuyt-Verschaeren (University of <A>ntwerp)
+!! @Article{
+!! author = {Verdonk, B. and Cuyt, A. and Verschaeren, D.},
+!! title = {A precision- and range-independent tool for testing
+!! floating-point arithmetic {I}: basic operations,
+!! square root and remainder},
+!! journal = {ACM TOMS},
+!! volume = {27},
+!! number = {1},
+!! pages = {92-118},
+!! year = {2001}}
+!! note = {Under revision}}
+!!
+!! This file is part of the tool IeeeCC754 or IEEE 754 Compliance Checker.
+!! It is a precision and range independent tool to test whether
+!! an implementation of floating-point arithmetic (in hardware or
+!! software) is compliant with the principles of the IEEE 754-854
+!! floating-point standards. You can find out more about the testing
+!! tool IeeeCC754 and the syntax and semantics of the test vectors
+!! at
+!! http://win-www.uia.ac.be/u/cant/ieeecc754.html
+!!
+!! Last updated:
+!! $Date$
+!!
+!! Contact:
+!! Brigitte.Verdonk@ua.ac.be
+!! Department of Mathematics and Computer Science
+!! University of Antwerp (UIA)
+!! Universiteitsplein 1
+!! B2610 Antwerp, BELGIUM
+!!
+!! Medium size numbers
+2/ ALL 1p15 1p5 OK 1p10
+A/ ALL -1p15 -1p5 OK 1p10
+2/ ALL 1p15 -1p5 OK -1p10
+2/ ALL -1p15 1p5 OK -1p10
+2/ ALL 1p120 1p20 OK 1p100
+A/ ALL -1p120 -1p20 OK 1p100
+2/ ALL -1p120 1p20 OK -1p100
+2/ ALL 1p120 -1p20 OK -1p100
+2/ ALL 1p63 1p23 OK 1p40
+A/ ALL -1p63 -1p23 OK 1p40
+A/ ALL -1p63 1p23 OK -1p40
+A/ ALL 1p63 -1p23 OK -1p40
+2/ ALL 1p47 1p13 OK 1p34
+A/ ALL -1p47 -1p13 OK 1p34
+A/ ALL -1p47 1p13 OK -1p34
+A/ ALL 1p47 -1p13 OK -1p34
+!! divisions by 10
+A/ ALL 40 10 OK 4
+A/ ALL -40 -10 OK 4
+A/ ALL -40 10 OK -4
+A/ ALL 40 -10 OK -4
+2/ ALL 32760 10 OK 3276
+2/ ALL 10000 10 OK 1000
+2/ ALL 10000 100 OK 100
+2/ ALL 10000 1000 OK 10
+
+!! / 1
+2/ ALL 1 1 OK 1
+2/ ALL -1 -1 OK 1
+A/ ALL 1 -1 OK -1
+2/ ALL -1 1 OK -1
+2/ ALL 2 1 OK 2
+2/ ALL -2 -1 OK 2
+2/ ALL -2 1 OK -2
+2/ ALL 2 -1 OK -2
+2/ ALL Td1 1 OK Td1
+2/ ALL Td1 -1 OK -Td1
+A/ ALL 0i1 1 OK 0i1
+A/ ALL -0i1 -1 OK 0i1
+A/ ALL -0i1 1 OK -0i1
+A/ ALL 0i1 -1 OK -0i1
+!! / 2
+2/ ALL Hm1 2 OK Hm2
+2/ ALL Hm1 -2 OK -Hm2
+2/ ALL -Hm1d1 2 OK -Hm2d1
+2/ ALL Hm1d3 -2 OK -Hm2d3
+2/ ALL Hd1 -2 OK -Hm1d1
+2/ ALL 8 2 OK 4
+A/ ALL -8 -2 OK 4
+2/ ALL -8 2 OK -4
+A/ ALL 8 -2 OK -4
+2/ ALL Tp1 -2 OK -T
+2/ ALL Tp1i3 -2 OK -Ti3
+2/ ALL Tp1i1 -2 OK -Ti1
+2/ ALL Tp1d2 2 OK Td1
+A/ ALL 0i(1)1 2 OK 0i(2)1
+A/ ALL -0i(1)1 -2 OK 0i(2)1
+A/ ALL -0i(1)1 2 OK -0i(2)1
+A/ ALL 0i(1)1 -2 OK -0i(2)1
+A/ ALL 0i2 2 OK 0i1
+A/ ALL -0i2 -2 OK 0i1
+A/ ALL -0i2 2 OK -0i1
+A/ ALL 0i2 -2 OK -0i1
+2/ ALL Hd1 Hm1d1 OK 2
+2/ ALL -Hm1i1 Hm2i1 OK -2
+2/ ALL Hm1i3 -Hm2i3 OK -2
+2/ ALL Tp1 T OK 2
+2/ ALL -Tp1i1 Ti1 OK -2
+2/ ALL Tp1i1 Ti1 OK 2
+2/ ALL Tp1i3 -Ti3 OK -2
+2/ ALL -Tp1i5 Ti5 OK -2
+A/ ALL 0i(1)1 0i(2)1 OK 2
+A/ ALL -0i(1)1 -0i(2)1 OK 2
+A/ ALL -0i(1)1 0i(2)1 OK -2
+A/ ALL 0i(1)1 -0i(2)1 OK -2
+A/ ALL 0i2 0i1 OK 2
+A/ ALL -0i2 -0i1 OK 2
+A/ ALL 0i2 -0i1 OK -2
+A/ ALL -0i2 0i1 OK -2
+!! * 2
+A/ ALL 3 1m1 OK 6
+A/ ALL -3 -1m1 OK 6
+A/ ALL -3 1m1 OK -6
+A/ ALL 3 -1m1 OK -6
+2/ ALL Td1 1m1 OK Tp1d2
+A/ ALL -Td1 -1m1 OK Tp1d2
+A/ ALL -Td1 1m1 OK -Tp1d2
+A/ ALL Td1 -1m1 OK -Tp1d2
+2/ ALL 0i1 1m1 OK 0i2
+A/ ALL -0i1 -1m1 OK 0i2
+2/ ALL -0i1 1m1 OK -0i2
+A/ ALL 0i1 -1m1 OK -0i2
+A/ ALL 3 6 OK 1m1
+A/ ALL -3 -6 OK 1m1
+A/ ALL -3 6 OK -1m1
+A/ ALL 3 -6 OK -1m1
+A/ ALL Td1 Tp1d2 OK 1m1
+A/ ALL -Td1 -Tp1d2 OK 1m1
+A/ ALL -Td1 Tp1d2 OK -1m1
+A/ ALL Td1 -Tp1d2 OK -1m1
+2/ ALL 0i1 0i2 OK 1m1
+A/ ALL -0i1 0i2 OK -1m1
+A/ ALL -0i1 -0i2 OK 1m1
+A/ ALL 0i1 -0i2 OK -1m1
+!! * 2^k
+A/ ALL 3 1m9 OK 3p9
+A/ ALL -3 -1m9 OK 3p9
+A/ ALL -3 1m9 OK -3p9
+A/ ALL 3 -1m9 OK -3p9
+2/ ALL Td1 1m9 OK Tp9d2
+A/ ALL -Td1 -1m9 OK Tp9d2
+A/ ALL -Td1 1m9 OK -Tp9d2
+A/ ALL Td1 -1m9 OK -Tp9d2
+2/ ALL 0i1 1m3 OK 0i8
+A/ ALL -0i1 -1m3 OK 0i8
+A/ ALL -0i1 1m3 OK -0i8
+A/ ALL 0i1 -1m3 OK -0i8
+A/ ALL 3 3p9 OK 1m9
+A/ ALL -3 3p9 OK -1m9
+A/ ALL -3 -3p9 OK 1m9
+A/ ALL 3 -3p9 OK -1m9
+A/ ALL Td1 Tp9d2 OK 1m9
+A/ ALL -Td1 Tp9d2 OK -1m9
+A/ ALL -Td1 -Tp9d2 OK 1m9
+A/ ALL Td1 -Tp9d2 OK -1m9
+A/ ALL 0i1 0i8 OK 1m3
+A/ ALL -0i1 0i8 OK -1m3
+A/ ALL -0i1 -0i8 OK 1m3
+A/ ALL 0i1 -0i8 OK -1m3
+!! / 3
+2/ ALL 9 3 OK 3
+2/ ALL -9 -3 OK 3
+A/ ALL -9 3 OK -3
+A/ ALL 9 -3 OK -3
+A/ ALL 6 3 OK 2
+2/ ALL -6 -3 OK 2
+A/ ALL 6 -3 OK -2
+A/ ALL -6 3 OK -2
+!! /4
+2/ ALL Hd3 4 OK Hm2d3
+2/ ALL Hd3 -4 OK -Hm2d3
+2/ ALL -Hd3 4 OK -Hm2d3
+2/ ALL -Hd3 -4 OK Hm2d3
+A/ ALL 0i(1)1 4 OK 0i(3)1
+A/ ALL -0i(1)1 -4 OK 0i(3)1
+A/ ALL -0i(1)1 4 OK -0i(3)1
+A/ ALL 0i(1)1 -4 OK -0i(3)1
+A/ ALL 0i4 4 OK 0i1
+A/ ALL -0i4 -4 OK 0i1
+A/ ALL -0i4 4 OK -0i1
+A/ ALL 0i4 -4 OK -0i1
+2/ ALL Hd1 Hm2d1 OK 4
+2/ ALL -Hd1 Hm2d1 OK -4
+2/ ALL Hd1 -Hm2d1 OK -4
+2/ ALL -Hd1 -Hm2d1 OK 4
+A/ ALL 0i(1)1 0i(3)1 OK 4
+A/ ALL -0i(1)1 -0i(3)1 OK 4
+A/ ALL -0i(1)1 0i(3)1 OK -4
+A/ ALL 0i(1)1 -0i(3)1 OK -4
+A/ ALL 0i4 0i1 OK 4
+A/ ALL -0i4 -0i1 OK 4
+A/ ALL 0i4 -0i1 OK -4
+A/ ALL -0i4 0i1 OK -4
+
+!! equal operands
+2/ ALL 5 5 OK 1
+A/ ALL -5 -5 OK 1
+A/ ALL 5 -5 OK -1
+A/ ALL -5 5 OK -1
+A/ ALL 3 3 OK 1
+A/ ALL -3 -3 OK 1
+A/ ALL -3 3 OK -1
+2/ ALL 3 -3 OK -1
+A/ ALL 7 7 OK 1
+A/ ALL -7 -7 OK 1
+A/ ALL 7 -7 OK -1
+2/ ALL -7 7 OK -1
+A/ ALL 0i1 0i1 OK 1
+A/ ALL -0i1 -0i1 OK 1
+A/ ALL 0i1 -0i1 OK -1
+A/ ALL -0i1 0i1 OK -1
+2/ ALL 0i9 9 OK 0i1
+2/ ALL 0i9 -9 OK -0i1
+
+!! special representations
+!! zero versus zero
+2/ ALL 0 0 i Q
+2/ ALL -0 0 i -Q
+2/ ALL 0 -0 i -Q
+2/ ALL -0 -0 i Q
+!! zero versus denormal
+! 0 / denormalized -> 0.
+2/ ALL 0 0i1 OK 0
+2/ ALL -0 0i3 OK -0
+2/ ALL 0 -0i2 OK -0
+2/ ALL -0 -0i4 OK 0
+2/ ALL 0 Td1 OK 0
+2/ ALL -0 Td1 OK -0
+2/ ALL 0 -Td1 OK -0
+2/ ALL -0 -Td1 OK 0
+! Denormalized * 0 -> Inf, DivBy0
+2/ ALL 0i1 0 z H
+2/ ALL -0i3 0 z -H
+2/ ALL 0i2 -0 z -H
+2/ ALL -0i4 -0 z H
+2/ ALL Td1 0 z H
+2/ ALL -Td1 0 z -H
+2/ ALL Td1 -0 z -H
+2/ ALL -Td1 -0 z H
+!! zero versus normal
+! 0 / small_integer -> 0.
+2/ ALL 0 1 OK 0
+2/ ALL -0 2 OK -0
+2/ ALL 0 -3 OK -0
+2/ ALL -0 -4 OK 0
+2/ ALL 0 5 OK 0
+2/ ALL -0 6 OK -0
+2/ ALL 0 -7 OK -0
+2/ ALL -0 -8 OK 0
+! Small_int / 0 -> Inf with DivBy0.
+2/ ALL 1 0 z H
+2/ ALL -2 0 z -H
+2/ ALL 3 -0 z -H
+2/ ALL -4 -0 z H
+2/ ALL 5 0 z H
+2/ ALL -6 0 z -H
+2/ ALL 7 -0 z -H
+2/ ALL -8 -0 z H
+! 0 / huge -> 0.
+2/ ALL 0 Hm1 OK 0
+2/ ALL -0 Hm2 OK -0
+2/ ALL 0 -Hm1 OK -0
+2/ ALL -0 -Hm2 OK 0
+2/ ALL 0 Hm1d1 OK 0
+2/ ALL -0 Hm2d1 OK -0
+2/ ALL 0 -Hm2d1 OK -0
+2/ ALL -0 -Hm1d1 OK 0
+! Huge / 0 -> Inf with DivBy0.
+2/ ALL Hm1 0 z H
+2/ ALL -Hm2 0 z -H
+2/ ALL Hm1 -0 z -H
+2/ ALL -Hm2 -0 z H
+2/ ALL Hm1d1 0 z H
+2/ ALL -Hm2d1 0 z -H
+2/ ALL Hm2d1 -0 z -H
+2/ ALL -Hm1d1 -0 z H
+! 0 / tiny -> 0.
+2/ ALL 0 T OK 0
+2/ ALL -0 Tp1 OK -0
+2/ ALL 0 -Tp1 OK -0
+2/ ALL -0 -T OK 0
+2/ ALL 0 Tp1d1 OK 0
+2/ ALL -0 Ti1 OK -0
+2/ ALL 0 -Ti1 OK -0
+2/ ALL -0 -Tp1d1 OK 0
+! Tiny / 0 -> Inf with DivBy0.
+2/ ALL T 0 z H
+2/ ALL -Tp1 0 z -H
+2/ ALL Tp1 -0 z -H
+2/ ALL -T -0 z H
+2/ ALL Tp1d1 0 z H
+2/ ALL -Ti1 0 z -H
+2/ ALL Ti1 -0 z -H
+2/ ALL -Tp1d1 -0 z H
+!! zero versus infinity
+! Inf / 0 --> Inf with no problem.
+2/ ALL H 0 OK H
+2/ ALL -H 0 OK -H
+2/ ALL H -0 OK -H
+2/ ALL -H -0 OK H
+! 0 / Inf --> 0 with no problem.
+2/ ALL 0 H OK 0
+2/ ALL -0 H OK -0
+2/ ALL 0 -H OK -0
+2/ ALL -0 -H OK 0
+!! zero versus NaN
+2/ ALL Q 0 OK Q
+2/ ALL Q -0 OK Q
+2/ ALL 0 Q OK Q
+2/ ALL -0 Q OK Q
+!2/ ALL S 0 i Q
+!2/ ALL S -0 i Q
+!2/ ALL 0 S i Q
+!2/ ALL -0 S i Q
+!! infinity versus infinity
+2/ ALL H H i Q
+2/ ALL -H H i -Q
+2/ ALL H -H i -Q
+2/ ALL -H -H i Q
+!! infinity versus denormal
+! Inf / denormalized -> Inf.
+2/ ALL H 0i1 OK H
+2/ ALL -H 0i3 OK -H
+2/ ALL H -0i2 OK -H
+2/ ALL -H -0i4 OK H
+2/ ALL H Td1 OK H
+2/ ALL -H Td1 OK -H
+2/ ALL H -Td1 OK -H
+2/ ALL -H -Td1 OK H
+! Denorm / Inf -> 0.
+2/ ALL 0i1 H OK 0
+2/ ALL -0i3 H OK -0
+2/ ALL 0i2 -H OK -0
+2/ ALL -0i4 -H OK 0
+2/ ALL Td1 H OK 0
+2/ ALL -Td1 H OK -0
+2/ ALL Td1 -H OK -0
+2/ ALL -Td1 -H OK 0
+!! infinity versus normal
+! Inf / small_integer -> Inf.
+2/ ALL H 1 OK H
+2/ ALL -H 2 OK -H
+2/ ALL H -3 OK -H
+2/ ALL -H -4 OK H
+2/ ALL H 5 OK H
+2/ ALL -H 6 OK -H
+2/ ALL H -7 OK -H
+2/ ALL -H -8 OK H
+! Small_int / Inf -> 0.
+2/ ALL 1 H OK 0
+2/ ALL -2 H OK -0
+2/ ALL 3 -H OK -0
+2/ ALL -4 -H OK 0
+2/ ALL 5 H OK 0
+2/ ALL -6 H OK -0
+2/ ALL 7 -H OK -0
+2/ ALL -8 -H OK 0
+! Huge / Inf -> 0.
+2/ ALL Hm1 H OK 0
+2/ ALL -Hm2 H OK -0
+2/ ALL Hm1 -H OK -0
+2/ ALL -Hm2 -H OK 0
+2/ ALL Hm1d1 H OK 0
+2/ ALL -Hm2d1 H OK -0
+2/ ALL Hd1 -H OK -0
+2/ ALL -Hd1 -H OK 0
+! Inf / huge -> Inf.
+2/ ALL H Hm1 OK H
+2/ ALL -H Hm2 OK -H
+2/ ALL H -Hm1 OK -H
+2/ ALL -H -Hm2 OK H
+2/ ALL H Hm1d1 OK H
+2/ ALL H -Hm2d1 OK -H
+2/ ALL H -Hd1 OK -H
+2/ ALL -H -Hd1 OK H
+! Inf / tiny -> Inf.
+2/ ALL H T OK H
+2/ ALL -H Tp1 OK -H
+2/ ALL H -Tp1 OK -H
+2/ ALL -H -T OK H
+2/ ALL H Tp1d1 OK H
+2/ ALL -H Ti1 OK -H
+2/ ALL H -Ti1 OK -H
+2/ ALL -H -Tp1d1 OK H
+! Tiny / Inf -> 0.
+2/ ALL T H OK 0
+2/ ALL -Tp1 H OK -0
+2/ ALL Tp1 -H OK -0
+2/ ALL -T -H OK 0
+2/ ALL Tp1d1 H OK 0
+2/ ALL -Ti1 H OK -0
+2/ ALL Ti1 -H OK -0
+2/ ALL -Tp1d1 -H OK 0
+!! infinity versus NaN
+2/ ALL Q H OK Q
+2/ ALL Q -H OK Q
+2/ ALL H Q OK Q
+2/ ALL -H Q OK Q
+!2/ ALL S H i Q
+!2/ ALL S -H i Q
+!2/ ALL H S i Q
+!2/ ALL -H S i Q
+!! NaN versus NaN
+2/ ALL Q Q OK Q
+!2/ ALL Q S i Q
+!2/ ALL S Q i Q
+!2/ ALL S S i Q
+!! NaN versus denormal
+2/ ALL Td1 Q OK Q
+2/ ALL -Td1 Q OK Q
+2/ ALL Q Td1 OK Q
+2/ ALL Q -Td1 OK Q
+2/ ALL Q 0i1 OK Q
+2/ ALL Q -0i1 OK Q
+2/ ALL 0i1 Q OK Q
+2/ ALL -0i1 Q OK Q
+!2/ ALL Td1 S i Q
+!2/ ALL -Td1 S i Q
+!2/ ALL S Td1 i Q
+!2/ ALL S -Td1 i Q
+!2/ ALL S 0i1 i Q
+!2/ ALL S -0i1 i Q
+!2/ ALL 0i1 S i Q
+!2/ ALL -0i1 S i Q
+!! NaN versus normal
+2/ ALL Q 1 OK Q
+2/ ALL Q -1 OK Q
+2/ ALL 1 Q OK Q
+2/ ALL -1 Q OK Q
+2/ ALL Q Hd1 OK Q
+2/ ALL Q -Hd1 OK Q
+2/ ALL Hd1 Q OK Q
+2/ ALL -Hd1 Q OK Q
+!2/ ALL S 1 i Q
+!2/ ALL S -1 i Q
+!2/ ALL 1 S i Q
+!2/ ALL -1 S i Q
+!2/ ALL S Hd1 i Q
+!2/ ALL S -Hd1 i Q
+!2/ ALL Hd1 S i Q
+!2/ ALL -Hd1 S i Q
+
+!! exceptions
+!! invalid and divide by zero, see special representations
+!! inexact, overflow
+!! exp. Z >= U
+2/ => Hm1 1m1 xo H
+2/ 0< Hm1 1m1 xo Hd1
+2/ => -Hm1 -1m1 xo H
+2/ 0< -Hm1 -1m1 xo Hd1
+2/ =< Hm1 -1m1 xo -H
+2/ =< -Hm1 1m1 xo -H
+2/ 0> Hm1 -1m1 xo -Hd1
+2/ 0> -Hm1 1m1 xo -Hd1
+2/ => Hm9 Tp9 xo H
+2/ 0< Hm9 Tp9 xo Hd1
+2/ => Hd1 0i1 xo H
+2/ 0< Hd1 0i1 xo Hd1
+2/ => Hm1 Td1 xo H
+2/ 0< Hm1 Td1 xo Hd1
+2/ => Hd1 1d1 xo H
+2/ 0< Hd1 1d1 xo Hd1
+!! Result = Max. normal, round or sticky bit <> 0
+!! This combination is not possible
+!! inexact, underflow
+!! X - Y <= -B-t
+!! Z = 0.0...0, round bit = 0
+A/ =0< T 2pt xu 0
+A/ > T 2pt xu 0i1
+A/ =0< -T -2pt xu 0
+A/ > -T -2pt xu 0i1
+A/ =0> T -2pt xu -0
+A/ < T -2pt xu -0i1
+A/ =0> -T 2pt xu -0
+A/ < -T 2pt xu -0i1
+!! denormal
+A/ =0< 0i1 4 xu 0
+A/ > 0i1 4 xu 0i1
+A/ =0< -0i1 -4 xu 0
+A/ > -0i1 -4 xu 0i1
+A/ =0> 0i1 -4 xu -0
+A/ < 0i1 -4 xu -0i1
+A/ =0> -0i1 4 xu -0
+A/ < -0i1 4 xu -0i1
+! Tiny / huge -> underflow.
+2/ =<0 0i1 Hd1 xu 0
+2/ > 0i1 Hd1 xu 0i1
+2/ =<0 -0i1 -Hd1 xu 0
+2/ > -0i1 -Hd1 xu 0i1
+2/ =0> 0i1 -Hd1 xu -0
+2/ < 0i1 -Hd1 xu -0i1
+2/ =0> -0i1 Hd1 xu -0
+2/ < -0i1 Hd1 xu -0i1
+!! X - Y = -B-t+1, round bit = 1, sticky bit = 1
+A/ 0< Tp1d1 1pt xu 0
+A/ => Tp1d1 1pt xu 0i1
+A/ 0< -Tp1d1 -1pt xu 0
+A/ => -Tp1d1 -1pt xu 0i1
+A/ 0> -Tp1d1 1pt xu -0
+A/ =< -Tp1d1 1pt xu -0i1
+A/ 0> Tp1d1 -1pt xu -0
+A/ =< Tp1d1 -1pt xu -0i1
+!! denormal
+A/ 0< Td1 1ptm1 xu 0
+A/ => Td1 1ptm1 xu 0i1
+A/ 0< -Td1 -1ptm1 xu 0
+A/ => -Td1 -1ptm1 xu 0i1
+A/ 0> -Td1 1ptm1 xu -0
+A/ =< -Td1 1ptm1 xu -0i1
+A/ 0> Td1 -1ptm1 xu -0
+A/ =< Td1 -1ptm1 xu -0i1
+!! X - Y = -B-t+1, round bit = 1, sticky bits = 0
+A/ 0< 3mB 1pt xu 0
+A/ => 3mB 1pt xu 0i1
+A/ 0< -3mB -1pt xu 0
+A/ => -3mB -1pt xu 0i1
+A/ 0> -3mB 1pt xu -0
+A/ =< -3mB 1pt xu -0i1
+A/ 0> 3mB -1pt xu -0
+A/ =< 3mB -1pt xu -0i1
+!! denormal
+A/ 0< 0i3 4 xu 0
+A/ => 0i3 4 xu 0i1
+A/ 0< -0i3 -4 xu 0
+A/ => -0i3 -4 xu 0i1
+A/ 0> -0i3 4 xu -0
+A/ =< -0i3 4 xu -0i1
+A/ 0> 0i3 -4 xu -0
+A/ =< 0i3 -4 xu -0i1
+!! X - Y = -B-t+1, round bit = 1, sticky bits = 1
+A/ 0< 5mBm1 1pt xu 0
+A/ => 5mBm1 1pt xu 0i1
+A/ 0< -5mBm1 -1pt xu 0
+A/ => -5mBm1 -1pt xu 0i1
+A/ 0> -5mBm1 1pt xu -0
+A/ =< -5mBm1 1pt xu -0i1
+A/ 0> 5mBm1 -1pt xu -0
+A/ =< 5mBm1 -1pt xu -0i1
+!! denormal
+A/ 0< 0i5 8 xu 0
+A/ => 0i5 8 xu 0i1
+A/ 0< -0i5 -8 xu 0
+A/ => -0i5 -8 xu 0i1
+A/ 0> -0i5 8 xu -0
+A/ =< -0i5 8 xu -0i1
+A/ 0> 0i5 -8 xu -0
+A/ =< 0i5 -8 xu -0i1
+!! X - Y = -B-t+1, round bit = 1, sticky bit = 0, round to even
+A/ =0< T 1pt xu 0
+A/ > T 1pt xu 0i1
+A/ =0< -T -1pt xu 0
+A/ > -T -1pt xu 0i1
+A/ =0> -T 1pt xu -0
+A/ < -T 1pt xu -0i1
+A/ =0> T -1pt xu -0
+A/ < T -1pt xu -0i1
+!! denormal
+2/ =0< 0i1 2 xu 0
+2/ > 0i1 2 xu 0i1
+2/ =0< -0i1 -2 xu 0
+2/ > -0i1 -2 xu 0i1
+2/ =0> -0i1 2 xu -0
+2/ < -0i1 2 xu -0i1
+2/ =0> 0i1 -2 xu -0
+2/ < 0i1 -2 xu -0i1
+!! X - Y = -B-t+2, round bit = 1, sticky bit = 0, round to even
+A/ 0< Tp1i(1)1 1pt xu 0i1
+A/ => Tp1i(1)1 1pt xu 0i2
+A/ 0< -Tp1i(1)1 -1pt xu 0i1
+A/ => -Tp1i(1)1 -1pt xu 0i2
+A/ 0> -Tp1i(1)1 1pt xu -0i1
+A/ =< -Tp1i(1)1 1pt xu -0i2
+A/ 0> Tp1i(1)1 -1pt xu -0i1
+A/ =< Tp1i(1)1 -1pt xu -0i2
+!! denormal
+A/ 0< 0i3 2 xu 0i1
+A/ => 0i3 2 xu 0i2
+A/ 0< -0i3 -2 xu 0i1
+A/ => -0i3 -2 xu 0i2
+A/ 0> -0i3 2 xu -0i1
+A/ =< -0i3 2 xu -0i2
+A/ 0> 0i3 -2 xu -0i1
+A/ =< 0i3 -2 xu -0i2
+!! exp. Z = -B + denormalization loss => inexactness
+A/ =0< Tp1d3 2 xu Td2
+A/ > Tp1d3 2 xu Td1
+A/ =0< -Tp1d3 -2 xu Td2
+A/ > -Tp1d3 -2 xu Td1
+A/ =0> -Tp1d3 2 xu -Td2
+A/ < -Tp1d3 2 xu -Td1
+A/ =0> Tp1d3 -2 xu -Td2
+A/ < Tp1d3 -2 xu -Td1
+A/ 0<= Ti(3)7i3 1p2i(1)1 xu 0i(4)5
+A/ > Ti(3)7i3 1p2i(1)1 xu 0i(4)5i1
+A/ 0< Ti(3)7i3 1pti(1)1 xu 0
+A/ >= Ti(3)7i3 1pti(1)1 xu 0i1
+!! denormal
+A/ 0< Td1 2 xu 0i(1)1d1
+A/ => Td1 2 xu 0i(1)1
+A/ 0< -Td1 -2 xu 0i(1)1d1
+A/ => -Td1 -2 xu 0i(1)1
+A/ 0> -Td1 2 xu -0i(1)1d1
+A/ =< -Td1 2 xu -0i(1)1
+A/ 0> Td1 -2 xu -0i(1)1d1
+A/ =< Td1 -2 xu -0i(1)1
+!! exp. Z = -B + inexactness, no denormalization loss
+2/ =0< T 1i1 xv Td1
+2/ > T 1i1 xu T
+A/ =0< -T -1i1 xv Td1
+A/ > -T -1i1 xu T
+2/ =0> -T 1i1 xv -Td1
+2/ < -T 1i1 xu -T
+A/ =0> T -1i1 xv -Td1
+A/ < T -1i1 xu -T
+2/ <=0 Ti1 1i2 xv Td1
+2/ > Ti1 1i2 xu T
+2/ <=0 Ti2 1i6 xv Td4
+!! denormal
+2/ =0< Td1 1i1 xv Td2
+A/ > Td1 1i1 xu Td1
+A/ =0< -Td1 -1i1 xv Td2
+A/ > -Td1 -1i1 xu Td1
+A/ =0> -Td1 1i1 xv -Td2
+A/ < -Td1 1i1 xu -Td1
+A/ =0> Td1 -1i1 xv -Td2
+A/ < Td1 -1i1 xu -Td1
+2/ >= Td2 1d2 xv Td1
+2/ >= Td9 1d2 xv Td8
+2/ <= -Td8 1d2 xv -Td7
+2/ <=0 Td1 1i2 xv Td3
+2/ > Td1 1i2 xu Td2
+!! exp. Z = -B + tininess after rounding
+A/ > Ti(1)1d1 3m1 xu T
+A/ = Ti(1)1d1 3m1 xu Td1
+A/ 0< Ti(1)1d1 3m1 xv Td1
+A/ < -Ti(1)1d1 3m1 xu -T
+A/ = -Ti(1)1d1 3m1 xu -Td1
+A/ 0> -Ti(1)1d1 3m1 xv -Td1
+A/ => 1d1 Hm2 xu T
+A/ <0 1d1 Hm2 xu Td1
+A/ =< -1d1 Hm2 xu -T
+A/ >0 -1d1 Hm2 xu -Td1
+!! tininess before and after rounding
+!! as though the exponent range were unbounded
+2/ 0< Tp1d1 2 xu Td1
+2/ => Tp1d1 2 xu T
+A/ 0< -Tp1d1 -2 xu Td1
+A/ => -Tp1d1 -2 xu T
+A/ 0> -Tp1d1 2 xu -Td1
+A/ =< -Tp1d1 2 xu -T
+2/ 0> Tp1d1 -2 xu -Td1
+A/ =< Tp1d1 -2 xu -T
+!! inexact, see rounding properties below
+
+!! exact rounding
+!! round bit = 0, sticky bit = 1 => inexact, round down
+! Tricky divides based on power series expansions
+! 1 / (1 + Nulp+) --> 1 - (2Nulp-) + tiny.
+2/ =0< 1 1i1 x 1d2
+2/ > 1 1i1 x 1d1
+2/ =0< -1 -1i1 x 1d2
+2/ > -1 -1i1 x 1d1
+2/ =0> -1 1i1 x -1d2
+2/ < -1 1i1 x -1d1
+2/ =0> 1 -1i1 x -1d2
+2/ < 1 -1i1 x -1d1
+2/ =0< 1 1i2 x 1d4
+2/ > 1 1i2 x 1d3
+2/ = 1 1i3 x 1d6
+2/ 0 1 1i3 x 1d6
+2/ < 1 1i3 x 1d6
+2/ > 1 1i3 x 1d5
+2/ = 1 1i4 x 1d8
+2/ 0 1 1i4 x 1d8
+2/ < 1 1i4 x 1d8
+2/ > 1 1i4 x 1d7
+! 1 / (1 - Nu-) --> 1 + (Q/2 u+) + tiny.
+2/ = 1 1d2 x 1i1
+2/ 0 1 1d2 x 1i1
+2/ < 1 1d2 x 1i1
+2/ > 1 1d2 x 1i2
+2/ = 1 1d4 x 1i2
+2/ 0 1 1d4 x 1i2
+2/ < 1 1d4 x 1i2
+2/ > 1 1d4 x 1i3
+2/ = 1 1d8 x 1i4
+2/ 0 1 1d8 x 1i4
+2/ < 1 1d8 x 1i4
+2/ > 1 1d8 x 1i5
+! (1 + Mulp+) / (1 + Qulp+) -->
+! Case M < Q: (1 + 2Mulp-) * (1 - 2Qulp- + (2Qulp-)^2 - tiny) -->
+! 1 - 2(Q-M)ulp- + 4(QQ-MQ)(ulp-)^2 + tiny -->
+! 1 - 2(Q-M)ulp- + tiny.
+! M + Q = 3.
+2/ = 1i1 1i2 x 1d2
+2/ 0 1i1 1i2 x 1d2
+2/ < 1i1 1i2 x 1d2
+2/ > 1i1 1i2 x 1d1
+! M + Q = 4.
+2/ = 1i1 1i3 x 1d4
+2/ 0 1i1 1i3 x 1d4
+2/ < 1i1 1i3 x 1d4
+2/ > 1i1 1i3 x 1d3
+! M + Q = 5.
+2/ = 1i2 1i3 x 1d2
+2/ 0 1i2 1i3 x 1d2
+2/ < 1i2 1i3 x 1d2
+2/ > 1i2 1i3 x 1d1
+! M + Q = 11.
+2/ = 1i4 1i7 x 1d6
+2/ 0 1i4 1i7 x 1d6
+2/ < 1i4 1i7 x 1d6
+2/ > 1i4 1i7 x 1d5
+! M + Q = 14.
+2/ = 1i6 1i8 x 1d4
+2/ 0 1i6 1i8 x 1d4
+2/ < 1i6 1i8 x 1d4
+2/ > 1i6 1i8 x 1d3
+! (1 - Mulp-) / (1 - Qulp-) -->
+! Case M < Q: (1 - (M/2)ulp+) * (1 + (Q/2)ulp+ + ((Q/2)ulp+)^2 + tiny) -->
+! 1 + ((Q-M)/2)ulp+ + (QQ-MQ)/4(ulp+)^2 + tiny -->
+! 1 + (Q-M)/2ulp+ + tiny.
+! M + Q = 4.
+2/ = 1d1 1d3 x 1i1
+2/ 0 1d1 1d3 x 1i1
+2/ < 1d1 1d3 x 1i1
+2/ > 1d1 1d3 x 1i2
+! M + Q = 6.
+2/ = 1d2 1d4 x 1i1
+2/ 0 1d2 1d4 x 1i1
+2/ < 1d2 1d4 x 1i1
+2/ > 1d2 1d4 x 1i2
+! M + Q = 8.
+2/ = 1d1 1d7 x 1i3
+2/ 0 1d1 1d7 x 1i3
+2/ < 1d1 1d7 x 1i3
+2/ > 1d1 1d7 x 1i4
+! M + Q = 10.
+2/ = 1d3 1d7 x 1i2
+2/ 0 1d3 1d7 x 1i2
+2/ < 1d3 1d7 x 1i2
+2/ > 1d3 1d7 x 1i3
+! M + Q = 12.
+2/ = 1d5 1d7 x 1i1
+2/ 0 1d5 1d7 x 1i1
+2/ < 1d5 1d7 x 1i1
+2/ > 1d5 1d7 x 1i2
+! (1 + Mulp+) / (1 - Qulp-) -->
+! (1 + Mulp+) * (1 + (Q/2)ulp+ + ((Q/2)ulp+)^2 + tiny) -->
+! 1 + (M + Q/2)ulp+ + tiny.
+! M + Q = 3.
+2/ = 1i1 1d2 x 1i2
+2/ 0 1i1 1d2 x 1i2
+2/ < 1i1 1d2 x 1i2
+2/ > 1i1 1d2 x 1i3
+! M + Q = 4.
+2/ = 1i2 1d2 x 1i3
+2/ 0 1i2 1d2 x 1i3
+2/ < 1i2 1d2 x 1i3
+2/ > 1i2 1d2 x 1i4
+! M + Q = 5.
+2/ = 1i3 1d2 x 1i4
+2/ 0 1i3 1d2 x 1i4
+2/ < 1i3 1d2 x 1i4
+2/ > 1i3 1d2 x 1i5
+! M + Q = 6.
+2/ = 1i2 1d4 x 1i4
+2/ 0 1i2 1d4 x 1i4
+2/ < 1i2 1d4 x 1i4
+2/ > 1i2 1d4 x 1i5
+2/ = 1i4 1d2 x 1i5
+2/ 0 1i4 1d2 x 1i5
+2/ < 1i4 1d2 x 1i5
+2/ > 1i4 1d2 x 1i6
+! (1 - Mulp-) / (1 + Qulp+) -->
+! (1 - Mulp-) * (1 - 2Qulp- + (2Qulp-)^2 - tiny) -->
+! 1 - (M + 2Q)ulp- + tiny.
+! M + Q = 2.
+2/ = 1d1 1i1 x 1d3
+2/ 0 1d1 1i1 x 1d3
+2/ < 1d1 1i1 x 1d3
+2/ > 1d1 1i1 x 1d2
+! M + Q = 3.
+2/ = 1d2 1i1 x 1d4
+2/ 0 1d2 1i1 x 1d4
+2/ < 1d2 1i1 x 1d4
+2/ > 1d2 1i1 x 1d3
+2/ = 1d1 1i2 x 1d5
+2/ 0 1d1 1i2 x 1d5
+2/ < 1d1 1i2 x 1d5
+2/ > 1d1 1i2 x 1d4
+! M + Q = 4.
+2/ = 1d3 1i1 x 1d5
+2/ 0 1d3 1i1 x 1d5
+2/ < 1d3 1i1 x 1d5
+2/ > 1d3 1i1 x 1d4
+2/ = 1d1 1i3 x 1d7
+2/ 0 1d1 1i3 x 1d7
+2/ < 1d1 1i3 x 1d7
+2/ > 1d1 1i3 x 1d6
+2/ = 1d2 1i2 x 1d6
+2/ 0 1d2 1i2 x 1d6
+2/ < 1d2 1i2 x 1d6
+2/ > 1d2 1i2 x 1d5
+! M + Q = 5.
+2/ = 1d4 1i1 x 1d6
+2/ 0 1d4 1i1 x 1d6
+2/ < 1d4 1i1 x 1d6
+2/ > 1d4 1i1 x 1d5
+2/ = 1d1 1i4 x 1d9
+2/ 0 1d1 1i4 x 1d9
+2/ < 1d1 1i4 x 1d9
+2/ > 1d1 1i4 x 1d8
+2/ = 1d3 1i2 x 1d7
+2/ 0 1d3 1i2 x 1d7
+2/ < 1d3 1i2 x 1d7
+2/ > 1d3 1i2 x 1d6
+2/ = 1d2 1i3 x 1d8
+2/ 0 1d2 1i3 x 1d8
+2/ < 1d2 1i3 x 1d8
+2/ > 1d2 1i3 x 1d7
+! A few tricky cases.
+A/ =0< -1d4 -1i1 x 1d6
+A/ > -1d4 -1i1 x 1d5
+A/ =0> -1d4 1i1 x -1d6
+A/ < -1d4 1i1 x -1d5
+A/ =0> 1d4 -1i1 x -1d6
+A/ < 1d4 -1i1 x -1d5
+!! 3ff7ffff ffffffff 3feffff fffffffe 3ff80000 00000000
+H/ 0< 3m1d1 1d2 x 3m1
+H/ => 3m1d1 1d2 x 3m1i1
+A/ 0< -3m1d1 -1d2 x 3m1
+A/ => -3m1d1 -1d2 x 3m1i1
+A/ 0> -3m1d1 1d2 x -3m1
+A/ =< -3m1d1 1d2 x -3m1i1
+A/ 0> 3m1d1 -1d2 x -3m1
+A/ =< 3m1d1 -1d2 x -3m1i1
+!! denormal
+A/ =0< 0i(1)1 Ti1 x 1m1d2
+A/ > 0i(1)1 Ti1 x 1m1d1
+A/ =0< -0i(1)1 -Ti1 x 1m1d2
+A/ > -0i(1)1 -Ti1 x 1m1d1
+A/ =0> -0i(1)1 Ti1 x -1m1d2
+A/ < -0i(1)1 Ti1 x -1m1d1
+A/ =0> 0i(1)1 -Ti1 x -1m1d2
+A/ < 0i(1)1 -Ti1 x -1m1d1
+!! round bit = 0, sticky bit = 10 => inexact, round down
+!! This combination is not possible
+!! round bit = 0, sticky bit = 1 => inexact, round down
+A/ =0< 3i2 1i1 x 3
+A/ > 3i2 1i1 x 3i1
+A/ =0< -3i2 -1i1 x 3
+A/ > -3i2 -1i1 x 3i1
+A/ =0> 3i2 -1i1 x -3
+A/ < 3i2 -1i1 x -3i1
+A/ =0> -3i2 1i1 x -3
+A/ < -3i2 1i1 x -3i1
+!! denormal
+A/ =0< 0i(2)3i1 Ti1 x 3m2
+A/ > 0i(2)3i1 Ti1 x 3m2i1
+A/ =0< -0i(2)3i1 -Ti1 x 3m2
+A/ > -0i(2)3i1 -Ti1 x 3m2i1
+A/ =0> 0i(2)3i1 -Ti1 x -3m2
+A/ < 0i(2)3i1 -Ti1 x -3m2i1
+A/ =0> -0i(2)3i1 Ti1 x -3m2
+A/ < -0i(2)3i1 Ti1 x -3m2i1
+!! round bit = 1, sticky bit = 0 => inexact, round up
+!! This combination is not possible
+!! round bit = 1, sticky bit = 1 => inexact, round up
+! 1 / (1 - Qu-) --> 1 + (Q/2 u+) + tiny.
+2/ = 1 1d3 x 1i2
+2/ 0 1 1d3 x 1i1
+2/ < 1 1d3 x 1i1
+2/ > 1 1d3 x 1i2
+2/ = 1 1d5 x 1i3
+2/ 0 1 1d5 x 1i2
+2/ < 1 1d5 x 1i2
+2/ > 1 1d5 x 1i3
+2/ = 1 1d9 x 1i5
+2/ 0 1 1d9 x 1i4
+2/ < 1 1d9 x 1i4
+2/ > 1 1d9 x 1i5
+! 1 / (1 - Qu-) --> 1 + (Q/2 u+) + tiny.
+2/ => 1 1d1 x 1i1
+2/ 0< 1 1d1 x 1
+2/ => -1 -1d1 x 1i1
+2/ 0< -1 -1d1 x 1
+2/ =< -1 1d1 x -1i1
+2/ 0> -1 1d1 x -1
+2/ =< 1 -1d1 x -1i1
+2/ 0> 1 -1d1 x -1
+! (1 - Mulp-) / (1 - Qulp-) -->
+! Case M < Q: (1 - (M/2)ulp+) * (1 + (Q/2)ulp+ + ((Q/2)ulp+)^2 + tiny) -->
+! 1 + ((Q-M)/2)ulp+ + (QQ-MQ)/4(ulp+)^2 + tiny -->
+! 1 + (Q-M)/2ulp+ + tiny.
+! M + Q = 3.
+2/ = 1d1 1d2 x 1i1
+2/ 0 1d1 1d2 x 1
+2/ < 1d1 1d2 x 1
+2/ > 1d1 1d2 x 1i1
+! M + Q = 5.
+2/ = 1d2 1d3 x 1i1
+2/ 0 1d2 1d3 x 1
+2/ < 1d2 1d3 x 1
+2/ > 1d2 1d3 x 1i1
+2/ = 1d1 1d4 x 1i2
+2/ 0 1d1 1d4 x 1i1
+2/ < 1d1 1d4 x 1i1
+2/ > 1d1 1d4 x 1i2
+! M + Q = 7.
+2/ = 1d3 1d4 x 1i1
+2/ 0 1d3 1d4 x 1
+2/ < 1d3 1d4 x 1
+2/ > 1d3 1d4 x 1i1
+! M + Q = 9.
+2/ = 1d2 1d7 x 1i3
+2/ 0 1d2 1d7 x 1i2
+2/ < 1d2 1d7 x 1i2
+2/ > 1d2 1d7 x 1i3
+! M + Q = 11.
+2/ = 1d4 1d7 x 1i2
+2/ 0 1d4 1d7 x 1i1
+2/ < 1d4 1d7 x 1i1
+2/ > 1d4 1d7 x 1i2
+! M + Q = 13.
+2/ = 1d6 1d7 x 1i1
+2/ 0 1d6 1d7 x 1
+2/ < 1d6 1d7 x 1
+2/ > 1d6 1d7 x 1i1
+! (1 + Mulp+) / (1 - Qulp-) -->
+! (1 + Mulp+) * (1 + (Q/2)ulp+ + ((Q/2)ulp+)^2 + tiny) -->
+! 1 + (M + Q/2)ulp+ + tiny.
+! M + Q = 2.
+2/ = 1i1 1d1 x 1i2
+2/ 0 1i1 1d1 x 1i1
+2/ < 1i1 1d1 x 1i1
+2/ > 1i1 1d1 x 1i2
+! M + Q = 3.
+2/ = 1i2 1d1 x 1i3
+2/ 0 1i2 1d1 x 1i2
+2/ < 1i2 1d1 x 1i2
+2/ > 1i2 1d1 x 1i3
+! M + Q = 4.
+2/ = 1i1 1d3 x 1i3
+2/ 0 1i1 1d3 x 1i2
+2/ < 1i1 1d3 x 1i2
+2/ > 1i1 1d3 x 1i3
+2/ = 1i3 1d1 x 1i4
+2/ 0 1i3 1d1 x 1i3
+2/ < 1i3 1d1 x 1i3
+2/ > 1i3 1d1 x 1i4
+! M + Q = 5.
+2/ = 1i2 1d3 x 1i4
+2/ 0 1i2 1d3 x 1i3
+2/ < 1i2 1d3 x 1i3
+2/ > 1i2 1d3 x 1i4
+! M + Q = 6.
+2/ = 1i3 1d3 x 1i5
+2/ 0 1i3 1d3 x 1i4
+2/ < 1i3 1d3 x 1i4
+2/ > 1i3 1d3 x 1i5
+2/ = 1i1 1d5 x 1i4
+2/ 0 1i1 1d5 x 1i3
+2/ < 1i1 1d5 x 1i3
+2/ > 1i1 1d5 x 1i4
+2/ = 1i5 1d1 x 1i6
+2/ 0 1i5 1d1 x 1i5
+2/ < 1i5 1d1 x 1i5
+2/ > 1i5 1d1 x 1i6
+!! denormal
+A/ => 0i(1)1 Tp1d1 x 1m2i1
+A/ 0< 0i(1)1 Tp1d1 x 1m2
+A/ => -0i(1)1 -Tp1d1 x 1m2i1
+A/ 0< -0i(1)1 -Tp1d1 x 1m2
+A/ =< -0i(1)1 Tp1d1 x -1m2i1
+A/ 0> -0i(1)1 Tp1d1 x -1m2
+A/ =< 0i(1)1 -Tp1d1 x -1m2i1
+A/ 0> 0i(1)1 -Tp1d1 x -1m2
+!! 3ff80000 00000001 3ff00000 00000001 3ff7ffff ffffffff
+H/ => 3m1i1 1i1 x 3m1
+H/ 0< 3m1i1 1i1 x 3m1d1
+A/ => -3m1i1 -1i1 x 3m1
+A/ 0< -3m1i1 -1i1 x 3m1d1
+A/ =< -3m1i1 1i1 x -3m1
+A/ 0> -3m1i1 1i1 x -3m1d1
+A/ =< 3m1i1 -1i1 x -3m1
+A/ 0> 3m1i1 -1i1 x -3m1d1
+!! round bit = 1, sticky bit = 1 => inexact, round up
+! (1 + Mu+) / (1 + Qu+) -->
+! Case M > Q: (1 + Mu+) * (1 - Qu+ + (Qu+)^2 - tiny) -->
+! 1 + (M-Q)u+ - (MQ-QQ)(u+)^2 + tiny -->
+! 1 + (M-Q)u+ - tiny.
+! M + Q = 3.
+2/ => 1i2 1i1 x 1i1
+2/ 0< 1i2 1i1 x 1
+2/ => -1i2 -1i1 x 1i1
+2/ 0< -1i2 -1i1 x 1
+2/ =< -1i2 1i1 x -1i1
+2/ 0> -1i2 1i1 x -1
+2/ =< 1i2 -1i1 x -1i1
+2/ 0> 1i2 -1i1 x -1
+! M + Q = 4.
+2/ = 1i3 1i1 x 1i2
+2/ 0 1i3 1i1 x 1i1
+2/ < 1i3 1i1 x 1i1
+2/ > 1i3 1i1 x 1i2
+! M + Q = 5.
+2/ = 1i4 1i1 x 1i3
+2/ 0 1i4 1i1 x 1i2
+2/ < 1i4 1i1 x 1i2
+2/ > 1i4 1i1 x 1i3
+! M + Q = 9.
+2/ = 1i7 1i2 x 1i5
+2/ 0 1i7 1i2 x 1i4
+2/ < 1i7 1i2 x 1i4
+2/ > 1i7 1i2 x 1i5
+! Q = 17.
+2/ = 1i9 1i8 x 1i1
+2/ 0 1i9 1i8 x 1
+2/ < 1i9 1i8 x 1
+2/ > 1i9 1i8 x 1i1
+! (1 - Mulp-) / (1 - Qulp-) -->
+! Case M > Q: (1 - Mulp-) * (1 + Qulp- + (Qulp-)^2 + tiny) -->
+! 1 - (M-Q)ulp- - (MQ-QQ)(ulp-)^2 + tiny -->
+! 1 - (M-Q)ulp- - tiny.
+! M + Q = 3.
+2/ = 1d2 1d1 x 1d1
+2/ 0 1d2 1d1 x 1d2
+2/ < 1d2 1d1 x 1d2
+2/ > 1d2 1d1 x 1d1
+! M + Q = 4.
+2/ = 1d3 1d1 x 1d2
+2/ 0 1d3 1d1 x 1d3
+2/ < 1d3 1d1 x 1d3
+2/ > 1d3 1d1 x 1d2
+! M + Q = 5.
+2/ = 1d3 1d2 x 1d1
+2/ 0 1d3 1d2 x 1d2
+2/ < 1d3 1d2 x 1d2
+2/ > 1d3 1d2 x 1d1
+2/ = 1d4 1d1 x 1d3
+2/ 0 1d4 1d1 x 1d4
+2/ < 1d4 1d1 x 1d4
+2/ > 1d4 1d1 x 1d3
+! M + Q = 6.
+2/ = 1d4 1d2 x 1d2
+2/ 0 1d4 1d2 x 1d3
+2/ < 1d4 1d2 x 1d3
+2/ > 1d4 1d2 x 1d2
+! M + Q = 7.
+2/ = 1d4 1d3 x 1d1
+2/ 0 1d4 1d3 x 1d2
+2/ < 1d4 1d3 x 1d2
+2/ > 1d4 1d3 x 1d1
+! M + Q = 11.
+2/ = 1d8 1d3 x 1d5
+2/ 0 1d8 1d3 x 1d6
+2/ < 1d8 1d3 x 1d6
+2/ > 1d8 1d3 x 1d5
+2/ = 1d9 1d2 x 1d7
+2/ 0 1d9 1d2 x 1d8
+2/ < 1d9 1d2 x 1d8
+2/ > 1d9 1d2 x 1d7
+! M + Q = 12.
+2/ = 1d8 1d4 x 1d4
+2/ 0 1d8 1d4 x 1d5
+2/ < 1d8 1d4 x 1d5
+2/ > 1d8 1d4 x 1d4
+! M + Q = 14.
+2/ = 1d9 1d5 x 1d4
+2/ 0 1d9 1d5 x 1d5
+2/ < 1d9 1d5 x 1d5
+2/ > 1d9 1d5 x 1d4
+!! denormal
+A/ => Td2 Tp1d1 x 1m1d3
+A/ 0< Td2 Tp1d1 x 1m1d4
+A/ => -Td2 -Tp1d1 x 1m1d3
+A/ 0< -Td2 -Tp1d1 x 1m1d4
+A/ =< -Td2 Tp1d1 x -1m1d3
+A/ 0> -Td2 Tp1d1 x -1m1d4
+A/ =< Td2 -Tp1d1 x -1m1d3
+A/ 0> Td2 -Tp1d1 x -1m1d4
--- /dev/null
+!! This file contains precision and range independent test vectors for
+!! the operation multiply (*). The first character in each
+!! test vector refers to the origin of the test vector
+!!
+!! 2: Jerome Coonen Version <2>
+!! 3: Jerome Coonen Version <3>
+!! @Phdthesis{
+!! author = {Coonen, J.T.},
+!! title = {Contributions to a proposed standard for binary
+!! floating-point arithmetic},
+!! school = {University of California, Berkeley},
+!! year = {1984}}
+!!
+!! H: precision independent encoding of UCB/<H>ough test vector
+!! @Unpublished{
+!! author = {David G. Hough and others},
+!! title = {{UCBTEST}, a suite of programs for testing certain
+!! difficult cases of {IEEE} 754 floating-point arithmetic},
+!! year = {1988},
+!! note = {Restricted public domain software from
+!! http://netlib.bell-labs.com/netlib/fp/index.html}}
+!!
+!! A: Verdonk-Cuyt-Verschaeren (University of <A>ntwerp)
+!! @Article{
+!! author = {Verdonk, B. and Cuyt, A. and Verschaeren, D.},
+!! title = {A precision- and range-independent tool for testing
+!! floating-point arithmetic {I}: basic operations,
+!! square root and remainder},
+!! journal = {ACM TOMS},
+!! volume = {27},
+!! number = {1},
+!! pages = {92-118},
+!! year = {2001}}
+!! note = {Under revision}}
+!!
+!! This file is part of the tool IeeeCC754 or IEEE 754 Compliance Checker.
+!! It is a precision and range independent tool to test whether
+!! an implementation of floating-point arithmetic (in hardware or
+!! software) is compliant with the principles of the IEEE 754-854
+!! floating-point standards. You can find out more about the testing
+!! tool IeeeCC754 and the syntax and semantics of the test vectors
+!! at
+!! http://win-www.uia.ac.be/u/cant/ieeecc754.html
+!!
+!! Last updated:
+!! $Date$
+!!
+!! Contact:
+!! Brigitte.Verdonk@ua.ac.be
+!! Department of Mathematics and Computer Science
+!! University of Antwerp (UIA)
+!! Universiteitsplein 1
+!! B2610 Antwerp, BELGIUM
+!!!! First some easy tests for consistency.
+! Check out sign manipulation.
+2* ALL 1 1 OK 1
+2* ALL -1 -1 OK 1
+2* ALL -1 1 OK -1
+2* ALL 1 2 OK 2
+2* ALL -1 -2 OK 2
+2* ALL -1 2 OK -2
+A* ALL 1 -2 OK -2
+2* ALL 2 3 OK 6
+2* ALL -2 -3 OK 6
+2* ALL -2 3 OK -6
+A* ALL 2 -3 OK -6
+2* ALL 3 3 OK 9
+2* ALL -3 -3 OK 9
+2* ALL -3 3 OK -9
+! 1.0 * various.
+2* ALL 0i1 1 OK 0i1
+!! 3ff00000 000000000 00000000 00000001 00000000 00000001
+A* ALL -0i1 -1 OK 0i1
+A* ALL -0i1 1 OK -0i1
+A* ALL -1 0i1 OK -0i1
+A* ALL 0i2 1 OK 0i2
+A* ALL -0i2 -1 OK 0i2
+2* ALL -0i2 1 OK -0i2
+A* ALL -1 0i2 OK -0i2
+!! 3ff00000 000000000 80000000 00000002 80000000 00000002
+A* ALL 0i4 1 OK 0i4
+2* ALL -0i4 -1 OK 0i4
+!! bff00000 00000000 80000000 00000004 00000000 00000004
+A* ALL -0i4 1 OK -0i4
+A* ALL -1 0i4 OK -0i4
+A* ALL Tp1d2 1 OK Tp1d2
+A* ALL -Tp1d2 -1 OK Tp1d2
+2* ALL -Tp1d2 1 OK -Tp1d2
+A* ALL -1 Tp1d2 OK -Tp1d2
+!! 3ff00000 000000000 801fffff fffffffe 801fffff fffffffe
+2* ALL 1 -0i9 OK -0i9
+2* ALL -1 0i9 OK -0i9
+A* ALL -1 -0i9 OK 0i9
+A* ALL 0i9 1 OK 0i9
+A* ALL 1 -Td1 OK -Td1
+A* ALL -1 Td1 OK -Td1
+!! bff0000000 00000000 800fffff ffffffff 000fffff ffffffff
+H* ALL -1 -Td1 OK Td1
+A* ALL Td1 1 OK Td1
+A* ALL 1 -Ti1 OK -Ti1
+A* ALL -1 Ti1 OK -Ti1
+!! !! bff0000000 00000000 801000001 00100000 00000000
+H* ALL -1 -Ti1 OK Ti1
+A* ALL Ti1 1 OK Ti1
+
+2* ALL 1 Tp1i3 OK Tp1i3
+2* ALL -1 Ti9 OK -Ti9
+2* ALL 1 Td3 OK Td3
+
+! Exact cases huge and 2.
+2* ALL 2 Hm1d1 OK Hd1
+A* ALL -2 -Hm1d1 OK Hd1
+2* ALL Hm1d1 -2 OK -Hd1
+2* ALL -Hm1d1 2 OK -Hd1
+A* ALL 2 Hm2i3 OK Hm1i3
+A* ALL -2 -Hm2i3 OK Hm1i3
+2* ALL 2 -Hm2i3 OK -Hm1i3
+A* ALL -2 Hm2i3 OK -Hm1i3
+A* ALL 2 Hm2i1 OK Hm1i1
+A* ALL -2 -Hm2i1 OK Hm1i1
+2* ALL -2 Hm2i1 OK -Hm1i1
+A* ALL 2 -Hm2i1 OK -Hm1i1
+2* ALL 2 Hm2 OK Hm1
+2* ALL Hm2 -2 OK -Hm1
+A* ALL 2 Hm2d1 OK Hm1d1
+A* ALL -2 -Hm2d1 OK Hm1d1
+2* ALL -2 Hm2d1 OK -Hm1d1
+A* ALL 2 -Hm2d1 OK -Hm1d1
+A* ALL 2 Hm2d3 OK Hm1d3
+A* ALL -2 -Hm2d3 OK Hm1d3
+2* ALL 2 -Hm2d3 OK -Hm1d3
+A* ALL -2 Hm2d3 OK -Hm1d3
+! Exact cases tiny and 2.
+2* ALL 2 T OK Tp1
+A* ALL -2 -T OK Tp1
+2* ALL T -2 OK -Tp1
+A* ALL -T 2 OK -Tp1
+2* ALL 2 Ti1 OK Tp1i1
+A* ALL -2 -Ti1 OK Tp1i1
+2* ALL -2 Ti1 OK -Tp1i1
+A* ALL 2 -Ti1 OK -Tp1i1
+A* ALL 2 Ti3 OK Tp1i3
+A* ALL -2 -Ti3 OK +Tp1i3
+A* ALL -Ti3 -2 OK Tp1i3
+2* ALL 2 -Ti3 OK -Tp1i3
+2* ALL -2 Ti3 OK -Tp1i3
+A* ALL 2 Ti5 OK Tp1i5
+A* ALL -2 -Ti5 OK Tp1i5
+2* ALL 2 -Ti5 OK -Tp1i5
+A* ALL -2 Ti5 OK -Tp1i5
+A* ALL 2 Ti9 OK Tp1i9
+A* ALL -2 -Ti9 OK Tp1i9
+2* ALL -2 Ti9 OK -Tp1i9
+A* ALL 2 -Ti9 OK -Tp1i9
+! Exact cases huge and 4.
+2* ALL 4 Hm2d1 OK Hd1
+2* ALL -4 Hm2d1 OK -Hd1
+2* ALL 4 -Hm2d1 OK -Hd1
+2* ALL -4 -Hm2d1 OK Hd1
+2* ALL Hm2d3 4 OK Hd3
+2* ALL Hm2d3 -4 OK -Hd3
+2* ALL -Hm2d3 4 OK -Hd3
+2* ALL -Hm2d3 -4 OK Hd3
+!! random exponents
+!! 36a00000 00000000 41800000 00000000 38300000 00000000
+H* ALL 1m9 1p8 OK 1m1
+A* ALL -1m9 -1p8 OK 1m1
+A* ALL -1m9 1p8 OK -1m1
+A* ALL -1p8 1m9 OK -1m1
+A* ALL 1m3 1m6 OK 1m9
+A* ALL -1m3 -1m6 OK 1m9
+A* ALL -1m3 1m6 OK -1m9
+A* ALL -1m6 1m3 OK -1m9
+A* ALL 8 8p6 OK 8p9
+A* ALL -8 -8p6 OK 8p9
+A* ALL -8 8p6 OK -8p9
+A* ALL -8p6 8 OK -8p9
+
+!! Special representations
+!! zero versus zero
+2* ALL 0 0 OK 0
+2* ALL -0 0 OK -0
+2* ALL -0 -0 OK 0
+!! zero versus denormal
+2* ALL 0i1 0 OK 0
+A* ALL -0i1 -0 OK 0
+A* ALL -0i1 0 OK -0
+A* ALL -0 0i1 OK -0
+A* ALL 0 0i2 OK 0
+A* ALL -0 -0i2 OK 0
+2* ALL 0 -0i2 OK -0
+A* ALL -0 0i2 OK -0
+A* ALL 0i3 0 OK 0
+A* ALL -0i3 -0 OK 0
+2* ALL -0i3 0 OK -0
+A* ALL 0i3 -0 OK -0
+A* ALL 0 0i4 OK 0
+2* ALL -0 -0i4 OK 0
+A* ALL 0i4 -0 OK -0
+A* ALL -0i4 0 OK -0
+2* ALL 0 Td1 OK 0
+A* ALL -0 -Td1 OK 0
+2* ALL -Td1 0 OK -0
+!! zero versus normal
+2* ALL 0 1 OK 0
+A* ALL -0 -1 OK 0
+A* ALL -0 1 OK -0
+A* ALL -1 0 OK -0
+2* ALL -2 0 OK -0
+A* ALL 0 3 OK 0
+A* ALL -0 -3 OK 0
+2* ALL 0 -3 OK -0
+A* ALL -0 3 OK -0
+A* ALL 4 0 OK 0
+2* ALL -4 -0 OK 0
+A* ALL -4 0 OK -0
+A* ALL -0 4 OK -0
+2* ALL 5 0 OK 0
+A* ALL -5 -0 OK 0
+A* ALL -5 0 OK -0
+A* ALL -0 5 OK -0
+A* ALL 6 0 OK 0
+A* ALL -6 -0 OK 0
+A* ALL -6 0 OK -0
+2* ALL -0 6 OK -0
+A* ALL 7 0 OK 0
+A* ALL -7 -0 OK 0
+A* ALL -7 0 OK -0
+A* ALL -0 7 OK -0
+A* ALL 8 0 OK 0
+A* ALL -8 -0 OK 0
+A* ALL -8 0 OK -0
+A* ALL -0 8 OK -0
+! 0 * huge -> 0.
+2* ALL Hm1 0 OK 0
+A* ALL -Hm1 -0 OK 0
+A* ALL -Hm1 0 OK -0
+A* ALL -0 Hm1 OK -0
+A* ALL Hm2 0 OK 0
+A* ALL -Hm2 -0 OK 0
+2* ALL -Hm2 0 OK -0
+A* ALL -0 Hm2 OK -0
+A* ALL Hm1d1 0 OK 0
+2* ALL -Hm1d1 -0 OK 0
+A* ALL -Hm1d1 0 OK -0
+A* ALL -0 Hm1d1 OK -0
+A* ALL Hm2d1 0 OK 0
+A* ALL -Hm2d1 -0 OK 0
+2* ALL -Hm2d1 0 OK -0
+A* ALL -0 Hm2d1 OK -0
+A* ALL 0 Hd1 OK 0
+2* ALL -Hd1 -0 OK 0
+A* ALL -Hd1 0 OK -0
+2* ALL -0 Hd1 OK -0
+! 0 * tiny -> 0.
+A* ALL 0 T OK 0
+A* ALL -T -0 OK 0
+A* ALL -T 0 OK -0
+A* ALL -0 T OK -0
+A* ALL 0 Tp1 OK 0
+A* ALL -Tp1 -0 OK 0
+2* ALL -Tp1 0 OK -0
+A* ALL Tp1 -0 OK -0
+2* ALL 0 Tp1d1 OK 0
+2* ALL -Tp1d1 -0 OK 0
+A* ALL -Tp1d1 0 OK -0
+A* ALL Tp1d1 -0 OK -0
+A* ALL 0 Ti1 OK 0
+A* ALL -Ti1 -0 OK 0
+2* ALL -Ti1 0 OK -0
+A* ALL Ti1 -0 OK -0
+!! zero versus infinity
+2* ALL H 0 i Q
+2* ALL -0 -H i Q
+2* ALL -0 H i -Q
+A* ALL 0 -H i -Q
+!! zero versus NaN
+2* ALL Q 0 OK Q
+2* ALL Q -0 OK Q
+!2* ALL S 0 i Q
+!2* ALL S -0 i Q
+!2* ALL 0 S i Q
+!2* ALL -0 S i Q
+!! infinity versus infinity
+2* ALL H H OK H
+2* ALL -H H OK -H
+2* ALL -H -H OK H
+!! infinity versus denormal
+2* ALL 0i1 H OK H
+A* ALL -0i1 -H OK H
+A* ALL -0i1 H OK -H
+A* ALL -H 0i1 OK -H
+A* ALL 0i2 H OK H
+A* ALL -0i2 -H OK H
+A* ALL -0i2 H OK -H
+A* ALL -H 0i2 OK -H
+A* ALL 0i3 H OK H
+A* ALL -0i3 -H OK H
+2* ALL -0i3 H OK -H
+A* ALL -H 0i3 OK -H
+A* ALL 0i4 H OK H
+A* ALL -0i4 -H OK H
+A* ALL -0i4 H OK -H
+A* ALL -H 0i4 OK -H
+A* ALL Td1 H OK H
+2* ALL -Td1 -H OK H
+2* ALL -Td1 H OK -H
+A* ALL -H Td1 OK -H
+!! infinity versus normal
+! Inf * small_integer -> Inf.
+2* ALL H 1 OK H
+2* ALL -2 H OK -H
+2* ALL H -3 OK -H
+2* ALL -4 -H OK H
+2* ALL 5 H OK H
+2* ALL -H 6 OK -H
+2* ALL 7 -H OK -H
+2* ALL -H -8 OK H
+! Inf * huge -> Inf.
+2* ALL Hm1 H OK H
+2* ALL -Hm2 H OK -H
+2* ALL H -Hm1 OK -H
+2* ALL -H -Hm2 OK H
+2* ALL H Hm1d1 OK H
+2* ALL -Hm2d1 H OK -H
+2* ALL H -Hd1 OK -H
+2* ALL -Hd1 -H OK H
+! Inf * tiny -> Inf.
+2* ALL T H OK H
+2* ALL -Tp1 H OK -H
+2* ALL -H -T OK H
+2* ALL H Tp1d1 OK H
+2* ALL -Ti1 H OK -H
+2* ALL -Tp1d1 -H OK H
+!! infinity versus NaN
+2* ALL Q H OK Q
+2* ALL Q -H OK Q
+!2* ALL S H i Q
+!2* ALL S -H i Q
+!2* ALL H S i Q
+!2* ALL -H S i Q
+!! NaN versus NaN
+2* ALL Q Q OK Q
+!2* ALL Q S i Q
+!2* ALL S Q i Q
+!2* ALL S S i Q
+!! NaN versus denormal
+2* ALL Td1 Q OK Q
+2* ALL -Td1 Q OK Q
+2* ALL Q 0i1 OK Q
+2* ALL Q -0i1 OK Q
+!2* ALL Td1 S i Q
+!2* ALL -Td1 S i Q
+!2* ALL S Td1 i Q
+!2* ALL S -Td1 i Q
+!2* ALL S 0i1 i Q
+!2* ALL S -0i1 i Q
+!2* ALL 0i1 S i Q
+!2* ALL -0i1 S i Q
+!! NaN versus normal
+2* ALL Q 1 OK Q
+2* ALL Q -1 OK Q
+2* ALL Q Hd1 OK Q
+2* ALL Q -Hd1 OK Q
+!2* ALL S 1 i Q
+!2* ALL S -1 i Q
+!2* ALL 1 S i Q
+!2* ALL -1 S i Q
+!2* ALL S Hd1 i Q
+!2* ALL S -Hd1 i Q
+!2* ALL Hd1 S i Q
+!2* ALL -Hd1 S i Q
+
+!! exceptions
+!! invalid, see special representations
+!! inexact, overflow
+!! exp. Z >= U
+2* => Hm1 2 xo H
+2* 0< Hm1 2i1 xo Hd1
+2* 0< Hm1 6i1 xo Hd1
+2* 0< Hm1 6 xo Hd1
+2* => Hm1 Hm1 xo H
+2* => Hm1i9 Hd6 xo H
+2* 0< Hm1 Hm2i6 xo Hd1
+2* => Hm1 Hd2 xo H
+2* => -5d2 -Hm1 xo H
+2* 0< -5d2 -Hm1 xo Hd1
+2* => -9i1 -Hm1 xo H
+2* 0< -7 -Hm1 xo Hd1
+2* => -3 -Hm1 xo H
+2* => -Hm1i5 -Hm1i1 xo H
+2* => -Hd1 -Hd1 xo H
+2* 0< -Hm2d7 -Hd1 xo Hd1
+2* => -Hd3 -Hm1i1 xo H
+2* => -Hd3 -3i1 xo H
+2* 0< -Hd3 -3i1 xo Hd1
+2* =< -3d2 Hm1 xo -H
+2* =< -7d7 Hm1 xo -H
+2* =< -9 Hm1 xo -H
+2* 0> -5 Hm1 xo -Hd1
+2* =< -Hd3 Hm1 xo -H
+2* =< -Hm2d7 Hm1 xo -H
+2* =< -Hm1d9 Hm2i1 xo -H
+2* 0> -Hm2 Hm1 xo -Hd1
+2* 0> Hm1 -4i5 xo -Hd1
+2* 0> Hm1 -8i3 xo -Hd1
+2* 0> Hm1 -2 xo -Hd1
+2* =< Hm1 -Hm2i4 xo -H
+2* =< Hm1 -Hm2 xo -H
+2* =< Hm1 -Hm1 xo -H
+2* 0> Hm1i9 -Hm2i2 xo -Hd1
+2* =< Hm1i9 -6i2 xo -H
+2* 0> Hm1i9 -6i2 xo -Hd1
+!! exp. Z = U - 1 + carry
+A* => 1i1 Hd1 xo H
+A* 0< 1i1 Hd1 xo Hd1
+A* => -1i1 -Hd1 xo H
+A* 0< -1i1 -Hd1 xo Hd1
+2* => 1i2 Hd2 xo H
+2* 0< 1i2 Hd2 xo Hd1
+A* => -1i2 -Hd2 xo H
+A* 0< -1i2 -Hd2 xo Hd1
+A* => 1i4 Hd4 xo H
+A* 0< 1i4 Hd4 xo Hd1
+A* => -1i4 -Hd4 xo H
+A* 0< -1i4 -Hd4 xo Hd1
+A* => 1i8 Hd8 xo H
+A* 0< 1i8 Hd8 xo Hd1
+A* => -1i8 -Hd8 xo H
+A* 0< -1i8 -Hd8 xo Hd1
+A* =< -1i1 Hd1 xo -H
+A* 0> -1i1 Hd1 xo -Hd1
+A* =< -Hd1 1i1 xo -H
+A* 0> -Hd1 1i1 xo -Hd1
+A* =< -1i2 Hd2 xo -H
+A* 0> -1i2 Hd2 xo -Hd1
+A* =< -Hd2 1i2 xo -H
+A* 0> -Hd2 1i2 xo -Hd1
+A* =< -1i4 Hd4 xo -H
+A* 0> -1i4 Hd4 xo -Hd1
+A* =< -Hd4 1i4 xo -H
+A* 0> -Hd4 1i4 xo -Hd1
+A* =< -1i8 Hd8 xo -H
+A* 0> -1i8 Hd8 xo -Hd1
+A* =< -Hd8 1i8 xo -H
+A* 0> -Hd8 1i8 xo -Hd1
+2* =< Hm1d3 -2i8 xo -H
+2* 0> Hm1d3 -2i8 xo -Hd1
+!! Result = Max. normal, round bit = 0, sticky bit = 01
+!! even precisions
+A* e =0< 1i(h+1)1d1 Hd(h)1i2 x Hd1
+A* e > 1i(h+1)1d1 Hd(h)1i2 xo H
+A* e =0> 1i(h+1)1d1 -Hd(h)1i2 x -Hd1
+A* e < 1i(h+1)1d1 -Hd(h)1i2 xo -H
+A* e =0> Hd(h)1i2 -1i(h+1)1d1 x -Hd1
+A* e < Hd(h)1i2 -1i(h+1)1d1 xo -H
+!! odd precisions
+A* o =0< 1i(h)1 Hd(h)2i1 x Hd1
+A* o > 1i(h)1 Hd(h)2i1 xo H
+A* o =0> 1i(h)1 -Hd(h)2i1 x -Hd1
+A* o < 1i(h)1 -Hd(h)2i1 xo -H
+!! Result = Max. normal, round bit = 0, sticky bit = 1
+!! even precisions
+A* e =0< 1i(h)1 Hd(h)2i3 x Hd1
+A* e > 1i(h)1 Hd(h)2i3 xo H
+A* e =0> 1i(h)1 -Hd(h)2i3 x -Hd1
+A* e < 1i(h)1 -Hd(h)2i3 xo -H
+!! odd precisions
+A* o =0< 1i(h)1d1 Hd(h)2i3 x Hd1
+A* o > 1i(h)1d1 Hd(h)2i3 xo H
+A* o =0> 1i(h)1d1 -Hd(h)2i3 x -Hd1
+A* o < 1i(h)1d1 -Hd(h)2i3 xo -H
+!! Result = Max. normal, round bit = 1, sticky bit = 0 => round to even
+!! even precisions
+!! This combination is only possible for precision-dependent cases
+!! odd precisions
+A* o 0< 1i(h+1)1 Hd(h+1)2 x Hd1
+A* o => 1i(h+1)1 Hd(h+1)2 xo H
+A* o 0> 1i(h+1)1 -Hd(h+1)2 x -Hd1
+A* o =< 1i(h+1)1 -Hd(h+1)2 xo -H
+!! Result = Max. normal, round bit = 1, sticky bit = 10
+A* => 2d4 Hm1i2 xo H
+A* 0< 2d4 Hm1i2 x Hd1
+A* => -2d4 -Hm1i2 xo H
+A* 0< -2d4 -Hm1i2 x Hd1
+A* =< -2d4 Hm1i2 xo -H
+A* 0> -2d4 Hm1i2 x -Hd1
+A* =< -Hm1i2 2d4 xo -H
+A* 0> -Hm1i2 2d4 x -Hd1
+!! Result = Max. normal, round bit = 1, sticky bit = 01
+!! even precisions
+A* e 0< 1i(h+5)5 Hd(h+1)1i(h+4)3 x Hd1
+A* e => 1i(h+5)5 Hd(h+1)1i(h+4)3 xo H
+A* e 0> 1i(h+5)5 -Hd(h+1)1i(h+4)3 x -Hd1
+A* e =< 1i(h+5)5 -Hd(h+1)1i(h+4)3 xo -H
+!! odd precisions
+A* o 0< 1i(h+1)1d1 Hd(h)1i2 x Hd1
+A* o => 1i(h+1)1d1 Hd(h)1i2 xo H
+A* o 0> 1i(h+1)1d1 -Hd(h)1i2 x -Hd1
+A* o =< 1i(h+1)1d1 -Hd(h)1i2 xo -H
+!! Result = Max. normal, round bit = 1, sticky bit = 1
+A* => 2d2 Hm1i1 xo H
+A* 0< 2d2 Hm1i1 x Hd1
+A* => -2d2 -Hm1i1 xo H
+A* 0< -2d2 -Hm1i1 x Hd1
+A* =< -2d2 Hm1i1 xo -H
+A* 0> -2d2 Hm1i1 x -Hd1
+A* =< -Hm1i1 2d2 xo -H
+A* 0> -Hm1i1 2d2 x -Hd1
+!! inexact, underflow
+!! X + Y <= -B-t-1 => exp. Z <= -B-t
+!! Z = 0.0...0, round bit = 0
+2* =0< T T xu 0
+A* > T T xu 0i1
+2* =0< -T -T xu 0
+A* > -T -T xu 0i1
+2* =0> -T T xu -0
+A* < -T T xu -0i1
+2* > T Tp1 xu 0i1
+A* =0< T Tp1 xu 0
+A* > -T -Tp1 xu 0i1
+A* =0< -T -Tp1 xu 0
+2* < -T Tp1 xu -0i1
+A* =0> -T Tp1 xu -0
+A* < T -Tp1 xu -0i1
+A* =0> T -Tp1 xu -0
+A* =0< Tp1 Tp1 xu 0
+A* > Tp1 Tp1 xu 0i1
+A* =0< -Tp1 -Tp1 xu 0
+2* > -Tp1 -Tp1 xu 0i1
+A* =0> -Tp1 Tp1 xu -0
+A* < -Tp1 Tp1 xu -0i1
+A* =0< 1mtm2 T xu 0
+A* > 1mtm2 T xu 0i1
+A* =0< -1mtm2 -T xu 0
+A* > -1mtm2 -T xu 0i1
+A* =0> -1mtm2 T xu -0
+A* < -1mtm2 T xu -0i1
+A* =0> 1mtm2 -T xu -0
+A* < 1mtm2 -T xu -0i1
+2* =0> -Td9 Tp1i3 xu -0
+2* =0> Td9 -Tp1i3 xu -0
+2* < -Td9 Tp1i3 xu -0i1
+2* < Td9 -Tp1i3 xu -0i1
+A* =0< Td9 Tp1i3 xu 0
+A* =0< -Td9 -Tp1i3 xu 0
+A* > Td9 Tp1i3 xu 0i1
+A* > -Td9 -Tp1i3 xu 0i1
+2* =0< Td1 Td2 xu 0
+2* =0< -Td1 -Td2 xu 0
+2* > Td1 Td2 xu 0i1
+2* > -Td1 -Td2 xu 0i1
+A* =0> -Td1 Td2 xu -0
+A* =0> Td1 -Td2 xu -0
+A* < -Td1 Td2 xu -0i1
+A* < Td1 -Td2 xu -0i1
+!! denormal
+A* =0< 0i1 1m3 xu 0
+A* > 0i1 1m3 xu 0i1
+A* =0< -0i1 -1m3 xu 0
+A* > -0i1 -1m3 xu 0i1
+A* =0> -0i1 1m3 xu -0
+A* < -0i1 1m3 xu -0i1
+A* =0> 0i1 -1m3 xu -0
+A* < 0i1 -1m3 xu -0i1
+2* > 0i1 0i1 xu 0i1
+2* =0< 0i1 0i1 xu 0
+2* < 0i1 -0i1 xu -0i1
+2* =0> -0i1 0i1 xu -0
+A* > -0i1 -0i1 xu 0i1
+A* =0< -0i1 -0i1 xu 0
+!! X + Y = -B-t-1, exp. Z = -B-t, due to carry,
+!! round bit = 0, sticky bits = 1
+A* =0< 1mtm1d1 Ti1 xu 0
+A* > 1mtm1d1 Ti1 xu 0i1
+A* =0< -1mtm1d1 -Ti1 xu 0
+A* > -1mtm1d1 -Ti1 xu 0i1
+A* =0> -1mtm1d1 Ti1 xu -0
+A* < -1mtm1d1 Ti1 xu -0i1
+A* =0> 1mtm1d1 -Ti1 xu -0
+A* < 1mtm1d1 -Ti1 xu -0i1
+!! X + Y = -B-t, exp. Z = -B-t, no carry
+!! round bit = 0, sticky bits = 1
+A* =0< 1mtd1 T xu 0
+A* > 1mtd1 T xu 0i1
+A* =0< -1mtd1 -T xu 0
+A* > -1mtd1 -T xu 0i1
+A* =0> -1mtd1 T xu -0
+A* < -1mtd1 T xu -0i1
+A* =0> 1mtd1 -T xu -0
+A* < 1mtd1 -T xu -0i1
+!! denormal
+A* =0< 0i1 1m2 xu 0
+A* > 0i1 1m2 xu 0i1
+A* =0< -0i1 -1m2 xu 0
+A* > -0i1 -1m2 xu 0i1
+A* =0> -0i1 1m2 xu -0
+A* < -0i1 1m2 xu -0i1
+A* =0> -1m2 0i1 xu -0
+A* < -1m2 0i1 xu -0i1
+!! X + Y = -B-t+2, exp. Z = -B-t+2, no carry
+!! round bit = 0, sticky bits = 1
+A* =0< 0i1 3m1d1 xu 0i1
+A* > 0i1 3m1d1 xu 0i2
+A* =0< -0i1 -3m1d1 xu 0i1
+A* > -0i1 -3m1d1 xu 0i2
+A* =0> -0i1 3m1d1 xu -0i1
+A* < -0i1 3m1d1 xu -0i2
+A* =0> -3m1d1 0i1 xu -0i1
+A* < -3m1d1 0i1 xu -0i2
+!! 3ff7ffff ffffffff 80000000 00000001 80000000 00000001
+!! X + Y = -B-t+3, exp. Z = -B-t+3, no carry
+!! round bit = 0, sticky bits = 1
+A* =0< 0i1 7m1d1 xu 0i3
+A* > 0i1 7m1d1 xu 0i4
+A* =0< -0i1 -7m1d1 xu 0i3
+A* > -0i1 -7m1d1 xu 0i4
+A* =0> -0i1 7m1d1 xu -0i3
+A* < -0i1 7m1d1 xu -0i4
+A* =0> -7m1d1 0i1 xu -0i3
+A* < -7m1d1 0i1 xu -0i4
+!! 400bffff ffffffff 80000000 00000001 800000 00000003
+!! X + Y = -B-t, exp. Z = -B-t-1, due to carry
+!! Z = 0.0...0, round bit = 1, sticky bits = 0
+!! This combination is not possible
+!! X + Y = -B-t+1, exp. Z = -B-t+1, no carry
+!! Z = 0.0...0, round bit = 1, sticky bits = 0
+!! even result
+A* =0< 1mt T xu 0
+A* > 1mt T xu 0i1
+A* =0< -1mt -T xu 0
+A* > -1mt -T xu 0i1
+A* =0> -1mt T xu -0
+A* < -1mt T xu -0i1
+A* =0> 1mt -T xu -0
+A* < 1mt -T xu -0i1
+!! denormal
+2* > 0i1 1m1 xu 0i1
+2* =0< 0i1 1m1 xu 0
+A* > -0i1 -1m1 xu 0i1
+A* =0< -0i1 -1m1 xu 0
+2* < 1m1 -0i1 xu -0i1
+2* =0> 1m1 -0i1 xu -0
+!! bfe00000 00000001 000000000 00000001 80000000 00000001
+H* < -1m1 0i1 xu -0i1
+H* =0> -1m1 0i1 xu -0
+!! X + Y = -B-t+2, exp. Z = -B-t+2, no carry
+!! Z = 0.0...01, round bit = 1, sticky bits = 0
+!! odd result
+A* 0< 0i1 3m1 xu 0i1
+A* => 0i1 3m1 xu 0i2
+A* 0< -0i1 -3m1 xu 0i1
+A* => -0i1 -3m1 xu 0i2
+!! bff80000 00000000 80000000 00000001 00000000 00000002
+A* 0> 3m1 -0i1 xu -0i1
+A* =< 3m1 -0i1 xu -0i2
+A* 0> -3m1 0i1 xu -0i1
+A* =< -3m1 0i1 xu -0i2
+!! X + Y = -B-t+3, exp. Z = -B-t+3, no carry
+!! Z = 0.0...01x, round bit = 1, sticky bits = 0
+!! even result
+A* =0< 0i1 5m1 xu 0i2
+A* > 0i1 5m1 xu 0i3
+A* =0< -0i1 -5m1 xu 0i2
+A* > -0i1 -5m1 xu 0i3
+A* =0> 5m1 -0i1 xu -0i2
+A* < 5m1 -0i1 xu -0i3
+A* =0> -5m1 0i1 xu -0i2
+A* < -5m1 0i1 xu -0i3
+!! odd result
+A* 0< 0i1 7m1 xu 0i3
+A* => 0i1 7m1 xu 0i4
+A* 0< -0i1 -7m1 xu 0i3
+A* => -0i1 -7m1 xu 0i4
+!! c00c0000 00000000 800000000 00000001 000000000 00000004
+A* 0> 7m1 -0i1 xu -0i3
+A* =< 7m1 -0i1 xu -0i4
+A* 0> -7m1 0i1 xu -0i3
+A* =< -7m1 0i1 xu -0i4
+!! X + Y = -B-t+1, exp. Z = -B-t+1, no carry
+!! Z = 0.0...0, round bit = 1, sticky bit = 1
+A* 0< 5mtm2 T xu 0
+A* => 5mtm2 T xu 0i1
+A* 0< -5mtm2 -T xu 0
+A* => -5mtm2 -T xu 0i1
+A* 0> -5mtm2 T xu -0
+A* =< -5mtm2 T xu -0i1
+A* 0> -T 5mtm2 xu -0
+A* =< -T 5mtm2 xu -0i1
+!! denormal
+A* 0< 0i1 1m1i1 xu 0
+A* => 0i1 1m1i1 xu 0i1
+A* 0< -0i1 -1m1i1 xu 0
+A* => -0i1 -1m1i1 xu 0i1
+A* 0> -0i1 1m1i1 xu -0
+A* =< -0i1 1m1i1 xu -0i1
+A* 0> -1m1i1 0i1 xu -0
+A* =< -1m1i1 0i1 xu -0i1
+!! X + Y = -B-t+2, exp. Z = -B-t+2, no carry
+!! Z = 0.0..010, round bit = 1, sticky bit = 1
+A* 0< 5m1i1 0i1 xu 0i2
+A* => 5m1i1 0i1 xu 0i3
+A* 0< -5m1i1 -0i1 xu 0i2
+A* => -5m1i1 -0i1 xu 0i3
+!! c0040000 00000001 00000000 00000001 80000000 00000003
+H* 0> -5m1i1 0i1 xu -0i2
+H* =< -5m1i1 0i1 xu -0i3
+A* 0> -0i1 5m1i1 xu -0i2
+A* =< -0i1 5m1i1 xu -0i3
+!! X + Y = -B-t, exp. Z = -B-t+1, due to carry
+!! Z = 0.0...0, round bit = 1, sticky bits = 1
+A* 0< 1mtm1i1 Tp1d1 xu 0
+A* => 1mtm1i1 Tp1d1 xu 0i1
+A* 0< -1mtm1i1 -Tp1d1 xu 0
+A* => -1mtm1i1 -Tp1d1 xu 0i1
+A* 0> -1mtm1i1 Tp1d1 xu -0
+A* =< -1mtm1i1 Tp1d1 xu -0i1
+A* 0> -Tp1d1 1mtm1i1 xu -0
+A* =< -Tp1d1 1mtm1i1 xu -0i1
+!! X + Y = -B-t+1, exp. Z = -B-t+1, no carry
+!! Z = 0.0...0, round bit = 1, sticky bits = 10
+A* 0< 3mtm1 T xu 0
+A* => 3mtm1 T xu 0i1
+A* 0< -3mtm1 -T xu 0
+A* => -3mtm1 -T xu 0i1
+A* 0> -3mtm1 T xu -0
+A* =< -3mtm1 T xu -0i1
+A* 0> -T 3mtm1 xu -0
+A* =< -T 3mtm1 xu -0i1
+!! denormal
+A* 0< 0i1 3m2 xu 0
+A* => 0i1 3m2 xu 0i1
+A* 0< -0i1 -3m2 xu 0
+A* => -0i1 -3m2 xu 0i1
+A* 0> -0i1 3m2 xu -0
+A* =< -0i1 3m2 xu -0i1
+A* 0> -3m2 0i1 xu -0
+A* =< -3m2 0i1 xu -0i1
+!! X + Y = -B-t, exp. Z = -B-t+1, due to carry
+!! Z = 0.0...0, round bit = 1, sticky bits = 0
+!! This combination is not possible
+!! X + Y = -B-t+1, exp. Z = -B-t+1, no carry
+!! Z = 0.0...0, round bit = 1, sticky bits = 1
+A* 0< 7mtm2 T xu 0
+A* => 7mtm2 T xu 0i1
+A* 0< -7mtm2 -T xu 0
+A* => -7mtm2 -T xu 0i1
+A* 0> -7mtm2 T xu -0
+A* =< -7mtm2 T xu -0i1
+A* 0> -T 7mtm2 xu -0
+A* =< -T 7mtm2 xu -0i1
+!! denormal
+A* 0< 0i1 3m2i1 xu 0
+A* => 0i1 3m2i1 xu 0i1
+A* 0< -0i1 -3m2i1 xu 0
+A* => -0i1 -3m2i1 xu 0i1
+A* 0> -0i1 3m2i1 xu -0
+A* =< -0i1 3m2i1 xu -0i1
+A* 0> -3m2i1 0i1 xu -0
+A* =< -3m2i1 0i1 xu -0i1
+2* 0< 0i1 1d1 xu 0
+2* => 0i1 1d1 xu 0i1
+A* 0< -0i1 -1d1 xu 0
+A* => -0i1 -1d1 xu 0i1
+2* 0> -0i1 1d1 xu -0
+A* =< -0i1 1d1 xu -0i1
+2* =< 0i1 -1d1 xu -0i1
+A* 0> 0i1 -1d1 xu -0
+!! X + Y = -B-t, exp. Z = -B-t+1, due to carry
+!! Z = 0.0...0, round bit = 1, sticky bits = 1
+A* 0< 1mtd1 Tp1d1 xu 0
+A* => 1mtd1 Tp1d1 xu 0i1
+A* 0< -1mtd1 -Tp1d1 xu 0
+A* => -1mtd1 -Tp1d1 xu 0i1
+A* 0> -1mtd1 Tp1d1 xu -0
+A* =< -1mtd1 Tp1d1 xu -0i1
+A* 0> -Tp1d1 1mtd1 xu -0
+A* =< -Tp1d1 1mtd1 xu -0i1
+!! exp. Z = -B + denormalization loss => inexactness
+!! denormal
+2* 0< Td4 1i1 xu Td4
+A* => Td4 1i1 xv Td3
+A* 0< -Td4 -1i1 xu Td4
+A* => -Td4 -1i1 xv Td3
+A* 0> -Td4 1i1 xu -Td4
+A* =< -Td4 1i1 xv -Td3
+A* 0> -1i1 Td4 xu -Td4
+A* =< -1i1 Td4 xv -Td3
+!! exp. Z = -B + denormalization loss after carry => inexactness
+A* => 3m2 Ti1 xv 0i(2)3i1
+A* 0< 3m2 Ti1 xu 0i(2)3
+A* => -3m2 -Ti1 xv 0i(2)3i1
+A* 0< -3m2 -Ti1 xu 0i(2)3
+A* =< -3m2 Ti1 xv -0i(2)3i1
+A* 0> -3m2 Ti1 xu -0i(2)3
+A* =< -Ti1 3m2 xv -0i(2)3i1
+A* 0> -Ti1 3m2 xu -0i(2)3
+!! exp. Z = -B + inexactness, no denormalization loss for =
+A* 0< Td2 1i1 xu Td2
+2* => Td2 1i1 xv Td1
+A* 0< -Td2 -1i1 xu Td2
+A* => -Td2 -1i1 xv Td1
+A* 0> -Td2 1i1 xu -Td2
+A* =< -Td2 1i1 xv -Td1
+A* 0> -1i1 Td2 xu -Td2
+A* =< -1i1 Td2 xv -Td1
+A* 0< Td8 1i1 xu Td8
+2* => Td8 1i1 xv Td7
+A* 0< -Td8 -1i1 xu Td8
+A* => -Td8 -1i1 xv Td7
+A* 0> -Td8 1i1 xu -Td8
+A* =< -Td8 1i1 xv -Td7
+A* 0> -1i1 Td8 xu -Td8
+A* =< -1i1 Td8 xv -Td7
+A* 0< Td9 1i1 xu Td9
+A* => Td9 1i1 xv Td8
+A* 0< -Td9 -1i1 xu Td9
+A* => -Td9 -1i1 xv Td8
+A* 0> -Td9 1i1 xu -Td9
+2* =< -Td9 1i1 xv -Td8
+A* 0> -1i1 Td9 xu -Td9
+A* =< -1i1 Td9 xv -Td8
+A* 0< Ti1 1d6 xu Td3
+2* => Ti1 1d6 xv Td2
+A* 0< -Ti1 -1d6 xu Td3
+A* => -Ti1 -1d6 xv Td2
+A* 0> -Ti1 1d6 xu -Td3
+A* =< -Ti1 1d6 xv -Td2
+A* 0> -1d6 Ti1 xu -Td3
+A* =< -1d6 Ti1 xv -Td2
+A* =0< Td2 1d4 xv Td4
+2* > Td2 1d4 xu Td3
+A* =0< -Td2 -1d4 xv Td4
+A* > -Td2 -1d4 xu Td3
+A* =0> -Td2 1d4 xv -Td4
+A* < -Td2 1d4 xu -Td3
+A* =0> -1d4 Td2 xv -Td4
+A* < -1d4 Td2 xu -Td3
+!! exp. Z = -B after carry + inexactness, no denormalization loss for =
+A* =0< 1m1d1 Ti3 xv 0i(1)1i1
+A* > 1m1d1 Ti3 xu 0i(1)1i2
+A* =0< -1m1d1 -Ti3 xv 0i(1)1i1
+A* > -1m1d1 -Ti3 xu 0i(1)1i2
+A* =0> -1m1d1 Ti3 xv -0i(1)1i1
+A* < -1m1d1 Ti3 xu -0i(1)1i2
+A* =0> -Ti3 1m1d1 xv -0i(1)1i1
+A* < -Ti3 1m1d1 xu -0i(1)1i2
+!! exp. Z = -B + tininess before rounding, not after rounding
+!! round bit = 1
+2* 0< Td1 1i1 xu Td1
+2* => Td1 1i1 xw T
+A* 0< -Td1 -1i1 xu Td1
+A* => -Td1 -1i1 xw T
+!! 800fffff ffffffff 3ff00000 00000001 80100000 00000000
+H* 0> -Td1 1i1 xu -Td1
+2* =< -Td1 1i1 xw -T
+A* 0> -1i1 Td1 xu -Td1
+A* =< -1i1 Td1 xw -T
+A* 0< 1i8 Td8 xu Td1
+2* => 1i8 Td8 xw T
+!! 000fffff fffffff8 3ff00000 00000008 00100000 00000000
+A* 0< -Td8 -1i8 xu Td1
+A* => -Td8 -1i8 xw T
+A* 0> -Td8 1i8 xu -Td1
+A* =< -Td8 1i8 xw -T
+A* 0> -1i8 Td8 xu -Td1
+A* =< -1i8 Td8 xw -T
+!! 000fffff fffffff8 bff00000 00000008 80100000 00000000
+2* 0< Ti1 1d2 xu Td1
+!! 00100000 00000001 3fefffff fffffffe 00100000 0000000
+H* => Ti1 1d2 xw T
+A* 0< -Ti1 -1d2 xu Td1
+A* => -Ti1 -1d2 xw T
+A* 0> -Ti1 1d2 xu -Td1
+A* =< -Ti1 1d2 xw -T
+A* 0> -1d2 Ti1 xu -Td1
+A* =< -1d2 Ti1 xw -T
+A* 0< Ti2 1d4 xu Td1
+!! subsitute for 20000000 02000000 1fffffff fc000000 00100000 00000000
+H* => Ti2 1d4 xw T
+A* 0< -Ti2 -1d4 xu Td1
+A* => -Ti2 -1d4 xw T
+A* 0> -Ti2 1d4 xu -Td1
+A* =< -Ti2 1d4 xw -T
+A* 0> -1d4 Ti2 xu -Td1
+A* =< -1d4 Ti2 xw -T
+!! round bit = 0
+A* 0< 1m1i2 Tp1d5 xv Td1
+A* = 1m1i2 Tp1d5 xu Td1
+A* > 1m1i2 Tp1d5 xu T
+A* 0< -1m1i2 -Tp1d5 xv Td1
+A* = -1m1i2 -Tp1d5 xu Td1
+A* > -1m1i2 -Tp1d5 xu T
+A* 0> -1m1i2 Tp1d5 xv -Td1
+A* = -1m1i2 Tp1d5 xu -Td1
+A* < -1m1i2 Tp1d5 xu -T
+A* 0> -Tp1d5 1m1i2 xv -Td1
+A* = -Tp1d5 1m1i2 xu -Td1
+A* < -Tp1d5 1m1i2 xu -T
+!! tininess before and after rounding,
+!! as though the exponent range were unbounded
+2* 0< Tp1d1 1m1 xu Td1
+2* => Tp1d1 1m1 xu T
+A* => -Tp1d1 -1m1 xu T
+2* 0< -Tp1d1 -1m1 xu Td1
+2* 0> -Tp1d1 1m1 xu -Td1
+A* =< -Tp1d1 1m1 xu -T
+A* 0> -1m1 Tp1d1 xu -Td1
+A* =< -1m1 Tp1d1 xu -T
+! Exact and below denormalization threshold -- no underflow.
+2* ALL T 1d2 OK Td1
+A* ALL -T -1d2 OK Td1
+A* ALL -T 1d2 OK -Td1
+A* ALL -1d2 T OK -Td1
+2* ALL Tp1d2 1m1 OK Td1
+A* ALL -Tp1d2 -1m1 OK Td1
+A* ALL -Tp1d2 1m1 OK -Td1
+A* ALL -1m1 Tp1d2 OK -Td1
+A* ALL Tp1d4 1m1 OK Td2
+2* ALL -Tp1d4 -1m1 OK Td2
+2* ALL -Tp1d4 1m1 OK -Td2
+A* ALL -1m1 Tp1d4 OK -Td2
+2* ALL Tp1d8 1m1 OK Td4
+A* ALL -Tp1d8 -1m1 OK Td4
+A* ALL -Tp1d8 1m1 OK -Td4
+A* ALL -1m1 Tp1d8 OK -Td4
+2* ALL 0i8 1m3 OK 0i1
+A* ALL -0i8 -1m3 OK 0i1
+2* ALL -0i8 1m3 OK -0i1
+A* ALL -1m3 0i8 OK -0i1
+2* ALL 0i6 1m1 OK 0i3
+A* ALL -0i6 -1m1 OK 0i3
+A* ALL -0i6 1m1 OK -0i3
+A* ALL -1m1 0i6 OK -0i3
+!! inexact, see rounding below
+
+!! exact rounding
+!! round bit = 0, sticky bit = 1 => inexact, round down
+!! carry
+2* 0<= 3d1 1d1 x 3d2
+2* > 3d1 1d1 x 3d1
+A* 0<= -3d1 -1d1 x 3d2
+A* > -3d1 -1d1 x 3d1
+2* 0>= -3d1 1d1 x -3d2
+2* < -3d1 1d1 x -3d1
+A* 0>= -1d1 3d1 x -3d2
+A* < -1d1 3d1 x -3d1
+2* 0<= 5d1 1d1 x 5d2
+2* > 5d1 1d1 x 5d1
+2* 0<= -5d1 -1d1 x 5d2
+2* > -5d1 -1d1 x 5d1
+A* 0>= -5d1 1d1 x -5d2
+A* < -5d1 1d1 x -5d1
+A* 0>= 5d1 -1d1 x -5d2
+A* < 5d1 -1d1 x -5d1
+2* =0< 7d1 1d1 x 7d2
+2* > 7d1 1d1 x 7d1
+A* =0< -7d1 -1d1 x 7d2
+A* > -7d1 -1d1 x 7d1
+A* =0> -7d1 1d1 x -7d2
+A* < -7d1 1d1 x -7d1
+A* =0> -1d1 7d1 x -7d2
+A* < -1d1 7d1 x -7d1
+A* =0< Tp1d1 1d1 x Tp1d2
+A* > Tp1d1 1d1 x Tp1d1
+A* =0< -Tp1d1 -1d1 x Tp1d2
+A* > -Tp1d1 -1d1 x Tp1d1
+A* =0> -Tp1d1 1d1 x -Tp1d2
+A* < -Tp1d1 1d1 x -Tp1d1
+A* =0> -1d1 Tp1d1 x -Tp1d2
+A* < -1d1 Tp1d1 x -Tp1d1
+A* =0< Hm2d7 4d1 x Hd8
+A* > Hm2d7 4d1 x Hd7
+2* =0< -Hm2d7 -4d1 x Hd8
+2* > -Hm2d7 -4d1 x Hd7
+A* =0> -Hm2d7 4d1 x -Hd8
+A* < -Hm2d7 4d1 x -Hd7
+A* =0> -4d1 Hm2d7 x -Hd8
+A* < -4d1 Hm2d7 x -Hd7
+!! no carry
+2* 0<= 1i1 1i1 x 1i2
+2* > 1i1 1i1 x 1i3
+2* 0<= -1i1 -1i1 x 1i2
+2* > -1i1 -1i1 x 1i3
+2* 0>= -1i1 1i1 x -1i2
+2* < -1i1 1i1 x -1i3
+2* =0< 1i2 1i1 x 1i3
+2* > 1i2 1i1 x 1i4
+2* =0< -1i2 -1i1 x 1i3
+2* > -1i1 -1i2 x 1i4
+2* =0> -1i2 1i1 x -1i3
+2* < -1i2 1i1 x -1i4
+A* =0> 1i2 -1i1 x -1i3
+A* < 1i2 -1i1 x -1i4
+2* =0< -1d1 -Hd1 x Hd2
+2* > -1d1 -Hd1 x Hd1
+!! denormal
+A* =0< 0i(1)1i1 2i1 x Ti3
+A* > 0i(1)1i1 2i1 x Ti4
+A* =0< -0i(1)1i1 -2i1 x Ti3
+A* > -0i(1)1i1 -2i1 x Ti4
+A* =0> -0i(1)1i1 2i1 x -Ti3
+A* < -0i(1)1i1 2i1 x -Ti4
+A* =0> -2i1 0i(1)1i1 x -Ti3
+A* < -2i1 0i(1)1i1 x -Ti4
+!! round bit = 0, sticky bit = 10 => inexact, round down
+!! carry
+A* =0< 3d1 3 x 8i(3)1d1
+A* > 3d1 3 x 8i(3)1
+A* =0< -3d1 -3 x 8i(3)1d1
+A* > -3d1 -3 x 8i(3)1
+A* =0> -3d1 3 x -8i(3)1d1
+A* < -3d1 3 x -8i(3)1
+A* =0> -3 3d1 x -8i(3)1d1
+A* < -3 3d1 x -8i(3)1
+!! no carry
+A* =0< 5 Hm3i1 x 5pB0m2i1
+A* > 5 Hm3i1 x 5pB0m2i2
+A* =0< -5 -Hm3i1 x 5pB0m2i1
+A* > -5 -Hm3i1 x 5pB0m2i2
+A* =0> -5 Hm3i1 x -5pB0m2i1
+A* < -5 Hm3i1 x -5pB0m2i2
+A* =0> -Hm3i1 5 x -5pB0m2i1
+A* < -Hm3i1 5 x -5pB0m2i2
+A* =0< 5mB0 2i1 x 5mB0p1i1
+A* > 5mB0 2i1 x 5mB0p1i2
+A* =0< -5mB0 -2i1 x 5mB0p1i1
+A* > -5mB0 -2i1 x 5mB0p1i2
+A* =0> -5mB0 2i1 x -5mB0p1i1
+A* < -5mB0 2i1 x -5mB0p1i2
+A* =0> -2i1 5mB0 x -5mB0p1i1
+A* < -2i1 5mB0 x -5mB0p1i2
+!! round bit = 0, sticky bit = 1 => inexact, round down
+!! no carry
+2* =0< 5i1 1i1 x 5i2
+2* > 5i1 1i1 x 5i3
+2* =0< -5i1 -1i1 x 5i2
+2* > -5i1 -1i1 x 5i3
+A* =0> -5i1 1i1 x -5i2
+A* < -5i1 1i1 x -5i3
+A* =0> -1i1 5i1 x -5i2
+A* < -1i1 5i1 x -5i3
+!! carry
+A* =0< 7d1 1d2 x 7d3
+A* > 7d1 1d2 x 7d2
+A* =0< -7d1 -1d2 x 7d3
+A* > -7d1 -1d2 x 7d2
+A* =0> -7d1 1d2 x -7d3
+A* < -7d1 1d2 x -7d2
+A* =0> -1d2 7d1 x -7d3
+A* < -1d2 7d1 x -7d2
+A* =0< 1d1 1d2 x 1d3
+A* > 1d1 1d2 x 1d2
+A* =0< -1d1 -1d2 x 1d3
+A* > -1d1 -1d2 x 1d2
+A* =0> -1d1 1d2 x -1d3
+A* < -1d1 1d2 x -1d2
+A* =0> 1d1 -1d2 x -1d3
+A* < 1d1 -1d2 x -1d2
+A* =0< Hm1d1 1i1 x Hm1
+A* > Hm1d1 1i1 x Hm1i1
+A* =0< -Hm1d1 -1i1 x Hm1
+A* > -Hm1d1 -1i1 x Hm1i1
+2* =0> -Hm1d1 1i1 x -Hm1
+2* < -Hm1d1 1i1 x -Hm1i1
+A* =0> -1i1 Hm1d1 x -Hm1
+A* < -1i1 Hm1d1 x -Hm1i1
+A* =0< Hm2d1 2i1 x Hm1
+A* > Hm2d1 2i1 x Hm1i1
+A* =0< -Hm2d1 -2i1 x Hm1
+A* > -Hm2d1 -2i1 x Hm1i1
+2* =0> -Hm2d1 2i1 x -Hm1
+2* < -Hm2d1 2i1 x -Hm1i1
+A* =0> -2i1 Hm2d1 x -Hm1
+A* < -2i1 Hm2d1 x -Hm1i1
+A* =0< 5mB0i1 2i1 x 5mB0p1i2
+A* > 5mB0i1 2i1 x 5mB0p1i3
+A* =0< -5mB0i1 -2i1 x 5mB0p1i2
+A* > -5mB0i1 -2i1 x 5mB0p1i3
+A* =0> -5mB0i1 2i1 x -5mB0p1i2
+A* < -5mB0i1 2i1 x -5mB0p1i3
+A* =0> -2i1 5mB0i1 x -5mB0p1i2
+A* < -2i1 5mB0i1 x -5mB0p1i3
+!! round bit = 1, sticky bit = 0
+!! half-way cases, round to even
+!! odd result
+!! carry
+A* => 3i4 7 x 21i4
+A* 0< 3i4 7 x 21i3
+A* => -3i4 -7 x 21i4
+A* 0< -3i4 -7 x 21i3
+A* =< -3i4 7 x -21i4
+A* 0> -3i4 7 x -21i3
+A* =< -7 3i4 x -21i4
+A* 0> -7 3i4 x -21i3
+!! no carry
+A* => 3 1i1 x 3i2
+A* 0< 3 1i1 x 3i1
+A* => -3 -1i1 x 3i2
+A* 0< -3 -1i1 x 3i1
+A* =< -3 1i1 x -3i2
+A* 0> -3 1i1 x -3i1
+A* =< -1i1 3 x -3i2
+A* 0> -1i1 3 x -3i1
+!! denormal
+A* => 1m1 Ti3 xu 0i(1)1i2
+A* 0< 1m1 Ti3 xu 0i(1)1i1
+A* => -1m1 -Ti3 xu 0i(1)1i2
+A* 0< -1m1 -Ti3 xu 0i(1)1i1
+A* =< -1m1 Ti3 xu -0i(1)1i2
+A* 0> -1m1 Ti3 xu -0i(1)1i1
+A* =< -Ti3 1m1 xu -0i(1)1i2
+A* 0> -Ti3 1m1 xu -0i(1)1i1
+!! even result
+!! carry
+A* =0< 3i4i8 7 x 21i8i2
+A* > 3i4i8 7 x 21i8i3
+A* =0< -3i4i8 -7 x 21i8i2
+A* > -3i4i8 -7 x 21i8i3
+A* =0> -3i4i8 7 x -21i8i2
+A* < -3i4i8 7 x -21i8i3
+A* =0> -7 3i4i8 x -21i8i2
+A* < -7 3i4i8 x -21i8i3
+!! no carry
+A* =0< 3 1i3 x 3i4
+A* > 3 1i3 x 3i5
+A* =0< -3 -1i3 x 3i4
+A* > -3 -1i3 x 3i5
+A* =0> -3 1i3 x -3i4
+A* < -3 1i3 x -3i5
+A* =0> -1i3 3 x -3i4
+A* < -1i3 3 x -3i5
+!! denormal
+A* > 1m1 Ti1 xu 0i(1)1i1
+A* =0< 1m1 Ti1 xu 0i(1)1
+A* > -1m1 -Ti1 xu 0i(1)1i1
+A* =0< -1m1 -Ti1 xu 0i(1)1
+A* < -1m1 Ti1 xu -0i(1)1i1
+A* =0> -1m1 Ti1 xu -0i(1)1
+A* < -Ti1 1m1 xu -0i(1)1i1
+A* =0> -Ti1 1m1 xu -0i(1)1
+!! round bit = 1, sticky bit = 10 => inexact, round up
+!! carry
+A* => 1i(2)1 2d2 x 2i(2)1d1
+A* 0< 1i(2)1 2d2 x 2i(2)1d2
+A* => -1i(2)1 -2d2 x 2i(2)1d1
+A* 0< -1i(2)1 -2d2 x 2i(2)1d2
+A* =< -1i(2)1 2d2 x -2i(2)1d1
+A* 0> -1i(2)1 2d2 x -2i(2)1d2
+A* =< -2d2 1i(2)1 x -2i(2)1d1
+A* 0> -2d2 1i(2)1 x -2i(2)1d2
+!! no carry
+A* => 7 1i1 x 7i2
+A* 0< 7 1i1 x 7i1
+A* => -7 -1i1 x 7i2
+A* 0< -7 -1i1 x 7i1
+A* =< -7 1i1 x -7i2
+A* 0> -7 1i1 x -7i1
+A* =< -1i1 7 x -7i2
+A* 0> -1i1 7 x -7i1
+A* => 7mB0 4i1 x 7mB0p2i2
+A* 0< 7mB0 4i1 x 7mB0p2i1
+A* => -7mB0 -4i1 x 7mB0p2i2
+A* 0< -7mB0 -4i1 x 7mB0p2i1
+A* =< -7mB0 4i1 x -7mB0p2i2
+A* 0> -7mB0 4i1 x -7mB0p2i1
+A* =< -4i1 7mB0 x -7mB0p2i2
+A* 0> -4i1 7mB0 x -7mB0p2i1
+!! round bit = 1, sticky bit = 1 => inexact, round up
+!! no carry
+2* => 3i1 1i1 x 3i3
+2* 0< 3i1 1i1 x 3i2
+A* => -3i1 -1i1 x 3i3
+A* 0< -3i1 -1i1 x 3i2
+2* =< -3i1 1i1 x -3i3
+2* 0> -3i1 1i1 x -3i2
+A* =< -1i1 3i1 x -3i3
+A* 0> -1i1 3i1 x -3i2
+A* => 3i1 1i3 x 3i6
+A* 0< 3i1 1i3 x 3i5
+A* => -3i1 -1i3 x 3i6
+A* 0< -3i1 -1i3 x 3i5
+A* =< -3i1 1i3 x -3i6
+A* 0> -3i1 1i3 x -3i5
+A* =< -1i3 3i1 x -3i6
+A* 0> -1i3 3i1 x -3i5
+!! carry
+2* => 3d1 1d2 x 3d2
+2* 0< 3d1 1d2 x 3d3
+A* => -3d1 -1d2 x 3d2
+A* 0< -3d1 -1d2 x 3d3
+A* =< -3d1 1d2 x -3d2
+A* 0> -3d1 1d2 x -3d3
+A* =< -1d2 3d1 x -3d2
+A* 0> -1d2 3d1 x -3d3
+2* => 7d1 1d4 x 7d4
+2* 0< 7d1 1d4 x 7d5
+A* => -7d1 -1d4 x 7d4
+A* 0< -7d1 -1d4 x 7d5
+A* =< -7d1 1d4 x -7d4
+A* 0> -7d1 1d4 x -7d5
+A* =< -1d4 7d1 x -7d4
+A* 0> -1d4 7d1 x -7d5
+A* => 3mB0i1 4i1 x 3mB0p2i3
+A* 0< 3mB0i1 4i1 x 3mB0p2i2
+A* => -3mB0i1 -4i1 x 3mB0p2i3
+A* 0< -3mB0i1 -4i1 x 3mB0p2i2
+A* =< -3mB0i1 4i1 x -3mB0p2i3
+A* 0> -3mB0i1 4i1 x -3mB0p2i2
+A* =< -4i1 3mB0i1 x -3mB0p2i3
+A* 0> -4i1 3mB0i1 x -3mB0p2i2
+!! round bit = 1, sticky bit = 1 => inexact, round up
+!! no carry
+2* => 7i1 1i1 x 7i3
+2* 0< 7i1 1i1 x 7i2
+A* => -7i1 -1i1 x 7i3
+A* 0< -7i1 -1i1 x 7i2
+2* =< -7i1 1i1 x -7i3
+2* 0> -7i1 1i1 x -7i2
+A* =< -1i1 7i1 x -7i3
+A* 0> -1i1 7i1 x -7i2
+!! 3fefffff fffffffe 3ff00000 00000001 3fefffff ffffffff
+H* => 1d2 1i1 x 1
+A* 0< 1d2 1i1 x 1d1
+A* => -1d2 -1i1 x 1
+A* 0< -1d2 -1i1 x 1d1
+A* =< -1d2 1i1 x -1
+A* 0> -1d2 1i1 x -1d1
+A* =< -1i1 1d2 x -1
+A* 0> -1i1 1d2 x -1d1
+!! carry
+2* => 3d1 1d3 x 3d3
+2* 0< 3d1 1d3 x 3d4
+A* => -3d1 -1d3 x 3d3
+A* 0< -3d1 -1d3 x 3d4
+A* =< -3d1 1d3 x -3d3
+A* 0> -3d1 1d3 x -3d4
+A* =< -1d3 3d1 x -3d3
+A* 0> -1d3 3d1 x -3d4
+A* => 7mB0i1 4i1 x 7mB0p2i3
+A* 0< 7mB0i1 4i1 x 7mB0p2i2
+A* => -7mB0i1 -4i1 x 7mB0p2i3
+A* 0< -7mB0i1 -4i1 x 7mB0p2i2
+A* =< -7mB0i1 4i1 x -7mB0p2i3
+A* 0> -7mB0i1 4i1 x -7mB0p2i2
+A* =< -4i1 7mB0i1 x -7mB0p2i3
+A* 0> -4i1 7mB0i1 x -7mB0p2i2
+
+! Just below denormalization threshold.
+2* ALL Td1 2 OK Tp1d2
+!! 40000000000 00000000 000fffff ffffffff 001fffff ffffffe
+A* ALL -Td1 -2 OK Tp1d2
+2* ALL -Td1 2 OK -Tp1d2
+A* ALL -2 Td1 OK -Tp1d2
+2* ALL -2 Td3 OK -Tp1d6
+2* ALL -Td3 -2 OK Tp1d6
+2* ALL 2 -Td3 OK -Tp1d6
+A* ALL Td3 2 OK Tp1d6
+!! c0000000 00000000 800fffff fffffffd 001fffff fffffffa
+2* ALL Td4 2 OK Tp1d8
+!! 40000000000 00000000 000fffff fffffffc 001fffff ffffff8
+A* ALL -Td4 -2 OK Tp1d8
+2* ALL Td4 -2 OK -Tp1d8
+A* ALL 2 -Td4 OK -Tp1d8
+
+! Normalizing tinies.
+!! * 2
+2* ALL 0i1 2 OK 0i2
+!! 4000000000 00000000 00000000 00000001 00000000 00000002
+A* ALL -0i1 -2 OK 0i2
+A* ALL 0i1 -2 OK -0i2
+A* ALL 2 -0i1 OK -0i2
+A* ALL 0i2 2 OK 0i4
+A* ALL -0i2 -2 OK 0i4
+A* ALL 0i2 -2 OK -0i4
+A* ALL 2 -0i2 OK -0i4
+A* ALL 0i3 2 OK 0i6
+A* ALL -0i3 -2 OK 0i6
+A* ALL 0i3 -2 OK -0i6
+A* ALL 2 -0i3 OK -0i6
+!! * 3
+A* ALL 3 0i1 OK 0i3
+A* ALL -3 -0i1 OK 0i3
+A* ALL 3 -0i1 OK -0i3
+A* ALL 0i1 -3 OK -0i3
+2* ALL 3 0i2 OK 0i6
+A* ALL -3 -0i2 OK 0i6
+A* ALL 3 -0i2 OK -0i6
+A* ALL 0i2 -3 OK -0i6
+A* ALL 3 0i3 OK 0i9
+A* ALL -3 -0i3 OK 0i9
+A* ALL 3 -0i3 OK -0i9
+A* ALL 0i3 -3 OK -0i9
+!! * 4
+A* ALL 4 0i1 OK 0i4
+A* ALL 4 -0i1 OK -0i4
+A* ALL -4 -0i1 OK 0i4
+A* ALL -4 0i1 OK -0i4
+2* ALL 4 0i2 OK 0i8
+A* ALL 4 -0i2 OK -0i8
+A* ALL -4 -0i2 OK 0i8
+A* ALL -4 0i2 OK -0i8
+!! * 5
+A* ALL -0i1 -5 OK 0i5
+!! 40040000 00000000 00000000 00000001 00000000 00000002
+H* ALL 5 0i1 OK 0i5
+2* ALL -0i1 5 OK -0i5
+!! 40140000 00000000 80000000 00000001 80000000 00000005
+A* ALL 0i1 -5 OK -0i5
+!! * medium
+!! 00000000 00000001 43500000 00000000 00300000 00000000
+H* ALL 0i1 2pt OK Tp2
+H* ALL -0i1 -2pt OK Tp2
+H* ALL -0i1 2pt OK -Tp2
+H* ALL -2pt 0i1 OK -Tp2
+A* ALL 0i1 1ptm1 OK T
+A* ALL -0i1 -1ptm1 OK T
+A* ALL -0i1 1ptm1 OK -T
+A* ALL -1ptm1 0i1 OK -T
--- /dev/null
+/*
+##########################################################################
+# #
+# Program: IeeeCC754 #
+# #
+# Description: #
+# IeeeCC754 or IEEE 754 Compliance Checker is a precision and range #
+# independent tool to test whether an implementation of #
+# floating-point arithmetic (in hardware or software) is compliant #
+# with the principles of the IEEE 754-854 floating-point standards. #
+# You can find out more about the testing tool IeeeCC754 at #
+# #
+# http://win-www.uia.ac.be/u/cant/ieeecc754.html #
+# #
+# This tool is in parts based on and greatly benefited from the #
+# the program FPTEST developed by Jerome Coonen. For a full #
+# description of the extensions to FPTEST and a reference to #
+# the original Coonen program, please refer to the URL given above. #
+# For the options available with the program IeeeCC754 and its #
+# compatibility with David Hough's hexadecimal UCB format, we #
+# also refer to the file readme.usage. #
+# #
+# Usage: see readme.usage #
+# #
+# Responsible authors: #
+# Brigitte Verdonk #
+# Annie Cuyt #
+# #
+# Contributors: #
+# Johan Bogo (1998-1999) #
+# Tim Gevers (10-12/2000) #
+# Debby Ooms (1996-1997) #
+# Geert Vermuyten (1996-1997) #
+# Dennis Verschaeren (09/1996-06/2000) #
+# #
+# Copyright (C) 2000 University of Antwerp #
+# #
+# This program can be obtained from the authors, free, but WITHOUT ANY #
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or #
+# FITNESS FOR A PARTICULAR PURPOSE. #
+# #
+# Contact: #
+# Brigitte.Verdonk@uia.ua.ac.be #
+# Department of Mathematics and Computer Science #
+# University of Antwerp (UIA) #
+# Universiteitsplein 1 #
+# B2610 Antwerp, BELGIUM #
+# #
+##########################################################################
+
+Filename:
+ $RCSfile$
+
+Last updated:
+ $Date$
+
+*/
+
+/***************************************************************************
+* This is a class definition for bitstrings. The bitstring is a array of type
+* (class T). The use of templates is to specify the block size. Only use
+* unsigned types to define the class T, because else the shift operations
+* (especially right shift) won't work correct.
+************************************************************************** */
+
+#ifndef _BITSTRING_H
+#define _BITSTRING_H
+
+
+#include <math.h>
+#include <iostream.h>
+
+
+#define NO_ERR 500
+#define ERR_OUT_OF_BOUND 501
+
+
+
+/*class definition*/
+/**This class has been created to simplify the manipulation of bits over some array of integers (unsigned longs).
+The internal structure of the bitstring resembles a little endian structure,
+because this concept simplifies the resizing of the bitstring.
+\TEX{\begin{figure}[h]
+\begin{center}
+\includegraphics[totalheight=3cm]{InterneBitstr.eps}
+\caption{Internal structure of Bitstring}
+\end{center}
+\end{figure}}
+@author Bogo Johan*/
+
+
+
+class Bitstring
+{
+protected:
+ ///the bitstring
+ unsigned long * bitstr;
+ ///length of bitstring,
+ long length;
+ /// number of array elments
+ long lengthBlock;
+ ///number of bits in class T
+ long lengthT;
+
+
+ /// returns a unsigned long with the first res bits set.
+ unsigned long GetPattern(unsigned long rest);
+
+ /** returns the first block of bitstr. It's only defined
+ to be used in PutByte so the xor-operator would work
+ properly.*/
+ unsigned long Convert();
+
+public:
+ /// Constructor, creates an empty bitstring
+ Bitstring();
+ /**Constructor, creates a bitstring of size size.
+ @param size the default size*/
+ Bitstring(unsigned long size);
+ /**Constructor,initiate the bitstring with the str as input
+ @param str the default value for the bitstring */
+ Bitstring(char * str);
+ /// Copy constructor.
+ Bitstring(const Bitstring& copy);
+ ///Destructor
+ ~Bitstring();
+
+ /**Get the length of the bitstring.
+ @return length of the bitstring*/
+ virtual unsigned long Length() const;
+ /**Change the length of the bitstring to "len". If "len" is
+ larger then the length, the bitstring is appended with 0, else
+ the bitstring is truncated to the new length "len"
+ @param len the new length of the bitstring
+ @return previous length
+ */
+ virtual unsigned long Resize(unsigned long len);
+
+ /**Get the bit value at position "bit"
+ @param bit position of the bit
+ @return the bit value \\ \begin{tabular}{rcl} 0 <= "bit" < length &->& The bit value\\
+ else & -> &0\end{tabular} */
+ int GetBit(long bit) const;
+
+ /**Replace the bit value at position "bit" with the new "bitvalue"
+ @param bit posisition of the bit
+ @param bitvalue new value
+ @return Previous bit value*/
+ int PutBit(unsigned long bit,unsigned int bitvalue);
+
+ /* Replace the bit value at position "bit" with the 1
+ @param bit position of the bit
+ @return Previous bit value*/
+ int Set(long bit);
+
+ /** Replace the bit value at position "bit" with the 0
+ @param bit position of the bit
+ @return Previous bit value */
+ int Clear(long bit);
+
+ /** Clears the bitstring
+ @return Cleared bitstring */
+ Bitstring ClearBitString();
+
+ /**Get the byte value at position "byte"
+ @param byte position of the byte
+ @return The byte value */
+ void GetByte(unsigned long byte,Bitstring sub) const;
+
+ /** Replace the byte value at position "byte" with the new "bytevalue"
+ @param byte position of the byte
+ @param bytevalue new value
+ @return: void // Previous byte value */
+ void PutByte(unsigned long byte,Bitstring bytevalue);
+
+
+ /** Increase the bitstring value by 1
+ @return Carry after most significant bit*/
+ int Inc();
+
+ /** Decrease the bitstring value by 1
+ @return \begin{tabular}{rcl} 1& -> &wrap around (negative)\\
+ 0& -> &OK \end{tabular} */
+ int Dec();
+
+ /**Converts a bitstring to a C-string
+ @return the converted bitstring\\ \begin{tabular}{ccl} length >0 & -> & The C-string\\
+ else & -> & "Bitstring is empty" \end{tabular}*/
+ virtual void BitstrToString(char str[256]) const;
+
+ /** Converts a C-string to a bitstring
+ @param str the C-string to be converted
+ @return converted bitstring */
+ virtual void StringToBitstr(char *str);
+
+ /** Puts bitstring *this in front of b2 -> so the first bit of b2
+ becomes the first bit of *thisb2
+ @param b2 second bitstring
+ @return *this -> *thisb2 */
+ void Concat(const Bitstring &b2);
+
+ /* Returns the substring defined by position "begin" to "count"
+ @param begin the begining of the substring
+ @param count the length of the substring
+ @return substring from bitstring */
+ // Bitstring SubBitstring (unsigned long begin, unsigned long count) const;
+ void SubBitstring(unsigned long begin, Bitstring &sub) const;
+
+ /** Overloads the array operator. Returns/change block "n"
+ @param n block number
+ @return block "n" */
+ unsigned long& operator [](unsigned long n) const;
+
+ /**Overloads the assign operator. Makes the bistring equal to "copy"
+ @param copy the new bitstring
+ @return The changed bitstring */
+ Bitstring& operator = (const Bitstring ©);
+
+ /** Overloads the equal operator.
+ @param b second bitstring
+ @return \begin{tabular}{lcl} equal & -> &1\\
+ not equal &->& 0 \end{tabular}*/
+ int operator == (const Bitstring & b) const;
+
+ /** Overloads the not equal operator.
+ @return \begin{tabular}{lcl} not equal& ->& 1\\
+ equal & ->& 0 \end{tabular}*/
+ int operator != (const Bitstring &b) const;
+
+ /** Overloads the greater than operator.
+ @return \begin{tabular}{lcl} greater & ->& 1\\
+ not greater & ->& 0\end{tabular} */
+ int operator > (const Bitstring &b) const;
+
+ /** Overloads the smaller than operator.
+ @return \begin{tabular}{lcl} smaller& ->& 1\\
+ not smaller & ->& 0\end{tabular} */
+ int operator < (const Bitstring &b) const;
+
+
+ /**Overloads the shift left operator. Shifts the bitstring "count"
+ bits to the left
+ @param count number of shifts
+ @return shifted bitstring */
+ void operator <<(long count);
+
+ /**Overloads the shift right operator. Shifts the bitstring "count"
+ bits to the righ
+ @param count number of shifts
+ @return shifted bitstring */
+ void operator >>(unsigned long count );
+
+
+ /**Overloads the bitwise and operator. Does a bitwise and with
+ "bitstr" and "bitst". Makes the size of bitst equal to the
+ bitstring.
+ @param bitst second bitstring
+ @return bitwised and -> *this \& bitst */
+ Bitstring operator &( const Bitstring &bitst);
+
+ /** Overloads the bitwise or operator. Does a bitwise or with
+ "bitstr" and "bitst". Makes the size of bitst equal to the
+ bitstring.
+ @param bitst second bitstring
+ @return bitwised or -> *this $|$ bitst */
+ Bitstring operator |( const Bitstring &bitst);
+
+ /** Overloads the bitwise xor operator. Does a bitwise xor with
+ "bitstr" and "bitst". Makes the size of bitst equal to the
+ bitstring.
+ @param bitst second bitstring
+ @return bitwised xor -> *this \^\ bitst */
+ Bitstring operator ^( const Bitstring &bitst);
+
+ /** Overloads the bitwise not operator. Does a bitwise not with
+ "bitstr".
+ @return bitwised not -> \cxxtilde(*this) */
+ Bitstring operator ~();
+
+ /** Overloads the stream output operator. Converts the bitstring to a
+ C-string and returns it to "ostream".
+ @param outs the ouput stream
+ @param outstr the bitstring
+ @return outs -> converted bitstring*/
+ friend ostream& operator << (ostream& outs,const Bitstring &outstr);
+
+ /** Overloads the stream input operator. Converts the C-string to a
+ bitstring.
+ @param ins the input stream
+ @param instr the bitstring
+ @return ins */
+ friend istream& operator >> (istream& ins, Bitstring &instr);
+};
+
+//@Include: Hex.h
+
+#endif
--- /dev/null
+/*
+##########################################################################
+# #
+# Program: IeeeCC754 #
+# #
+# Description: #
+# IeeeCC754 or IEEE 754 Compliance Checker is a precision and range #
+# independent tool to test whether an implementation of #
+# floating-point arithmetic (in hardware or software) is compliant #
+# with the principles of the IEEE 754-854 floating-point standards. #
+# You can find out more about the testing tool IeeeCC754 at #
+# #
+# http://win-www.uia.ac.be/u/cant/ieeecc754.html #
+# #
+# This tool is in parts based on and greatly benefited from the #
+# the program FPTEST developed by Jerome Coonen. For a full #
+# description of the extensions to FPTEST and a reference to #
+# the original Coonen program, please refer to the URL given above. #
+# For the options available with the program IeeeCC754 and its #
+# compatibility with David Hough's hexadecimal UCB format, we #
+# also refer to the file readme.usage. #
+# #
+# Usage: see readme.usage #
+# #
+# Responsible authors: #
+# Brigitte Verdonk #
+# Annie Cuyt #
+# #
+# Contributors: #
+# Johan Bogo (1998-1999) #
+# Tim Gevers (10-12/2000) #
+# Debby Ooms (1996-1997) #
+# Geert Vermuyten (1996-1997) #
+# Dennis Verschaeren (09/1996-06/2000) #
+# #
+# Copyright (C) 2000 University of Antwerp #
+# #
+# This program can be obtained from the authors, free, but WITHOUT ANY #
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or #
+# FITNESS FOR A PARTICULAR PURPOSE. #
+# #
+# Contact: #
+# Brigitte.Verdonk@uia.ua.ac.be #
+# Department of Mathematics and Computer Science #
+# University of Antwerp (UIA) #
+# Universiteitsplein 1 #
+# B2610 Antwerp, BELGIUM #
+# #
+##########################################################################
+
+Filename:
+ $RCSfile$
+
+Last updated:
+ $Date$
+
+*/
+
+
+// MORE INFORMATION ON THE FUNCTIONS IN THIS HEADER FILE CAN BE FOUND
+// ON THE WEBPAGE
+// http://win-www.uia.ac.be/u/cant/ieeecc754.html
+// ``Adapt IeeeCC754 to test your floating-point implementation''
+
+// ----
+// Includes
+// ----
+
+#include <Fp.h>
+#include <Bitstring.h>
+
+// ----
+// Includes and Defines specificly for testing MpIeee
+// ----
+#ifdef MPIEEE_TEST
+#include <MpIeee.hh>
+#endif
+
+// ----
+// Includes and Defines specificly for testing FMLib
+// ----
+#ifdef FMLIB_TEST
+#include <Sdefs.h>
+#endif
+
+// ----
+// CLASS DEFINITION : DriverFloatRepr
+// ----
+
+
+class DriverFloatRepr: public FP
+{
+protected:
+
+void SetLibRound( );
+// call the appropriate functions to set the rounding mode
+// on the target platform - see item (a) on webpage
+
+void SetLibEnvironment( );
+// call the appropriate functions to clear all floating-point
+// exceptions on the target platform - see item (b) on webpage
+
+void GetLibExceptions( );
+// call the appropriate functions to read out exceptions generated
+// by the target platform - see item (b) on webpage
+
+public:
+
+#ifndef FMLIB_TEST
+// For testing FMLib we use other definitions
+// --
+DriverFloatRepr::DriverFloatRepr( ) :FP( )
+ {}
+
+DriverFloatRepr::DriverFloatRepr( int m,int e,int h ) :FP( m,e,h )
+ {}
+
+DriverFloatRepr::DriverFloatRepr( Bitstring &fp,int m,int e,int h ) :FP( fp,m,e,h )
+ {}
+ ;
+#endif
+
+// If your target implementation is implemented in hardware,
+// provide an implementation of the functions listed below for
+// conversion between your hardware data types and DriverFloatRepr
+// see item (c) on webpage and
+// ftp://win-ftp.uia.ac.be/pub/cant/IeeeCC754/converting.pdf
+
+DriverFloatRepr( float f );
+DriverFloatRepr( double d );
+DriverFloatRepr( long double l );
+float tofloat( );
+double todouble( );
+long double tolongdouble( );
+
+
+// If your target implementation is implemented in software,
+// provide an implementation of the functions listed below for
+// conversion between your floating-point datatype and
+// DriverFloatRepr (don't forget to replace MyDatatype by the
+// appropriate identifier in this declaration) - see item (c) on
+// webpage and
+// ftp://win-ftp.uia.ac.be/pub/cant/IeeeCC754/converting.pdf
+
+DriverFloatRepr (void *val);
+void* to(void *val);
+
+
+
+//
+// Here is an example to test the multiprecision floating-point
+// implementation MpIeee:
+
+#ifdef MPIEEE_TEST
+// Functions that Convert MpIeee to DriverFloatRepr and vice-versa
+//--
+
+DriverFloatRepr ( const MpIeee &M );
+MpIeee to( );
+
+#endif
+
+#ifdef FMLIB_TEST
+// Functions specifically for Testing FMLib
+// --
+
+DriverFloatRepr::DriverFloatRepr( );
+DriverFloatRepr::DriverFloatRepr( int m,int e,int h );
+DriverFloatRepr::DriverFloatRepr( Bitstring &fp,int m,int e,int h );
+DriverFloatRepr::DriverFloatRepr( DriverFloatRepr& );
+void DriverFloatRepr::fromDriverFloatRepr( Bitstring& m,Bitstring& e,int h );
+void DriverFloatRepr::toDriverFloatRepr( Bitstring m,Bitstring e,int h, int signf );
+FmNumber value;
+long Length;
+char* byteToStr( long );
+void Reverse( Bitstring& );
+void SetOperations( );
+
+#endif
+
+// provide implementaton of the functions listed below in the file
+// BasicOperations/$PLATFORM/BasicOperationstest.cc
+// see item (d) on webpage
+// --
+
+DriverFloatRepr operator + ( DriverFloatRepr &T );
+DriverFloatRepr operator - ( DriverFloatRepr &T );
+DriverFloatRepr operator * ( DriverFloatRepr &T );
+DriverFloatRepr operator / ( DriverFloatRepr &T );
+DriverFloatRepr operator % ( DriverFloatRepr &T );
+DriverFloatRepr sqrt( );
+
+// provide implementation of the functions listed below in the file
+// Conversions/$PLATFORM/Conversionstest.cc
+// see item (d) on webpage
+// --
+
+DriverFloatRepr roundto ( int, int, int );
+DriverFloatRepr copyto ( int, int, int );
+DriverFloatRepr rint ( );
+DriverFloatRepr ri ( ) ;
+DriverFloatRepr ru ( ) ;
+DriverFloatRepr rI ( ) ;
+DriverFloatRepr rU ( ) ;
+DriverFloatRepr ci ( int, int, int );
+DriverFloatRepr cu ( int, int, int );
+DriverFloatRepr cI ( int, int, int );
+DriverFloatRepr cU ( int, int, int );
+DriverFloatRepr b2d ( int );
+DriverFloatRepr d2b ( );
+
+// conversions between DriverFloatRepr and hardware integer
+// data types; implementation is provided in the files
+// BasicOperations/$PLATFORM/fpenv_$PLATFORM.cc
+// and
+// Conversions/$PLATFORM/fpenv_$PLATFORM.cc
+// and should not be modified
+// --
+
+DriverFloatRepr( long i );
+DriverFloatRepr( unsigned long i );
+DriverFloatRepr( long long int i );
+DriverFloatRepr( unsigned long long int i );
+int toint( );
+unsigned int touint( );
+long long int tolonglong( );
+unsigned long long int toulonglong( );
+
+};
--- /dev/null
+/*
+##########################################################################
+# #
+# Program: IeeeCC754 #
+# #
+# Description: #
+# IeeeCC754 or IEEE 754 Compliance Checker is a precision and range #
+# independent tool to test whether an implementation of #
+# floating-point arithmetic (in hardware or software) is compliant #
+# with the principles of the IEEE 754-854 floating-point standards. #
+# You can find out more about the testing tool IeeeCC754 at #
+# #
+# http://win-www.uia.ac.be/u/cant/ieeecc754.html #
+# #
+# This tool is in parts based on and greatly benefited from the #
+# the program FPTEST developed by Jerome Coonen. For a full #
+# description of the extensions to FPTEST and a reference to #
+# the original Coonen program, please refer to the URL given above. #
+# For the options available with the program IeeeCC754 and its #
+# compatibility with David Hough's hexadecimal UCB format, we #
+# also refer to the file readme.usage. #
+# #
+# Usage: see readme.usage #
+# #
+# Responsible authors: #
+# Brigitte Verdonk #
+# Annie Cuyt #
+# #
+# Contributors: #
+# Johan Bogo (1998-1999) #
+# Tim Gevers (10-12/2000) #
+# Debby Ooms (1996-1997) #
+# Geert Vermuyten (1996-1997) #
+# Dennis Verschaeren (09/1996-06/2000) #
+# #
+# Copyright (C) 2000 University of Antwerp #
+# #
+# This program can be obtained from the authors, free, but WITHOUT ANY #
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or #
+# FITNESS FOR A PARTICULAR PURPOSE. #
+# #
+# Contact: #
+# Brigitte.Verdonk@uia.ua.ac.be #
+# Department of Mathematics and Computer Science #
+# University of Antwerp (UIA) #
+# Universiteitsplein 1 #
+# B2610 Antwerp, BELGIUM #
+# #
+##########################################################################
+
+Filename:
+ $RCSfile$
+
+Last updated:
+ $Date$
+
+*/
+
+/***************************************************************************
+* This is a class definition for floating point numbers (IEEE 754).
+* It uses the bitstring class for storing the exponent and the mantissa.
+************************************************************************** */
+
+#ifndef _FP_H
+#define _FP_H
+#include <stdio.h>
+
+#include <Bitstring.h>
+#include <Hex.h>
+
+#define RM_NEAR 0
+#define RM_UP 2
+#define RM_DOWN 1
+#define RM_ZERO 3
+
+
+#define NOT_KNOWN 100
+
+#ifndef MYBIG_ENDIAN
+ #define MYBIG_ENDIAN 101
+#endif
+
+#ifndef MYLITTLE_ENDIAN
+ #define MYLITTLE_ENDIAN 102
+#endif
+
+#define maxstr 5000
+// maximum chars for binary to decimal conversion
+
+/**This is an abstract class defining floating-points as described in the IEEE 754 standard. It uses the Bitstring class to represent the mantissa and exponent
+separately. The hidden bit is always present in the mantissa and needs to be defined for input and output in a hexadecimal form.\\
+\\
+There are three functions that need to be overloaded: SetRound(), GetExceptions(), SetEnvironment(). The first one must set the rounding mode of the library,
+according to the rounding mode stored in the environment \textit{fpEnv}. This
+can be done by calling the function GetFPRound() which returns the value actual rounding mode. GetExceptions() needs to convert the exceptions stored in the
+testing library to the exceptions located in the environment \textit{fpEnv}.
+To set the exceptions in the environment the functions: SetFPDivByZero(), SetFPInvalid(), SetFPUnderflow(), SetFPOverflow(), SetFPInexact() can be used.
+The last function SetEnvironment() must set the library default environment.
+
+
+@author Bogo Johan*/
+
+class FP
+{
+
+protected:
+ ///Little or Big Endian
+ static int Endian;
+
+ /**The representation of a floating-point environment. \\
+ Bit positions and values: \begin{itemize}
+ \item 0: divide by zero
+ \item 1: invalid
+ \item 2: underflow
+ \item 3: overflow
+ \item 4: inexact
+ \item 21 - 22 : rounding mode
+ \begin{itemize}
+ \item 00: round to nearest
+ \item 01: round up
+ \item 10: round down
+ \item 11: round to zero
+ \end{itemize}
+ \end{itemize} */
+ static Bitstring fpEnv;
+
+ ///The sign of the floating-point number
+ int sign;
+ ///Hidden bit (yes/no)
+ int hidden;
+ ///The size of the mantissa
+ int sizeMant;
+ ///The mantissa
+ Bitstring mant;
+ ///The exponent
+ Bitstring exp;
+
+
+ /**Checks if the hardware is big or little endian. This function is only
+ needed to correctly convert a FP to a hardware floating-point*/
+ static void CheckEndian();
+
+ /**Set the library rounding mode. This member function needs to be
+ overloaded when testing a floating-point implementation. The tester should
+ call his library function(s) to set the rounding mode corresponding the
+ one saved in fpEnv.*/
+ void SetLibRound(){};
+ /**Get library exceptions. This member functions needs to be overloaded
+ when testing a floating-point implementation. The tester should call his
+ function(s) to get the occured exceptions in his library and set them in
+ the fpEnv with SetFPDivByZero(), SetFPInvalid(),...*/
+ void GetLibExceptions(){};
+ /**Get FP rounding mode stored in fpEnv
+ @return the rounding mode \\ \begin{tabular}{ccl} 0 &:& round to nearest $(RM\_NEAR)$ \\
+ 1 &:& round up (RM\_UP) \\
+ 2 &:& round down $(RM\_DOWN)$ \\
+ 3 &:& round to zero $(RM\_ZERO)$
+ \end{tabular}
+ */
+ int GetFPRound();
+
+ ///Sets the divide by zero exception in fpEnv
+ void SetFPDivByZero(){fpEnv.Set(0);}
+ ///Sets the invalid exception in fpEnv
+ void SetFPInvalid() {fpEnv.Set(1);}
+ ///Sets the underflow exception in fpEnv
+ void SetFPUnderflow(){fpEnv.Set(2);}
+ ///Sets the overflow exception in fpEnv
+ void SetFPOverflow() {fpEnv.Set(3);}
+ ///Sets the inexact exception in fpEnv
+ void SetFPInexact() {fpEnv.Set(4);}
+
+
+
+public:
+
+ ///The size of the exponent
+ int sizeExp;
+ ///decimal
+ char *decimal; // binary to decimal conversion
+
+ ///Constructor
+ FP();
+ /**Constructor setting the size of the exponent, the mantissa and the
+ hidden bit
+ @param sizeM the size of the mantissa
+ @param sizeE the size of the exponent
+ @param hiddenbit if there is a hidden bit (0: false / 1: true)*/
+ FP(int sizeM, int sizeE,int hiddenbit=0);
+ /**Constructor setting the size of the exponent,the mantissa and the
+ hidden bit. It initializes the floating-point number with a bitstring.
+ The bitstring must have the following form (sign exp (h) mant)
+ @param fp a bitstring containing the hardware reprecentation
+ of a floating-point
+ @param sizeM the size of the mantissa
+ @param sizeE the size of the exponent
+ @param hiddenbit if there is a hidden bit (0: false / 1: true) */
+ FP(Bitstring &fp,int sizeM, int sizeE,int hiddenbit=0);
+ /**Copy constructor
+ @param copy an other FP object*/
+ FP(FP & copy);
+
+ //Destructor
+ virtual~FP(){};
+
+ ///returns true (1) if there is a hidden bit
+ int Hidden(){return hidden;};
+ /**returns or sets the sign
+ @param sgn the new sign \\ \begin{tabular}{rcl} 1 &:& negative \\
+ 0 &:& positive \\
+ -1 &:& no change
+ \end{tabular}
+ @return the current sign or the previous depending \it{sgn}
+ */
+ int Sign(int sgn=-1);
+
+ /**Returns the mantissa
+ @return the mantissa hidden bit included (if defined)*/
+ Bitstring & GetMantissa();
+ /**Returns the exponent
+ @return the exponent*/
+ Bitstring & GetExponent();
+ /**Sets the mantissa
+ @param mantissa the new mantissa including the hidden bit (if defined)
+ @return the previous mantissa*/
+ Bitstring PutMantissa(Bitstring &mantissa);
+ /**Sets the exponent
+ @param exponent the new exponent.
+ @return the previous exponent.*/
+ Bitstring PutExponent(Bitstring &exponent);
+
+ /**Checks if the floating-point is a Zero
+ @return \begin{tabular}{rcl} 1 &:& is a Zero\\
+ 0 &:& is not a Zero
+ \end{tabular}*/
+ int IsZero();
+
+ /**Checks if the floating-point is a negative Zero
+ @return \begin{tabular}{rcl} 1 &:& is a neg Zero\\
+ 0 &:& is not a neg Zero
+ \end{tabular}*/
+ int IsNegZero();
+
+ /**Checks if the floating-point is a NaN
+ @return \begin{tabular}{rcl} 1 &:& is a NaN \\
+ 0 &:& is not a NaN
+ \end{tabular}*/
+ int IsNaN();
+ /**Creates a quiet NaN */
+ void CreateQFPNan();
+
+ /**Assignment operator
+ @param copy an other FP object to be copied
+ @return *this*/
+ FP& operator = (const FP ©);
+ /**Assignment operator
+ @param copy an Bitstring object to be converted to a FP object
+ @return *this*/
+ FP& operator = (const Bitstring ©);
+
+ /**Set the default library environment rounding mode. This member function
+ needs to be overloaded when testing a floating-point implementation. The
+ tester should call his library function(s) to set the default library
+ environment. Normaly this means to clear the exception flags and restoring
+ the rounding mode to round to nearest.*/
+ void SetLibEnvironment(){};
+
+ /** Sets the rounding mode in the fpEnv to rm
+ @param rm next values a defined \\ \begin{tabular}{rcl} 0 &:& round to nearest $(RM\_NEAR)$ \\
+ 1 &:& round up (RM\_UP) \\
+ 2 &:& round down $(RM\_DOWN)$ \\
+ 3 &:& round to zero $(RM\_ZERO)$
+ \end{tabular}
+ */
+ void SetFPRound (int rm);
+ ///Clears the environment (fpEnv)
+ void ClearFPEnvironment();
+ /**Returns the exceptions stored in fpEnv as a Bitstring
+ @return a Bitstring with next bit positions set, depending the exception \\\begin{tabular}{rcl}
+ 0 &:& divide by zero\\
+ 1 &:& invalid\\
+ 2 &:& underflow\\
+ 3 &:& overflow\\
+ 4 &:& inexact
+ \end{tabular} */
+ void GetFPExceptions(Bitstring);
+
+
+ /**Chekcs if there has occured a divide by zero exception
+ @return\begin{tabular}{rcl} 1 &:& divide by zero exception\\
+ 0 &:& no divide by zero exception
+ \end{tabular}*/
+ int GetFPDivByZero(){return fpEnv.GetBit(0);}
+ /**chekcs if there has occured a invalid exception
+ @return\begin{tabular}{rcl} 1 &:& invalid exception \\
+ 0 &:& no invalid exception
+ \end{tabular}*/
+ int GetFPInvalid() {//cout << "fpEnv.GetBit(1)" << fpEnv.GetBit(1);
+ return fpEnv.GetBit(1);}
+ /**chekcs if there has occured a underflow exception
+ @return\begin{tabular}{rcl} 1 &:& underflow exception \\
+ 0 &:& no underflow exception
+ \end{tabular}*/
+ int GetFPUnderflow(){return fpEnv.GetBit(2);}
+ /**chekcs if there has occured a overflow exception
+ @return\begin{tabular}{rcl} 1 &:& overflow exception \\
+ 0 &:& no overflow exception
+ \end{tabular}*/
+ int GetFPOverflow() {return fpEnv.GetBit(3);}
+ /**chekcs if there has occured a inexact exception
+ @return\begin{tabular}{rcl} 1 &:& inexact exception \\
+ 0 &:& no inexact exception
+ \end{tabular}*/
+ int GetFPInexact() {return fpEnv.GetBit(4);}
+ int istiny();
+ int isInf();
+ int isNan();
+
+ ///Overloaded output operator
+ friend ostream& operator << (ostream& outs, FP &outstr);
+
+ friend istream& operator >> (istream& ins, FP &instr);
+
+};
+
+//@Include: MyFloat.h MyDouble.h MyQuad.h FpSim.h Bitstring.h UCB.h dlist.h stack.h ../Calculator/FPcalculator.h
+
+#endif
--- /dev/null
+/*
+##########################################################################
+# #
+# Program: IeeeCC754 #
+# #
+# Description: #
+# IeeeCC754 or IEEE 754 Compliance Checker is a precision and range #
+# independent tool to test whether an implementation of #
+# floating-point arithmetic (in hardware or software) is compliant #
+# with the principles of the IEEE 754-854 floating-point standards. #
+# You can find out more about the testing tool IeeeCC754 at #
+# #
+# http://win-www.uia.ac.be/u/cant/ieeecc754.html #
+# #
+# This tool is in parts based on and greatly benefited from the #
+# the program FPTEST developed by Jerome Coonen. For a full #
+# description of the extensions to FPTEST and a reference to #
+# the original Coonen program, please refer to the URL given above. #
+# For the options available with the program IeeeCC754 and its #
+# compatibility with David Hough's hexadecimal UCB format, we #
+# also refer to the file readme.usage. #
+# #
+# Usage: see readme.usage #
+# #
+# Responsible authors: #
+# Brigitte Verdonk #
+# Annie Cuyt #
+# #
+# Contributors: #
+# Johan Bogo (1998-1999) #
+# Tim Gevers (10-12/2000) #
+# Debby Ooms (1996-1997) #
+# Geert Vermuyten (1996-1997) #
+# Dennis Verschaeren (09/1996-06/2000) #
+# #
+# Copyright (C) 2000 University of Antwerp #
+# #
+# This program can be obtained from the authors, free, but WITHOUT ANY #
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or #
+# FITNESS FOR A PARTICULAR PURPOSE. #
+# #
+# Contact: #
+# Brigitte.Verdonk@uia.ua.ac.be #
+# Department of Mathematics and Computer Science #
+# University of Antwerp (UIA) #
+# Universiteitsplein 1 #
+# B2610 Antwerp, BELGIUM #
+# #
+##########################################################################
+
+Filename:
+ $RCSfile$
+
+Last updated:
+ $Date$
+
+*/
+
+/***************************************************************************
+* This is a class definition for hexadecimal input of the bitstrings class.
+* Hex is inherited from bitstring, so there are no data members necessery.
+* The only thing that has to be done is to define the functions that change
+* in behaviour.
+************************************************************************** */
+#ifndef _HEXSTR_H
+#define _HEXSTR_H
+
+
+#include <iostream.h>
+#include <Bitstring.h>
+
+/*class definition*/
+
+/**
+ This class manipulates the Bitstring class as a hexadecimal string of bits.
+ The only difference in the
+ hexadecimal representation is the length of the string, as it
+ is four times smaller than the binary representation.
+
+ All the members are defined in the class Bitstring, therefore there are no
+ extra data members in this class.
+
+ @author Bogo Johan
+ */
+
+class Hex : public Bitstring
+{
+
+protected:
+ /** returns the binairy value of character v
+ @param v: character between 0-9 and A-F or a-F
+ @return: the binary value of v*/
+ void GetBin(char v);
+
+ /** returns the character value of the Bitstring b
+ @param b: binary value, from 0000-1111
+ @return: the character value of b*/
+ char GetHex(Bitstring& b) const;
+
+
+public:
+ /// Constructor, creates empty Bitstring
+ Hex();
+
+ /** Constructor
+ @param size: specifies the initial size of the bitstring.
+ The size is multiplied by 4 for a bistring.*/
+ Hex(unsigned long size);
+
+ /**Constructor, initiates the object with str
+ @param hstr: the hexadecimal number in a string-format */
+ Hex(char *hstr);
+
+ /**Copy constructor
+ @param copy a Bitstring object */
+ Hex(const Bitstring ©);
+
+ ///Deconstructor
+ ~Hex(){};
+
+
+ /** Get the length of the bitstring
+ @return: the length of the bitstring divided by 4*/
+ unsigned long Length() const {return length/4;};
+
+ /** changes the length of the bitstring to \textit{len} *4.
+ If the new length is larger then before, the bitstring
+ is appended with 0, else the bitstring is truncated to
+ the new length.
+ @param len the new length of the Bitstring
+ @return the previous length.
+ */
+ unsigned long Resize(unsigned long len);
+
+ /**converts the Bitstring to a C-string.
+ @return the converted Bitstring*/
+ void BitstrToString(char* out) const;
+
+ /**converts a C-string to a bitstring.
+ @param hstr a C-string to be converted
+ @return the HexString*/
+ void StringToBitstr(char *hstr);
+
+};
+
+#endif
--- /dev/null
+/*
+##########################################################################
+# #
+# Program: IeeeCC754 #
+# #
+# Description: #
+# IeeeCC754 or IEEE 754 Compliance Checker is a precision and range #
+# independent tool to test whether an implementation of #
+# floating-point arithmetic (in hardware or software) is compliant #
+# with the principles of the IEEE 754-854 floating-point standards. #
+# You can find out more about the testing tool IeeeCC754 at #
+# #
+# http://win-www.uia.ac.be/u/cant/ieeecc754.html #
+# #
+# This tool is in parts based on and greatly benefited from the #
+# the program FPTEST developed by Jerome Coonen. For a full #
+# description of the extensions to FPTEST and a reference to #
+# the original Coonen program, please refer to the URL given above. #
+# For the options available with the program IeeeCC754 and its #
+# compatibility with David Hough's hexadecimal UCB format, we #
+# also refer to the file readme.usage. #
+# #
+# Usage: see readme.usage #
+# #
+# Responsible authors: #
+# Brigitte Verdonk #
+# Annie Cuyt #
+# #
+# Contributors: #
+# Tarun Agarwal (05-07/2002) #
+# Johan Bogo (1998-1999) #
+# Tim Gevers (10-12/2000) #
+# Debby Ooms (1996-1997) #
+# Geert Vermuyten (1996-1997) #
+# Dennis Verschaeren (09/1996-06/2000) #
+# #
+# Copyright (C) 2000 University of Antwerp #
+# #
+# This program can be obtained from the authors, free, but WITHOUT ANY #
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or #
+# FITNESS FOR A PARTICULAR PURPOSE. #
+# #
+# Contact: #
+# Brigitte.Verdonk@uia.ua.ac.be #
+# Department of Mathematics and Computer Science #
+# University of Antwerp (UIA) #
+# Universiteitsplein 1 #
+# B2610 Antwerp, BELGIUM #
+# #
+##########################################################################
+
+Filename:
+ $RCSfile$
+
+Last updated:
+ $Date$
+
+*/
+
+#ifndef _UCB_H
+#define _UCB_H
+
+// ----
+// Includes
+// ----
+#include <string.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <fstream.h>
+#include <Fp.h>
+
+// ----
+// Defines
+// ----
+#define BUF_LEN 1024
+#define FP_STR 256
+
+#define NO_FLAGS_INEXACT 16
+#define NO_FLAGS_OVERFLOW 8
+#define NO_FLAGS_UNDERFLOW 4
+#define NO_FLAGS_INVALID 2
+#define NO_FLAGS_DIV_BY_ZERO 1
+
+extern int ieee;
+
+template<class T> class UCB
+{
+
+protected:
+
+ fstream infile, outfile,logfile;
+ char dest[ BUF_LEN ];
+ strstream logstream;
+
+ int line,sizeE,sizeM,hidden,dsizeE,dsizeM,dhidden,noFlags,signedZero,ieeeVector;
+ char operation[ 10 ],prec,rounding,compare[ 5 ],exceptions[ 10 ];
+ T operand1,operand2,result;
+ int pre, post; // to accomodate '?'
+ unsigned int errors,warnings,skipped;
+
+ void PrintError( T &res );
+
+public:
+
+ int signalu,notsignalu,signalv,signalw,notsignalv,notsignalw,nou,nov,now,allops;
+
+ UCB( );
+ ~UCB( );
+
+ void SetFPRound ( );
+
+ int OpenInput( char* filename );
+ int OpenOutput( char* filename );
+ int OpenLogFile( char* filename,int argc,char **argv );
+ int ReadLine( char* str=NULL,int sZero=1, int nflags=0,int *lines=NULL );
+
+ char* GetOperation( );
+ char GetPrecision( );
+ char GetRounding( );
+ char* GetCompare( );
+ char* GetExceptions( );
+ T & GetOperand1( );
+ T & GetOperand2( );
+ T & GetResult( );
+
+ char* DoLine( int tiny,int inf, int nan);
+ void Compare ( T &reslt );
+ void Close( int tiny );
+};
+
+
+template <class T>
+UCB<T>::UCB( )
+{
+ line = 0;
+ // result.SetEnvironment(); change BV
+ signalu = 0;
+ signalv = 0;
+ signalw = 0;
+ notsignalu = 0;
+ notsignalv = 0;
+ notsignalw = 0;
+ nou= 1;
+ nov = 1;
+ now = 1;
+ pre = post = 0;
+ errors = 0;
+ warnings = 0;
+ skipped = 0;
+ allops = 0;
+}
+
+template <class T>
+UCB<T>::~UCB( )
+{}
+
+
+template <class T>
+int UCB<T>::OpenInput( char* filename )
+{
+ infile.open( filename,ios::in );
+ if ( infile.good( ) )
+ return 1;
+
+ return 0;
+}
+
+template <class T>
+void UCB<T>::Close( int tiny )
+{
+ logfile << "Summary: " << endl;
+ logfile << "-------- " << endl;
+
+ if ( tiny ) { // conclusion underflow
+ if ( ucb.nou ) {
+ if ( ucb.nov ) {
+ if ( !( ucb.now ) )
+ logfile << "Warning: only 'w' underflow cases in the testset" << endl;
+ } else
+ if ( ucb.now )
+ logfile << "Warning: only 'v' underflow cases in the testset" << endl;
+ else
+ logfile << "Warning: only 'v' and 'w' underflow cases in the testset" << endl;
+ } // if
+ else {
+ if ( ucb.nov ) {
+ if ( ucb.now ) {
+ logfile << "Warning: no special 'v' or 'w' underflow cases in the testset" << endl;
+ if ( ucb.signalu && !ucb.notsignalu )
+ logfile << "Implementation signals underflow in case the result" << endl << "(1) is tiny after rounding and" << endl << "(2) suffers denormalization loss" << endl << "('u' - underflow)" << endl;
+ } else
+ logfile << "Warning: no special 'v' underflow cases in the testset" << endl;
+ } else {
+ if ( ucb.now ) {
+ logfile << "Warning: no special 'w' underflow cases in the testset" << endl;
+ if ( ( ucb.signalu && !ucb.notsignalu ) && ( ucb.signalv && !ucb.notsignalv ) )
+ logfile << "Implementation signals underflow in case the result" << endl << "(1) is tiny after rounding and" << endl << "(2) raises the inexact exception" << endl << "('v' - underflow)" << endl;
+ } else if ( ucb.signalu && !ucb.notsignalu ) {
+ if ( ucb.signalw && !ucb.notsignalw )
+ logfile << "Implementation signals underflow in case the result" << endl << "(1) is tiny before rounding and" << endl << "(2) raises the inexact exception" << endl << "('w' - underflow)" << endl;
+ else if ( ucb.signalv && !ucb.notsignalv )
+ logfile << "Implementation signals underflow in case the result" << endl << "(1) is tiny after rounding and" << endl << "(2) raises the inexact exception"<< endl << "('v' - underflow)" << endl;
+ else
+ logfile << "Implementation signals underflow in case the result" << endl << "(1) is tiny after rounding and" << endl << "(2) suffers denormalization loss" << endl << "('u' - underflow)" << endl;
+ } // else
+ } // else
+ } // else
+ } // if tiny
+
+ logfile << "Errors: " << errors << "/" << allops << endl;
+ logfile << "Warnings: " << warnings << "/" << allops << endl;
+ logfile << "Skipped: " << skipped << "/" << allops << endl;
+}
+
+template <class T>
+int UCB<T>::OpenOutput( char* filename )
+{
+ outfile.open( filename,ios::out );
+ if ( outfile.good( ) )
+ return 1;
+
+ return 0;
+}
+
+template <class T>
+int UCB<T>::OpenLogFile( char* filename,int argc, char **argv )
+{
+ logfile.open( filename,ios::out );
+ if ( logfile.good( ) ) {
+ logfile << "Testrun: ";
+ for ( int i = 0; i < argc;i++ )
+ logfile << argv[ i ] << " ";
+ logfile << endl << endl << flush;
+ return 1;
+ }
+
+ return 0;
+}
+
+template <class T>
+int UCB<T>::ReadLine( char* str,int sZero,int nflags,int *lines )
+{
+ int i,j,k,gotInput=0,count;
+ Hex tmphex,tmphex2;
+ Bitstring tmpbitstring,tmpbitstring2;
+ char buf[ BUF_LEN ],tmp[ FP_STR ];
+ line++;
+ signedZero=sZero;
+
+ pre = post = 0;
+ if( !str ) {
+ if ( !infile.eof( ) ) {
+ infile.getline( buf,BUF_LEN );
+ if( strlen( buf ) !=0 )
+ gotInput=1;
+ }
+
+ if( nflags )
+ noFlags = nflags;
+ } else {
+ strncpy( buf,str,strlen( str ) );
+ gotInput=1;
+ line=*lines;
+ noFlags=nflags;
+ }
+
+
+ if( gotInput ) {
+ i=0;
+ while ( buf[ i ] != ' ' ) {
+ operation[ i ] =buf[ i ];
+ i++;
+ }
+
+ operation[ i ] ='\0';
+
+ if ( !isdigit( operation[ strlen( operation ) -1 ] ) ) {
+ prec= operation[ strlen( operation ) -1 ];
+ operation[ strlen( operation ) -1 ] ='\0';
+ switch ( prec ) {
+ case 's':
+ sizeE=8;
+ sizeM=23+1;
+ hidden=1;
+ ieeeVector=0;
+ break;
+ case 'S':
+ sizeE=8;
+ sizeM=23+1;
+ hidden=1;
+ ieeeVector=1;
+ break;
+ case 'd':
+ sizeE=11;
+ sizeM=52+1;
+ hidden=1;
+ ieeeVector=0;
+ break;
+ case 'D':
+ sizeE=11;
+ sizeM=52+1;
+ hidden=1;
+ ieeeVector=1;
+ break;
+ case 'l':
+ sizeE=15;
+ sizeM=64 + 1;
+ hidden=0;
+ ieeeVector=0;
+ break;
+ case 'L':
+ sizeE=15;
+ sizeM=64 + 1;
+ hidden=0;
+ ieeeVector=1;
+ break;
+ case 'q':
+ sizeE=15;
+ sizeM=112+1;
+ hidden=1;
+ ieeeVector=0;
+ break;
+ case 'Q':
+ sizeE=15;
+ sizeM=112+1;
+ hidden=1;
+ ieeeVector=1;
+ break;
+ case 'm':
+ sizeE=15;
+ sizeM=240 + 1;
+ hidden = 0;
+ ieeeVector=0;
+ break;
+ case 'M':
+ sizeE=15;
+ sizeM=240 + 1;
+ hidden = 0;
+ ieeeVector=1;
+ break;
+ }
+ } else {
+
+ ieeeVector=0; // Cannot be ieeeVector!
+
+ i--;
+
+ while ( isdigit( buf[ i ] ) ) i--; // rewind
+
+ i++;
+ operation[ i ] = '\0'; // ignore digit after operation
+ j = 0;
+
+ while ( buf[ i ] != ' ' )
+ tmp[ j++ ] =buf[ i++ ];
+
+ tmp[ j ] ='\0';
+ sizeE = atoi( tmp );
+
+ while ( buf[ ++i ] == ' ' );
+
+ j = 0;
+
+ while ( buf[ i ] != ' ' )
+ tmp[ j++ ] =buf[ i++ ];
+
+ tmp[ j ] ='\0';
+ hidden = atoi( tmp );
+
+ while ( buf[ ++i ] == ' ' );
+
+ j = 0;
+
+ while ( buf[ i ] != ' ' )
+ tmp[ j++ ] =buf[ i++ ];
+
+ tmp[ j ] ='\0';
+ sizeM = atoi( tmp );
+ sizeM++ ; // +1 for the sign
+ }
+
+ while ( buf[ i ] == ' ' ) i++;
+
+ // read destination format
+ if ( ( strncmp( operation,"rt",2 ) == 0 ) || ( strncmp( operation,"ct",2 ) == 0 ) ) {
+ if ( !isdigit( buf[ i ] ) ) {
+ prec = buf[ i ];
+ switch ( prec ) {
+ case 's':
+ dsizeE=8;
+ dsizeM=23+1;
+ dhidden=1;
+ break;
+ case 'd':
+ dsizeE=11;
+ dsizeM=52+1;
+ dhidden=1;
+ break;
+ case 'l':
+ dsizeE=15;
+ dsizeM=64 + 1;
+ dhidden=0;
+ // cout << 'l' << endl;
+ break;
+ case 'q':
+ dsizeE=15;
+ dsizeM=112+1;
+ dhidden=1;
+ break;
+ case 'm':
+ dsizeE=15;
+ dsizeM=240 + 1;
+ dhidden = 0;
+ break;
+ } // switch
+
+ i++;
+ while ( buf[ i ] == ' ' ) i++;
+ } // if
+ else {
+ j = 0;
+
+ while ( buf[ i ] != ' ' )
+ tmp[ j++ ] =buf[ i++ ];
+ tmp[ j ] ='\0';
+ dsizeE = atoi( tmp );
+
+ while ( buf[ ++i ] == ' ' );
+
+ j = 0;
+ while ( buf[ i ] != ' ' )
+ tmp[ j++ ] = buf[ i++ ];
+ tmp[ j ] ='\0';
+ dhidden = atoi( tmp );
+
+ while ( buf[ ++i ] == ' ' );
+ j = 0;
+
+ while ( buf[ i ] != ' ' )
+ tmp[ j++ ] =buf[ i++ ];
+ tmp[ j ] ='\0';
+ dsizeM = atoi( tmp );
+ dsizeM++;
+
+ } // else
+
+ while ( buf[ i ] == ' ' ) i++;
+ } // if
+ else {
+ dsizeE = sizeE;
+ dhidden = hidden;
+ dsizeM = sizeM;
+ } // else
+
+ rounding=buf[ i ];
+
+ while ( buf[ ++i ] == ' ' );
+
+ j=0;
+
+ while ( buf[ i ] != ' ' )
+ compare[ j++ ] =buf[ i++ ];
+
+ compare[ j ] ='\0';
+
+ while ( buf[ ++i ] == ' ' );
+
+ j=0;
+ while ( buf[ i ] != ' ' ) {
+ exceptions[ j++ ] =buf[ i++ ];
+ exceptions[ j++ ] =' ';
+ }
+ exceptions[ j ] ='\0';
+
+ while ( buf[ ++i ] == ' ' );
+
+ if ( ( strncmp( operation,"ci",2 ) ==0 ) ||
+ ( strncmp( operation,"cu",2 ) ==0 ) ) {
+ count = 32; // 32 bit integer
+ i += 2; // avoid 0x
+
+ for ( j=0; j<count;j++ ) {
+ if ( isdigit( buf[ i ] ) || ( ( buf[ i ] >= 'a' ) && ( buf[ i ] <= 'f' ) ) )
+ tmp[ j ] = buf[ i++ ];
+ else {
+ tmp[ j ] = 0;
+ break;
+ }
+ } // for
+
+ for ( ; j<count;j++ )
+ tmp[ j ] = 0;
+
+ } else if ( ( strncmp( operation,"cI",2 ) ==0 ) ||
+ ( strncmp( operation,"cU",2 ) ==0 ) ) {
+ count = 64; // 64 bit integer
+ i += 2; // avoid 0x
+ for ( j=0; j<count;j++ ) {
+ if ( isdigit( buf[ i ] ) || ( ( buf[ i ] >= 'a' ) && ( buf[ i ] <= 'f' ) ) )
+ tmp[ j ] = buf[ i++ ];
+ else {
+ tmp[ j ] = 0;
+ break;
+ }
+ }
+ for ( ; j<count;j++ )
+ tmp[ j ] = 0;
+
+ } else if ( strncmp( operation,"d2b",3 ) == 0 ) {
+ j = 0;
+ while ( buf[ i ] != ' ' ) {
+ tmp[ j++ ] = buf[ i++ ];
+ }
+
+ } else {
+ count =( int ) ceil( ( double ) ( sizeM+sizeE ) /32.0 ) *8;
+ for ( j=0; j<count ;j++ ) {
+ if ( buf[ i ] ==' ' )
+ i++;
+ tmp[ j ] = buf[ i++ ];
+ }
+ }
+ tmp[ j ] ='\0';
+
+ if ( strncmp( operation,"d2b",3 ) == 0 ) {
+ operand1 = T( sizeM-1, sizeE, hidden ); // sets Mantissa and exp right
+ operand1.decimal = new char[ maxstr ];
+ for ( k = 0; k <= j; k++ )
+ operand1.decimal[ k ] = tmp[ k ];
+ operand1.decimal[ k ] = '\n';
+ } else if ( strncmp( operation,"ci",2 ) ==0 ) {
+ tmphex.StringToBitstr( tmp );
+ operand1 = T( tmphex,32,0,0 );
+ } else if ( strncmp( operation,"cu",2 ) ==0 ) {
+ tmphex.StringToBitstr( tmp );
+ operand1 = T( tmphex,32,0,0 );
+ } else if ( strncmp( operation,"cI",2 ) ==0 ) {
+ tmphex.StringToBitstr( tmp );
+ operand1 = T( tmphex,64,0,0 );
+ } else if ( strncmp( operation,"cU",2 ) ==0 ) {
+ tmphex.StringToBitstr( tmp );
+ operand1 = T( tmphex,64,0,0 );
+ } else {
+ tmphex.StringToBitstr( tmp );
+ operand1 = T( tmphex,sizeM-1,sizeE,hidden );
+ }
+
+ i++;
+ count =( int ) ceil( ( double ) ( sizeM+sizeE ) /32.0 ) *8; // reset count!
+
+ for ( j=0; j<count ;j++ ) {
+ if ( buf[ i ] ==' ' )
+ i++;
+ tmp[ j ] = buf[ i++ ];
+ }
+
+ tmp[ j ] ='\0';
+ tmphex.StringToBitstr( tmp );
+ operand2 = T( tmphex,sizeM-1,sizeE,hidden );
+
+ if ( buf[ i+1 ] == '?' ) {
+ pre = 1;
+ } else {
+ if ( ( strncmp( operation,"ri",2 ) ==0 ) ||
+ ( strncmp( operation,"ru",2 ) ==0 ) ) {
+ count = 32; // 32 bit integer
+ i += 3; // avoid 0x
+ for ( j=0; j<count;j++ ) {
+ if ( isdigit( buf[ i ] ) || ( ( buf[ i ] >= 'a' ) && ( buf[ i ] <= 'f' ) ) )
+ tmp[ j ] = buf[ i++ ];
+ else {
+ tmp[ j ] = 0;
+ break;
+ }
+ } // for
+ for ( ; j<count;j++ )
+ tmp[ j ] = 0;
+ }
+ else if ( ( strncmp( operation,"rI",2 ) ==0 ) ||
+ ( strncmp( operation,"rU",2 ) ==0 ) ) {
+ count = 64; // 64 bit integer
+ i += 3; // avoid 0x
+ for ( j=0; j<count;j++ ) {
+ if ( isdigit( buf[ i ] ) || ( ( buf[ i ] >= 'a' ) && ( buf[ i ] <= 'f' ) ) )
+ tmp[ j ] = buf[ i++ ];
+ else {
+ tmp[ j ] = 0;
+ break;
+ }
+ } // for
+ for ( ; j<count;j++ )
+ tmp[ j ] = 0;
+ } else if ( strncmp( operation,"b2d",3 ) == 0 ) {
+ i++;
+ j = 0;
+ while ( buf[ i ] != '\n' ) {
+ tmp[ j++ ] = buf[ i++ ];
+ }
+ } else {
+ count =( int ) ceil( ( double ) ( dsizeM+dsizeE ) /32.0 ) *8;
+ i++;
+ for ( j=0; j<count ;j++ ) {
+ if ( buf[ i ] ==' ' )
+ i++;
+ tmp[ j ] = buf[ i++ ];
+ }
+ }
+
+ tmp[ j ] ='\0';
+
+ if ( strncmp( operation,"b2d",3 ) == 0 ) {
+ result.decimal = new char[ maxstr ];
+ for ( k = 0; k <= j; k++ )
+ result.decimal[ k ] = tmp[ k ];
+ result.decimal[ k ] = '\0';
+ }
+
+ else if ( strncmp( operation,"ri",2 ) ==0 ) {
+ tmphex.StringToBitstr( tmp );
+ result = T( tmphex,32,0,0 );
+ } else if ( strncmp( operation,"ru",2 ) ==0 ) {
+ tmphex.StringToBitstr( tmp );
+ result = T( tmphex,32,0,0 );
+ } else if ( strncmp( operation,"rI",2 ) ==0 ) {
+ tmphex.StringToBitstr( tmp );
+ result = T( tmphex,64,0,0 );
+ } else if ( strncmp( operation,"rU",2 ) ==0 ) {
+ tmphex.StringToBitstr( tmp );
+ result = T( tmphex,64,0,0 );
+ } else {
+ tmphex.StringToBitstr( tmp );
+ result = T( tmphex,dsizeM-1,dsizeE,dhidden );
+ }
+
+ return 1;
+ }
+ }
+ return 0;
+}
+
+template <class T>
+char* UCB<T>::GetOperation( )
+{
+ return operation;
+}
+
+template <class T>
+char UCB<T>::GetPrecision( )
+{
+ return prec;
+}
+
+template <class T>
+char UCB<T>::GetRounding( )
+{
+ return rounding;
+}
+
+template <class T>
+char* UCB<T>::GetCompare( )
+{
+ return compare;
+}
+
+template <class T>
+char* UCB<T>::GetExceptions( )
+{
+ return exceptions;
+}
+
+template <class T>
+T & UCB<T>::GetOperand1( )
+{
+ return operand1;
+}
+
+template <class T>
+T & UCB<T>::GetOperand2( )
+{
+ return operand2;
+}
+
+template <class T>
+T & UCB<T>::GetResult( )
+{
+ return result;
+}
+
+template <class T>
+char* UCB<T>::DoLine( int tiny,int inf, int nan)
+{
+ T res;
+ int i = 0;
+
+ if ( !( tiny ) && ( operand1.istiny( ) || operand2.istiny( ) || result.istiny( ) ) )
+ return NULL; // do not test tiny denormalized numbers
+ else if ( !( inf ) && ( operand1.isInf( ) || operand2.isInf( ) || result.isInf( ) ) )
+ return NULL; // do not test infinities
+ else if ( !( nan ) && ( operand1.isNan( ) || operand2.isNan( ) || result.isNan( ) ) )
+ return NULL; // do not test NaNs
+ // logstream.seekp(0,ios::beg);
+
+ allops++;
+ SetFPRound( );
+ result.ClearFPEnvironment( );
+
+#ifdef BasicOperations
+ if ( strncmp( operation,"add",3 ) ==0 )
+ res = operand1 + operand2;
+ else if( strncmp( operation,"sub",3 ) ==0 )
+ res = operand1 - operand2;
+ else if( strncmp( operation,"mul",3 ) ==0 )
+ res = operand1 * operand2;
+ else if( strncmp( operation,"div",3 ) ==0 )
+ res = operand1 / operand2; // debug
+ else if( strncmp( operation,"rem",3 ) ==0 )
+ res = operand1 % operand2;
+ else if( strncmp( operation,"sqrt",4 ) ==0 )
+ res = operand1.sqrt( );
+#endif
+
+#ifdef Conversions
+ if ( strncmp( operation,"rt",2 ) ==0 )
+ res = operand1.roundto( dsizeE,dsizeM-1,dhidden );
+ else if ( strncmp( operation,"ct",2 ) ==0 )
+ res = operand1.copyto( dsizeE,dsizeM-1,dhidden );
+ else if ( strncmp( operation,"i",1 ) ==0 )
+ res = operand1.rint( );
+ else if ( strncmp( operation,"ri",2 ) ==0 )
+ res = operand1.ri( );
+ else if ( strncmp( operation,"ru",2 ) ==0 )
+ res = operand1.ru( );
+ else if ( strncmp( operation,"rI",2 ) ==0 )
+ res = operand1.rI( );
+ else if ( strncmp( operation,"rU",2 ) ==0 )
+ res = operand1.rU( );
+ else if ( strncmp( operation,"ci",2 ) ==0 )
+ res = operand1.ci( dsizeE,dsizeM-1,dhidden );
+ else if ( strncmp( operation,"cu",2 ) ==0 )
+ res = operand1.cu( dsizeE,dsizeM-1,dhidden );
+ else if ( strncmp( operation,"cI",2 ) ==0 )
+ res = operand1.cI( dsizeE,dsizeM-1,dhidden );
+ else if ( strncmp( operation,"cU",2 ) ==0 )
+ res = operand1.cU( dsizeE,dsizeM-1,dhidden );
+ else if ( strncmp( operation,"b2d",3 ) ==0 ) {
+ i = 0;
+ while ( result.decimal[ i ] != 'E' ) {
+ i++;
+ }
+ if ( result.decimal[ 0 ] == '+' || result.decimal[ 0 ] == '-' )
+ i--;
+
+ res = operand1.b2d( i );
+ }
+ else if ( strncmp( operation,"d2b",3 ) ==0 ) {
+ res = operand1.d2b( );
+ }
+#if defined(IntelPentium) && defined(NONE_TEST) && defined(Conversions)
+ else if( strncmp( operation,"rem",3 ) ==0 )
+ res = operand1 % operand2;
+ else if( strncmp( operation,"sqrt",4 ) ==0 )
+ res = operand1.sqrt( );
+#endif
+
+#endif
+
+ Compare( res );
+ return dest;
+}
+
+template <class T>
+void UCB<T>::PrintError( T &res )
+{
+ unsigned int i;
+ if ( (!ieeeVector) || (ieee) )
+ errors++; // total number of errors encountered
+ else
+ warnings++;
+ logfile<<"Operation: " << operation << endl;
+ switch ( rounding ) {
+ case 'n':
+ logfile<<"Round to nearest" << endl;
+ break;
+ case 'z':
+ logfile<<"Round to zero" << endl;
+ break;
+ case 'p':
+ logfile<<"Round up" << endl;
+ break;
+ case 'm':
+ logfile<<"Round down" << endl;
+ break;
+ } // switch
+ logfile<<"Operand 1: " << operand1 << endl;
+ logfile<<"Operand 2: " << operand2 << endl;
+ logfile<< "Flags expected: ";
+ for( i=0 ; i < strlen( exceptions );i++ )
+ switch ( exceptions[ i ] ) {
+ case 'x':
+ logfile<<"x ";
+ break;
+ case 'o':
+ logfile<<"o ";
+ break;
+ case 'u':
+ logfile<<"u ";
+ break;
+ case 'a':
+ logfile<<"v ";
+ break;
+ case 'b':
+ logfile<<"w ";
+ break;
+ case 'v':
+ logfile<<"i ";
+ break;
+ case 'd':
+ logfile<<"z ";
+ break;
+ } // switch
+ logfile << endl;
+ logfile <<"Flags returned: ";
+ if ( res.GetFPDivByZero( ) )
+ logfile << "z " ;
+ if ( res.GetFPInvalid( ) )
+ logfile << "i " ;
+ if ( res.GetFPInexact( ) )
+ logfile << "x " ;
+ if ( res.GetFPOverflow( ) )
+ logfile << "o " ;
+ if ( res.GetFPUnderflow( ) ) {
+ logfile << "u " ;
+ }
+ logfile << endl;
+ logfile << "Correct result: " << result << endl;
+ logfile << "Returned result: " << res << endl<< endl;
+}
+
+
+template <class T>
+void UCB<T>::Compare ( T &reslt )
+{
+ unsigned int i,check=1;
+ if ( ( noFlags & NO_FLAGS_DIV_BY_ZERO ) == 0 ) {
+ if( reslt.GetFPDivByZero( ) )
+ if( !strchr( exceptions,'d' ) ) {
+ logfile<<((ieeeVector) && !(ieee) ? "Warning " : "Error ") << "Line "<<line<< ": divide by zero not expected"<<endl;
+ check = 0;
+ }
+ }
+
+ if ( ( noFlags & NO_FLAGS_INVALID ) == 0 ) {
+ if( reslt.GetFPInvalid( ) )
+ if( !strchr( exceptions,'v' ) ) {
+ logfile<<((ieeeVector) && !(ieee) ? "Warning " : "Error ") <<"Line "<<line<< ": invalid not expected "<<endl;
+ check = 0;
+ }
+ }
+
+ if ( ( noFlags & NO_FLAGS_INEXACT ) == 0 ) {
+ if( reslt.GetFPInexact( ) )
+ if( !strchr( exceptions,'x' ) ) {
+ logfile<<((ieeeVector) && !(ieee) ? "Warning " : "Error ") <<"Line "<<line<< ": inexact not expected"<<endl;
+ check = 0;
+ }
+ }
+
+ if ( ( noFlags & NO_FLAGS_OVERFLOW ) == 0 ) {
+ if( reslt.GetFPOverflow( ) )
+ if( !strchr( exceptions,'o' ) ) {
+ logfile<<((ieeeVector) && !(ieee) ? "Warning " : "Error ") <<"Line "<<line<< ": overflow not expected"<<endl;
+ check = 0;
+ }
+ }
+
+ if ( ( noFlags & NO_FLAGS_UNDERFLOW ) == 0 ) {
+ if( reslt.GetFPUnderflow( ) )
+ if( !strchr( exceptions,'u' ) ) {
+ if( strchr( exceptions,'a' ) ) {
+ signalv = 1;
+ if ( notsignalv ) {
+ logfile<<((ieeeVector) && !(ieee) ? "Warning " : "Error ") <<"Line "<<line<< ": underflow without denormalization loss previously not detected"<< endl;
+ check = 0;
+ } // end if
+ }
+ else if ( strchr( exceptions,'b' ) ) {
+ signalw = 1;
+ if ( notsignalv ) {
+ logfile<<((ieeeVector) && !(ieee) ? "Warning " : "Error ") <<"Line "<<line<< ": underflow without denormalization loss previously not detected" << endl;
+ }
+ if ( notsignalw ) {
+ logfile <<((ieeeVector) && !(ieee) ? "Warning " : "Error ")<<"Line "<<line<< ": underflow before rounding previously not detected"<< endl;
+ check = 0;
+ } // end if
+ }
+ else {
+ logfile<<((ieeeVector) && !(ieee) ? "Warning " : "Error ") <<"Line "<<line<< ": underflow not expected"<<endl;
+ check = 0;
+ } // end if
+ }
+ else
+ signalu = 1;
+ } // end if
+
+ for( i=0 ; i < strlen( exceptions );i++ ) {
+ switch ( exceptions[ i ] ) {
+ case 'x':
+ if ( ( noFlags & NO_FLAGS_INEXACT ) == 0 ) {
+ if( !reslt.GetFPInexact( ) ) {
+ logfile<<((ieeeVector) && !(ieee) ? "Warning " : "Error ") <<"Line "<<line<< ": inexact flag not returned"<<endl;
+ check = 0;
+ }
+ }
+ break;
+ case 'o':
+ if ( ( noFlags & NO_FLAGS_OVERFLOW ) == 0 ) {
+ if( !reslt.GetFPOverflow( ) ) {
+ logfile <<((ieeeVector) && !(ieee) ? "Warning " : "Error ")<<"Line "<<line<< ": overflow flag not returned"<<endl;
+ check = 0;
+ }
+ }
+ break;
+ case 'u':
+ nou = 0;
+ if ( ( noFlags & NO_FLAGS_UNDERFLOW ) == 0 ) {
+ if( !reslt.GetFPUnderflow( ) ) {
+ logfile<<((ieeeVector) && !(ieee) ? "Warning " : "Error ") <<"Line "<<line<< ": underflow not returned"<<endl;
+ notsignalu = 1;
+ check = 0;
+ }
+ }
+ break;
+ case 'a':
+ nov = 0;
+ if ( ( noFlags & NO_FLAGS_UNDERFLOW ) == 0 ) {
+ if( !reslt.GetFPUnderflow( ) ) {
+ notsignalv = 1;
+ //PrintError(reslt);
+ if ( signalv ) {
+ check = 0;
+ } // end if
+ } // end if
+ } // end if
+
+ break;
+ case 'b':
+ now = 0;
+ if ( ( noFlags & NO_FLAGS_UNDERFLOW ) == 0 ) {
+ if( !reslt.GetFPUnderflow( ) ) {
+ notsignalw = 1;
+ if ( signalw ) {
+ logfile<<((ieeeVector) && !(ieee) ? "Warning " : "Error ") <<"Line "<<line<< ": underflow before rounding previously detected"<< endl;
+ check = 0;
+ } // end if
+ } // end if
+ } // end if
+
+ break;
+ case 'v':
+ if ( ( noFlags & NO_FLAGS_INVALID ) == 0 ) {
+ if( !reslt.GetFPInvalid( ) ) {
+ logfile<<((ieeeVector) && !(ieee) ? "Warning " : "Error ") <<"Line "<<line<< ": invalid flag not returned"<<endl;
+ check = 0;
+ }
+ }
+ break;
+ case 'd':
+ if ( ( noFlags & NO_FLAGS_DIV_BY_ZERO ) == 0 ) {
+ if( !reslt.GetFPDivByZero( ) ) {
+ logfile<<((ieeeVector) && !(ieee) ? "Warning " : "Error ") <<"Line "<<line<< ": divide flag not returned"<<endl;
+ check = 0;
+ }
+ }
+ break;
+ }
+ }
+ if ( !pre ) { // no '?'
+ if ( result.decimal != NULL ) {
+ if ( strcmp( result.decimal,reslt.decimal ) != 0 ) {
+ int rd=0, rdd=0, epos=-100;
+ char *resultdummy=new char[maxstr];
+ while (result.decimal[rd] != '\0')
+ {
+ if ((rd==epos+1) && result.decimal[rd]!='-')
+ resultdummy[rdd++]='+';
+
+ resultdummy[rdd] = result.decimal[rd];
+
+ if (result.decimal[rd] == 'E')
+ epos=rd;
+ rd++;
+ rdd++;
+ }
+ resultdummy[rdd] = '\0';
+
+ if (strcmp(resultdummy, reslt.decimal) != 0)
+ {
+ logfile <<((ieeeVector) && !(ieee) ? "Warning " : "Error ") << "Line "<<line<< ": different decimal representation"<< endl;
+ check =0;
+ }
+ delete[] resultdummy;
+ }
+ } else if ( result.IsNaN( ) ) {
+ if( !reslt.IsNaN( ) ) {
+ check=0;
+ logfile<<((ieeeVector) && !(ieee) ? "Warning " : "Error ") <<"Line : "<< line << ": result is not a NaN"<<endl;
+ }
+ } else {
+ if ( reslt.sizeExp > 0 ) {
+ if ( result.Sign( ) != reslt.Sign( ) ) {
+ if (!result.IsZero( ) ) {
+ logfile<<((ieeeVector) && !(ieee) ? "Warning " : "Error ") <<"Line "<<line<< ": Different sign"<< endl;
+ check =0;
+ }
+ else if ( signedZero ) {
+ // In this case result is a zero and there is signedzero
+ logfile<<((ieeeVector) && !(ieee) ? "Warning " : "Error ") <<"Line "<<line<< ": Different sign"<< endl;
+ check =0;
+ }
+ }
+ if ( result.GetExponent( ) != reslt.GetExponent( ) ) {
+ logfile<<((ieeeVector) && !(ieee) ? "Warning " : "Error ") << "Line "<<line<< ": exponent different" << endl;
+ check =0;
+ }
+ }
+ if( result.GetMantissa( ) != reslt.GetMantissa( ) ) {
+ logfile<<((ieeeVector) && !(ieee) ? "Warning " : "Error ") << "Line "<<line<< ": mantissa different" << endl;
+ check =0;
+ }
+ }
+ }
+ if ( !check )
+ PrintError( reslt );
+}
+
+template <class T>
+void UCB<T>::SetFPRound( )
+{
+ switch ( rounding ) {
+ case 'n':
+ result.SetFPRound( RM_NEAR );
+ break;
+ case 'z':
+ result.SetFPRound( RM_ZERO );
+ break;
+ case 'p':
+ result.SetFPRound( RM_UP );
+ break;
+ case 'm':
+ result.SetFPRound( RM_DOWN );
+ break;
+ }
+}
+
+#endif
--- /dev/null
+ /*
+##########################################################################
+# #
+# Program: IeeeCC754 #
+# #
+# Description: #
+# IeeeCC754 or IEEE 754 Compliance Checker is a precision and range #
+# independent tool to test whether an implementation of #
+# floating-point arithmetic (in hardware or software) is compliant #
+# with the principles of the IEEE 754-854 floating-point standards. #
+# You can find out more about the testing tool IeeeCC754 at #
+# #
+# http://win-www.uia.ac.be/u/cant/ieeecc754.html #
+# #
+# This tool is in parts based on and greatly benefited from the #
+# the program FPTEST developed by Jerome Coonen. For a full #
+# description of the extensions to FPTEST and a reference to #
+# the original Coonen program, please refer to the URL given above. #
+# For the options available with the program IeeeCC754 and its #
+# compatibility with David Hough's hexadecimal UCB format, we #
+# also refer to the file readme.usage. #
+# #
+# Usage: see readme.usage #
+# #
+# Responsible authors: #
+# Brigitte Verdonk #
+# Annie Cuyt #
+# #
+# Contributors: #
+# Tarun Agarwal(05-07/2002) #
+# Johan Bogo (1998-1999) #
+# Tim Gevers (10-12/2000) #
+# Debby Ooms (1996-1997) #
+# Geert Vermuyten (1996-1997) #
+# Dennis Verschaeren (09/1996-06/2000) #
+# #
+# Copyright (C) 2000 University of Antwerp #
+# #
+# This program can be obtained from the authors, free, but WITHOUT ANY #
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or #
+# FITNESS FOR A PARTICULAR PURPOSE. #
+# #
+# Contact: #
+# Brigitte.Verdonk@uia.ua.ac.be #
+# Department of Mathematics and Computer Science #
+# University of Antwerp (UIA) #
+# Universiteitsplein 1 #
+# B2610 Antwerp, BELGIUM #
+# #
+##########################################################################
+
+Filename:
+ $RCSfile$
+
+Last updated:
+ $Date$
+
+*/
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <string.h>
+#include <iostream.h>
+#include <fstream.h>
+#include <strstream.h>
+#include <iomanip.h>
+#include <math.h>
+#include <Bitstring.h>
+#include <UCB.h>
+#include <limits.h>
+#include <string>
+extern "C" {
+typedef double LLDBL;
+#include <fltcalc.h>
+}
+
+using namespace std;
+
+#include <DriverFloatRepr.h>
+template<class M> class UCB;
+UCB<DriverFloatRepr> ucb;
+
+#define TD_OVERFLOW 0x08
+#define TD_UNDERFLOW 0x10
+#define TD_UNDERFLOWV 0x40 // inexactness, no denormalization loss
+#define TD_UNDERFLOWW 0x80 // tininess before rounding
+
+#define TD_INVALID 0x01
+#define TD_INEXACT 0x20
+#define TD_DIVBYZERO 0x04
+#define IEEEDEFAULTENV 0
+
+#define TD_TONEAREST 0 // deze numberlen worden gebruikt // FP_RN
+#define TD_UPWARD 2 // ipv de originele roundingnumberlen // FP_RP
+#define TD_DOWNWARD 3 // zoals die voorkomen in "ieeefp.h" // FP_RM
+#define TD_TOWARDZERO 1 // voor compatibiliteit met de UCB // FP_RZ
+// outputfile qua volgorde van
+// rounding
+#define ALL_FORMATS 3
+#define TESTEVEN 1
+#define TESTODD 2
+#define NO_FLAGS 31
+#define NO_FLAGS_INEXACT 16
+#define NO_FLAGS_OVERFLOW 8
+#define NO_FLAGS_UNDERFLOW 4
+#define NO_FLAGS_INVALID 2
+#define NO_FLAGS_DIV_BY_ZERO 1
+#define ROUND_ALL 31
+#define ROUND_NEAREST 8
+#define ROUND_UP 4
+#define ROUND_DOWN 2
+#define ROUND_ZERO 1
+#define ALL_MODES ((1<<TD_TONEAREST) | (1<<TD_DOWNWARD) | (1<<TD_UPWARD) | (1<<TD_TOWARDZERO))
+#define NO_OF_BITS 32
+#define USAGE "Error in calling " << argv[0] <<endl<<\
+"For instructions on calling the program, see the readme.usage file."<<endl\
+
+
+int cant_infinity=0 , small_norm=0;
+int HexNoIsGiven=0;
+int posDec;
+int posUpDec;
+int incexp=0;
+int NaN1,NaN2,NaN3;
+int err1,err2,err3;
+int isIeeeVector=0;
+unsigned long expon;
+unsigned long hidden;
+unsigned long mant;
+unsigned long length;
+unsigned long rest;
+unsigned long sign_exp_length;
+unsigned long kl_biased_exp;
+unsigned long sign_exp_rest ;
+FILE *input=NULL, *output=NULL;
+unsigned long readings;
+unsigned long sexpon;
+unsigned long dexpon;
+unsigned long smant=0;
+unsigned long dmant=0;
+unsigned long shidden;
+unsigned long dhidden;
+unsigned long slength;
+unsigned long srest;
+unsigned long dlength;
+unsigned long drest;
+unsigned long ssign_exp_length; // sign+exponent length(in multiples of NO_OF_BITS)
+unsigned long ssign_exp_rest;
+unsigned long dsign_exp_length;
+unsigned long dsign_exp_rest;
+unsigned long skl_biased_exp;
+unsigned long dkl_biased_exp;
+unsigned long testFormats;
+unsigned long testModes;
+unsigned long flushVector;
+unsigned long killerVector;
+unsigned long *operand1, *operand2, *result;
+long xcp, dots, wrong_input, lines_in, err_form;
+char dot, opcode, op2code, op3code, op4code;
+int comp_sort;
+int CmndLinePos=1, def=0, defe = 0,deft=0,falt =0;
+int ucbInput=0;
+int check =-1;
+int noFlags=0;
+int Round =ROUND_ALL;
+int dectobin=0;
+int tiny=1;
+int inf=1;
+int NaN=1;
+int signedZero=1;
+int ieee=1;
+char *intstr = NULL;
+int skipVector=0,jumpOverflow=0,jumpUnderflow=0,jumpInvalid=0,jumpDivZero=0;
+int pre = 0, post = 0; // to accomodate '?' before or after a result
+int NaNresult = 0;
+char *binary;
+char *upbinary;
+int nextdig = 0;
+int mysignbit = 0;
+char *decimal = new char[ maxstr ];
+char *updecimal = new char[ maxstr ];
+char *logfilename = "ieee.log";
+
+
+void ParseArgs( int, char** );
+void ParsecaseO( int argc, char** argv);
+void ParsecaseS();
+void ParsecaseD( int argc, char** argv);
+void ParsecaseL();
+void ParsecaseQ();
+void ParsecaseM();
+void ParsecaseE( int argc, char** argv);
+void ParsecaseT( int argc, char** argv);
+void ParsecaseR( int argc, char** argv);
+void ParsecaseN( int argc, char** argv);
+void ParsecaseJ( int argc, char** argv);
+void ParsecaseH();
+void PostParseAction( int argc, char** argv );
+void readParam( unsigned long & );
+int readAline( );
+void Calc_General_Stuff( );
+void putDot( );
+void getModes( );
+void getExceptions( );
+unsigned long getinteger();
+unsigned long getHex();
+void getNumber( unsigned long *number);
+void getbinary( unsigned long *number);
+void getdecimal( );
+void getFPsig(unsigned long *number);
+void getFPexp(unsigned long *number);
+void getBbias(unsigned long *number);
+void getBsignificant(unsigned long *number);
+long int getBexpon();
+void getDsignificand();
+void getDexpon();
+void exitmem( );
+int FindNextSpace( string pstring , int beginpos, int occurance );
+void writeUCB();
+void writeUCBopcode(ostrstream &stream);
+void writeUCBprecision(ostrstream &stream);
+void writeUCBround(int m,ostrstream &stream);
+void writeUCBexcep(ostrstream &stream);
+void writeUCBoperand(ostrstream &stream);
+void writeUCBresult(int m,ostrstream &stream);
+void writeUCBcomutative(ostrstream &stream);
+void writeUCBresultBin (int m, ostrstream &stream);
+void writeUCBresultDec (int m, ostrstream &stream);
+void writeUCBresultNum (ostrstream &stream);
+void getFPInteger( unsigned long *number);
+void Infinity( unsigned long *number);
+void Quiet_NaN( unsigned long *number);
+void Signaling_NaN( unsigned long *number);
+void Smallest_Norm( unsigned long *number);
+void ModifierPorM(unsigned long *number,int McasePorM);
+void getModifier(unsigned long *number);
+void ModifierIorD(unsigned long *number,int McaseIorD);
+void getFPRootNumber( unsigned long *number);
+void getFPHexNo();
+int getSign();
+void initialize_values(int source);
+unsigned long null_exp( const unsigned long *number);
+unsigned long one_exp( const unsigned long *number);
+void Plus( unsigned long *number, unsigned long k);
+void PlusBias( unsigned long *number);
+void Minus( unsigned long *number, unsigned long k);
+void MinusBias( unsigned long *number);
+void PlusBk( unsigned long *number, unsigned long k );
+void MinusBk( unsigned long *number, unsigned long k);
+void Incr_at_pos( unsigned long *number, unsigned long pos, unsigned long k);
+void Incr( unsigned long *number, unsigned long k);
+void Decr_at_pos (long unsigned int *, long unsigned int, long unsigned int);
+void Decr( unsigned long *number, unsigned long k);
+void ModifierU( unsigned long *number, unsigned long ulps);
+char* WriteNumber( const unsigned long *, unsigned long, unsigned long,unsigned long, unsigned long, const int );
+void skipSpace( );
+int mygetc( FILE* );
+void myungetc( int, FILE* );
+
+
+
+/*-----------------------------------------------------------------------------
+name :main()
+description :this is the Ieee compliance checker for floating point
+ implementation according to IEEE754-854 specifications.
+called from :/
+call fns :ParseArgs(),Calc_General_Stuff(),readAline(),putdot(),ucb.close()
+exceptions :/
+algorithm :
+Global var. used :
+-----------------------------------------------------------------------------*/
+
+
+int main( int argc,char * argv[ ] )
+{
+ init_fltcalc(0);
+ readings=dots=wrong_input=lines_in=err_form=0;
+ if ( argc >1 )
+
+ ParseArgs( argc, argv ); /* to parse arguments in the executing statement*/
+
+ else
+
+ {
+ cout << USAGE;
+ exit( 1 );
+ }
+
+ Calc_General_Stuff( );
+
+ operand1 = new unsigned long[ slength ];
+ if ( operand1 == NULL )
+ {
+ printf( "\nNot enough memory!\n" );
+ printf( "Program aborted.\n" );
+ fclose( input );
+ fclose( output );
+ exit( EXIT_SUCCESS );
+ }
+
+ operand2 = new unsigned long[ slength ];
+ if ( operand2 == NULL )
+ {
+ printf( "\nNot enough memory\n" );
+ printf( "Program aborted.\n" );
+ fclose( input );
+ fclose( output );
+ delete[ ] operand1;
+ exit( EXIT_SUCCESS );
+ }
+
+ result = new unsigned long[ dlength ];
+
+ if ( result == NULL )
+ {
+ printf( "\nNot enough memory\n" );
+ printf( "Program aborted.\n" );
+ fclose( input );
+ fclose( output );
+ delete[ ] operand1;
+ delete[ ] operand2;
+ exit( EXIT_SUCCESS );
+ }
+
+ dot='.';
+
+ while ( readAline( ) )
+ {
+ skipVector = 0;
+ readings += 1;
+ putDot( );
+ }
+
+ printf( "\n\nCounting %ld lines.\n", readings );
+
+ delete[ ] operand1;
+ delete[ ] operand2;
+ delete[ ] result;
+ ucb.Close( tiny );
+ fclose( input );
+ if ( output )
+ fclose( output );
+ return 0;
+}
+
+
+
+
+/*-----------------------------------------------------------------------------
+name :ParseArgs()
+description :parse the command line arguments to get the precision and
+ rounding modes.
+called from :main()
+call fns :ParsecaseO/S/D/L/Q/M/E/T/R/N/J/H , PostParseAction
+Global var. used :check, def,defe,deft,flat,ucbInput
+-----------------------------------------------------------------------------*/
+void ParseArgs( int argc, char** argv )
+{
+ int j;
+ dmant = 0;
+ dexpon = 0;
+ shidden=0;
+
+ while ( CmndLinePos < argc )
+ {
+ if ( ( strlen( argv[ CmndLinePos ] ) <= 3 ) && ( argv[CmndLinePos][ 0 ] == '-' ) )
+ {
+ switch ( argv[CmndLinePos][ 1 ] )
+ {
+ case 'c': //coonen format
+ if ( check == -1 )
+ check = 1;
+ else
+ falt =1;
+ break;
+
+ case 'u': //ucb format (precisely one of
+ // -c | -u |-o should be there)
+ if ( check !=-1 )
+ falt =1;
+ def =1;
+ ucbInput =1;
+ break;
+
+ case 'o': //change coonen to ucb format
+ ParsecaseO(argc,argv);
+ break;
+
+
+ case 's': //single precision
+ ParsecaseS();
+ break;
+ case 'd': //if -d then double presion
+ ParsecaseD(argc,argv); // else specifications for destination
+ break;
+ case 'l': //long double precision
+ ParsecaseL();
+ break;
+ case 'q': //quadruple precision
+ ParsecaseQ();
+ break;
+ case 'm': //multi precision
+ ParsecaseM();
+ break;
+ case 'e': //specify no. of bits for exponent
+ ParsecaseE(argc,argv);
+ break;
+ case 't': //specify <int> bits precision
+ ParsecaseT(argc,argv);
+ break;
+
+ case 'r': //specify rounding modes
+ ParsecaseR(argc,argv);
+ break;
+
+ case 'i': //test conversions within range specified by ieee
+ ieee=0;
+ break;
+
+ case 'n': //do not test specified exceptions, infinity,...
+ ParsecaseN(argc,argv);
+ break;
+
+ case 'j': //jump/skip test vectors raising overflow, ...
+ ParsecaseJ(argc,argv);
+ break;
+
+ case 'h': //specify if hidden bit
+ ParsecaseH();
+ break;
+
+ case 'f': // name of log file
+ CmndLinePos++;
+ logfilename = argv[CmndLinePos];
+ break;
+
+ default:
+ falt = 1;
+ } // end switch
+ }
+ else
+ {
+ if ( CmndLinePos == argc-1 ) //check if test vector file exists
+ {
+ input = fopen( argv[CmndLinePos], "r" );
+ if ( input == NULL )
+ {
+ printf( "ERROR: can't open %s.\n",argv[CmndLinePos] );
+ falt =1;
+ } else
+ printf( "Taking input from %s.\n",argv[CmndLinePos] );
+ } else
+ falt = 1;
+ }
+
+ if ( falt )
+ {
+ cout << USAGE;
+ exit( 1 );
+ }
+
+ CmndLinePos++;
+ } // end while
+
+
+ if ( ( dmant == 0 ) || ( dexpon == 0 ) ) //if destination precision still has initial
+ { //values then equate them to that of source.
+ dmant = smant; //(could be changed only for conversions)
+ dexpon = sexpon;
+ dhidden = shidden;
+ } // if
+
+
+ PostParseAction(argc,argv);
+
+}
+
+
+
+
+/*-----------------------------------------------------------------------------
+name :ParsecaseO()
+description :change coonen to ucb format
+called from :ParseArgs()
+call fns :\
+Global var. used :check,CmndLinePos,falt
+-----------------------------------------------------------------------------*/
+void ParsecaseO( int argc, char** argv)
+{
+ if ( check == -1 )
+ {
+ if ( ++CmndLinePos != argc )
+ {
+ if ( argv[CmndLinePos][ 0 ] != '-' )
+ {
+ output = fopen( argv[CmndLinePos], "w" );
+ if ( output == NULL )
+ {
+ printf( "ERROR: can't create %s.\n",argv[CmndLinePos] );
+ falt =1;
+ } else
+ printf( "Output sent to %s.\n",argv[CmndLinePos] );
+ } else
+ falt = 1;
+ } else
+ falt = 1;
+ check = 0;
+ } else
+ falt = 1;
+}
+
+
+/*-----------------------------------------------------------------------------
+name :ParsecaseS()
+description :specify single precision
+called from :ParseArgs()
+call fns :\
+Global var. used :sexpon,smant,shidden,def,falt
+-----------------------------------------------------------------------------*/
+void ParsecaseS()
+{
+ if ( !def )
+ {
+ sexpon = 8;
+ smant = 23;
+ shidden = 1;
+ def = 1;
+ } else
+ falt =1;
+}
+
+
+/*-----------------------------------------------------------------------------
+name :ParsecaseD()
+description :default is for double precision else it gets precision
+ specifications for the destination (only used in conversions)
+called from :ParseArgs()
+call fns :\
+Global var. used :CmndLinePos,falt
+-----------------------------------------------------------------------------*/
+void ParsecaseD( int argc, char** argv)
+{
+ switch ( argv[CmndLinePos][ 2 ] )
+ {
+ case 'h':
+ dhidden= 1;
+ dmant = dmant -1;
+ break;
+ case 'e':
+ if ( ++CmndLinePos != argc )
+ {
+ dexpon = atoi( argv[CmndLinePos] );
+ if ( dexpon == 0 )
+ {
+ cout << "Error: not a number or zero" << endl;
+ falt =1;
+ }
+ }
+ break;
+ case 't':
+ if ( ++CmndLinePos != argc )
+ {
+ dmant = dmant + atoi( argv[CmndLinePos] );
+ if ( dmant == 0 )
+ cout << "Error: not a number or zero" << endl;
+ }
+ break;
+ case 's':
+ dexpon = 8;
+ dmant = 23;
+ dhidden = 1;
+ break;
+ case 'd':
+ dexpon = 11;
+ dmant = 52;
+ dhidden = 1;
+ break;
+ case 'l':
+ dexpon = 15;
+ dmant = 64;
+ dhidden = 0;
+ break;
+ case 'q':
+ dexpon = 15;
+ dmant = 112;
+ dhidden = 1;
+ break;
+ case 'm':
+ dexpon = 15;
+ dmant = 240;
+ dhidden = 0;
+ break;
+ default:
+ if ( !def )
+ {
+ sexpon = 11;
+ smant = 52;
+ shidden = 1;
+ def = 1;
+ } else
+ falt =1;
+ break;
+ } // switch
+}
+
+
+/*-----------------------------------------------------------------------------
+name :ParsecaseL()
+description :long doulbe precision
+called from :ParseArgs()
+call fns :\
+Global var. used :
+-----------------------------------------------------------------------------*/
+void ParsecaseL()
+{
+ if ( !def )
+ {
+ sexpon = 15;
+ smant = 64;
+ shidden = 0;
+ def = 1;
+ } else
+ falt =1;
+}
+
+
+/*-----------------------------------------------------------------------------
+name :ParsecaseQ()
+description :quadruple precision
+called from :ParseArgs()
+call fns :\
+Global var. used :
+-----------------------------------------------------------------------------*/
+void ParsecaseQ()
+{
+ if ( !def )
+ {
+ sexpon = 15;
+ smant = 112;
+ shidden = 1;
+ def = 1;
+ } else
+ falt =1;
+}
+
+
+/*-----------------------------------------------------------------------------
+name :ParsecaseM()
+description :Multi precision
+called from :ParseArgs()
+call fns :\
+Global var. used :
+-----------------------------------------------------------------------------*/
+void ParsecaseM()
+{
+ if ( !def )
+ {
+ sexpon = 15;
+ smant = 240;
+ shidden = 0;
+ def = 1;
+ } else
+ falt =1;
+}
+
+
+/*-----------------------------------------------------------------------------
+name :ParsecaseE()
+description :specify no. of bits for exponent
+called from :ParseArgs()
+call fns :\
+Global var. used :CmndLinePos,falt
+-----------------------------------------------------------------------------*/
+void ParsecaseE( int argc, char** argv)
+{
+ if ( !def )
+ {
+ if ( ++CmndLinePos != argc )
+ {
+ sexpon = atoi( argv[CmndLinePos] );
+ if ( sexpon == 0 )
+ {
+ cout << "Error: not a number or zero" << endl;
+ falt =1;
+ }
+ defe =1;
+ } else
+ falt = 1;
+ } else
+ falt =1;
+}
+
+
+/*-----------------------------------------------------------------------------
+name :ParsecaseT()
+description :specify <int> bits precision
+called from :ParseArgs()
+call fns :\
+Global var. used :CmndLinePos,falt
+-----------------------------------------------------------------------------*/
+void ParsecaseT( int argc, char** argv)
+{
+ if( !def )
+ {
+ if ( ++CmndLinePos != argc )
+ {
+ smant = smant + atoi( argv[CmndLinePos] );
+ if ( smant == 0 )
+ {
+ cout << "Error: not a number or zero" << endl;
+ falt =1;
+ }
+ deft=1;
+ } else
+ falt =1;
+ } else
+ falt =1;
+}
+
+
+/*-----------------------------------------------------------------------------
+name :ParsecaseR()
+description :specify rounding modes
+called from :ParseArgs()
+call fns :\
+Global var. used :
+-----------------------------------------------------------------------------*/
+void ParsecaseR( int argc, char** argv)
+{
+ int j;
+ Round = 0;
+ if ( ++CmndLinePos != argc )
+ {
+ if ( ( argv[CmndLinePos][ 0 ] != '-' ) && ( CmndLinePos != argc -1 ) )
+ {
+ j=0;
+ while ( argv[CmndLinePos][ j ] != '\0' )
+ {
+ switch( argv[CmndLinePos][ j ] )
+ {
+ case 'n':
+ Round |= ROUND_NEAREST;
+ break;
+ case 'p':
+ Round |= ROUND_UP;
+ break;
+ case 'm':
+ Round |= ROUND_DOWN;
+ break;
+ case 'z':
+ Round |= ROUND_ZERO;
+ break;
+ }
+ j++;
+ } // while
+ }
+ else
+ {
+ Round = ROUND_ALL; // Test all
+ CmndLinePos--;
+ }
+ } else
+ falt = 1;
+}
+
+
+/*-----------------------------------------------------------------------------
+name :ParsecaseN()
+description :do not test specified exceptions, denormalized nos., NaNs,
+ signed infinty, signed zeros
+called from :ParseArgs()
+call fns :\
+Global var. used :
+-----------------------------------------------------------------------------*/
+void ParsecaseN( int argc, char** argv)
+{
+ int j;
+ if ( ++CmndLinePos != argc )
+ {
+ if ( ( argv[CmndLinePos][ 0 ] != '-' ) && ( CmndLinePos != argc -1 ) )
+ {
+ j=0;
+ while ( argv[CmndLinePos][ j ] != '\0' )
+ {
+ switch( argv[CmndLinePos][ j ] )
+ {
+ /*
+ case 'i':
+ noFlags |= NO_FLAGS_INVALID;
+ break;
+ */
+ case 'o':
+ noFlags |= NO_FLAGS_OVERFLOW ;
+ break;
+ case 'x':
+ noFlags |= NO_FLAGS_INEXACT;
+ break;
+ case 'z':
+ noFlags |= NO_FLAGS_DIV_BY_ZERO;
+ break;
+ case 'u':
+ noFlags |= NO_FLAGS_UNDERFLOW;
+ break;
+ case 't':
+ if ( ( argv[CmndLinePos][ j+1 ] == 'i' ) &&
+ ( argv[CmndLinePos][ j+2 ] == 'n' ) &&
+ ( argv[CmndLinePos][ j+3 ] == 'y' ) )
+ {
+ tiny = 0;
+ j += 3;
+ } else
+ falt = 1;
+ break;
+ case 'i':
+ if ( ( argv[CmndLinePos][ j+1 ] == 'n' ) &&
+ ( argv[CmndLinePos][ j+2 ] == 'f' ) ) {
+ inf = 0;
+ j += 2;
+ } else
+ {
+ noFlags |= NO_FLAGS_INVALID;
+ }
+ break;
+ case 'n':
+ if ( ( argv[CmndLinePos][ j+1 ] == 'a' ) &&
+ ( argv[CmndLinePos][ j+2 ] == 'n' ) )
+ {
+ NaN = 0;
+ j += 2;
+ } else
+ falt = 1;
+ break;
+ case 's':
+ if ( ( argv[CmndLinePos][ j+1 ] == 'n' ) &&
+ ( argv[CmndLinePos][ j+2 ] == 'z' ) )
+ {
+ signedZero = 0;
+ j += 2;
+ } else
+ falt = 1;
+ break;
+ }
+ j++;
+ } // while
+ }
+ else
+ {
+ noFlags = NO_FLAGS; //Test no flags (all values selected)
+ CmndLinePos--;
+ }
+ } else
+ falt = 1;
+}
+
+
+/*-----------------------------------------------------------------------------
+name :ParsecaseJ()
+description :jump/skip test vectors raising overflow, underflow, invalid or
+ divide by zero exception
+called from :ParseArgs()
+call fns :\
+Global var. used :
+-----------------------------------------------------------------------------*/
+void ParsecaseJ( int argc, char** argv)
+{
+ int j;
+ if ( ++CmndLinePos != argc )
+ {
+ if ( ( argv[CmndLinePos][ 0 ] != '-' ) && ( CmndLinePos != argc -1 ) )
+ {
+ j=0;
+ while ( argv[CmndLinePos][ j ] != '\0' )
+ {
+ switch( argv[CmndLinePos][ j ] ) {
+ case 'i':
+ jumpInvalid= 1;
+ break;
+ case 'o':
+ jumpOverflow= 1;
+ break;
+ case 'u':
+ jumpUnderflow= 1;
+ break;
+ case 'z':
+ jumpDivZero= 1;
+ break;
+ default:
+ falt = 1;
+ break;
+ }
+ j++;
+ } // while
+ }
+ } else
+ falt = 1;
+}
+
+
+/*-----------------------------------------------------------------------------
+name :ParsecaseH()
+description :specify if hidden bit
+called from :ParseArgs()
+call fns :\
+Global var. used :
+-----------------------------------------------------------------------------*/
+void ParsecaseH()
+{
+ if( !def )
+ {shidden= 1;
+ smant = smant -1;}
+ else
+ falt =1;
+}
+
+
+
+
+/*-----------------------------------------------------------------------------
+name :PostParseAction()
+description :if change to ucb then calls required fns,
+ else check for errors and opens log file.
+called from :ParseArgs()
+call fns :ucb.OpenLogFile(),ucb.ReadLine(),ucb.DoLine(),ucb.Close
+Global var. used :check, def,defe,deft,flat,ucbInput
+-----------------------------------------------------------------------------*/
+void PostParseAction( int argc, char** argv )
+{
+
+ if ( !ucbInput )
+ { // check float formats
+ if ( ( sexpon > 32 ) || ( dexpon> 32 ) )
+ {
+ cout << "Exit: exponent size too big (> 32)" << endl;
+ exit( 1 );
+ } else if ( ( smant+shidden <24 ) || ( dmant+dhidden <24 ) || ( sexpon < 8 ) || ( dexpon < 8 ) )
+ {
+ cout << "Exit: floating-point format too small" << endl;
+ exit( 1 );
+ } else if ( ( smant + shidden < sexpon ) || ( dmant + dhidden < dexpon ) )
+ {
+ cout << "Exit: Precision t must at least equal exponent size" << endl;
+ exit( 1 );
+ } else if ( ( smant + shidden > ((unsigned long)1 << (sexpon-1))) || ( dmant + dhidden > ((unsigned long)1 << (dexpon-1)) ) )
+ {
+ cout << "Exit: Precision t > Bias + 1 = 2^(e-1)" << endl;
+ exit( 1 );
+ }
+ } // if
+
+ if ( ( !def ) & ( !deft | !defe ) )
+ {
+ cout << USAGE;
+ exit( 1 );
+ }
+
+
+ if ( check )
+ ucb.OpenLogFile( logfilename,argc,argv );
+
+
+ if ( ucbInput )
+ {
+ if ( input )
+ {
+ ucb.OpenInput( argv[ argc-1 ] );
+ while ( ucb.ReadLine( NULL,signedZero, noFlags ) )
+ {
+ ucb.DoLine( tiny,inf,NaN );
+ }
+ ucb.Close( tiny );
+ }
+ exit( 1 );
+ }
+
+
+ if ( ( input == NULL ) | ( ( output == NULL ) & ( check == -1 ) ) )
+ {
+ if ( input == NULL )
+ cout << "Error: No input \n";
+ else
+ cout << "Error: No output\n";
+
+ cout << USAGE;
+ exit( 1 );
+ }
+}
+
+
+
+/*-----------------------------------------------------------------------------
+name :Calc_General_Stuff()
+description :calculates the sizes of arrays to store numbers according to the
+ precision specifications in the command line
+called from :main()
+call fns :/
+exceptions :/
+algorithm :
+Global var. used :slength,srest,sexpon,smant,delength,drest,dexpon,dmant,
+ ssign_exp_length,ssign_exp_rest,skl_biased_exp,dkl_biased_exp,
+ dsign_exp_length,dsign_exp_rest.
+-----------------------------------------------------------------------------*/
+
+void Calc_General_Stuff( )
+{
+ //to calculate length of arrays used
+ // change BV 17/01/01
+
+ /* comments regarding the calculated variables
+ s for source , d for destination.
+ slength ---- length of FP format in multiples of <no. of bits>
+ srest ---- no. of bits required for FP format in
+ the last of these allocated array elemnt
+ ssign_exp_length ---number of array elements to
+ represent all the bits in exponent + sign bit
+ ssign_exp_rest --- no. of bits required for sign + exponent in
+ the last of these allocated array elemnt - 1
+ NO_OF_BITS--- number of bits in array element
+ */
+
+ slength = ( unsigned long ) ceil( ( sexpon+smant+1 ) /float(NO_OF_BITS));
+ srest = ( sexpon+smant+1 ) % NO_OF_BITS;
+
+ dlength = ( unsigned long ) ceil( ( dexpon+dmant+1 ) /float(NO_OF_BITS));
+ drest = ( dexpon+dmant+1 ) % NO_OF_BITS;
+
+ ssign_exp_length = ( sexpon/NO_OF_BITS ) + 1;
+ ssign_exp_rest = sexpon % NO_OF_BITS;
+
+ dsign_exp_length = ( dexpon/NO_OF_BITS ) + 1;
+ dsign_exp_rest = dexpon % NO_OF_BITS;
+
+ skl_biased_exp = 1L << ( NO_OF_BITS-ssign_exp_rest-1 );
+ dkl_biased_exp = 1L << ( NO_OF_BITS-dsign_exp_rest-1 );
+
+}
+
+
+
+
+
+/*-----------------------------------------------------------------------------
+name :readAline()
+description :reads a test vector from the file and checks if the test
+ software/hardware is compatible with IEEE spcifications
+called from :main()
+call fns :getbinary(),getNumber(),getdecimal()isspace(),mygetc(),myungetc(),
+ getModes(),getException(),skipSpace(),WriteNumber(),
+ initialize_values(),writeUCB().
+exceptions :/
+algorithm :/
+Global var. used :lots
+-----------------------------------------------------------------------------*/
+
+int readAline( )
+{
+ char c;
+ err1=0,err2=0,err3=0, isIeeeVector=0;
+ comp_sort=0;
+ err_form=0;
+ killerVector=0;
+ int NaN1, NaN2, NaN3;
+ int source=0;
+
+ char *tmp;
+
+ pre = post = 0;
+ NaN1 = NaN2 = NaN3 = 0;
+
+ while ( ( ( c = mygetc( input ) ) == '!' ) || ( c == '\n' ) || ( c == ' ' ) )
+ {
+ if ( c == '!' )
+ /* Skip rest of comment line. */
+ while ( ( c = mygetc( input ) ) != '\n' )
+ ;
+ if ( c == '\n' )
+ lines_in++;
+ }
+
+ if ( c == EOF )
+ return 0;
+
+ opcode = mygetc( input ); // 2nd character is the first character of the opcode
+ op2code=op3code = op4code = ' ';
+ testFormats=0;
+ c = mygetc( input );
+
+ if ( !isspace( c ) )
+ {
+ op2code = c;
+ }
+ // seek further opcode bytes
+ while ( !isspace( c ) ) c = mygetc( input ); // and throw them away because we only need first char
+
+
+ // Get the precision specifications
+ while ( isspace( c ) ) c= mygetc( input );
+ switch ( c ) {
+ case 's':
+ op3code='s';
+ break;
+ case 'd':
+ op3code='d';
+ break;
+ case 'l':
+ op3code='l';
+ break;
+ case 'q':
+ op3code='q';
+ break;
+ case 'm':
+ op3code='m';
+ break;
+ case 'e':
+ testFormats= TESTEVEN;
+ break;
+ case 'o':
+ testFormats= TESTODD;
+ break;
+ default:
+ op3code='z'; // op3code z-> no precisions specification
+ myungetc( c, input); // put the current char back because it does not belong to precision specs
+ break;
+ }
+ // check if test-vector precision specs correspond with command-line provided precision specs
+ if ( op3code !='z' && op3code !='e' && op3code!='o' )
+ {
+ if ( ( (sexpon==8) && ( (shidden+smant) ==24 ) && (op3code != 's') ) ||
+ ( ( ( (sexpon!=8) || (shidden+smant)!=24 ) ) && (op3code == 's') ) ||
+ ( ( sexpon==11 ) && ( (shidden+smant)==53) && (op3code != 'd') ) ||
+ ( ( (sexpon!=11) || ( (shidden+smant)!=53) ) && (op3code == 'd') ) ||
+ ( ( sexpon==15 ) && ((shidden+smant)==64 ) && ( op3code != 'l' ) ) ||
+ ( ( ( sexpon!=15 ) || ((shidden+smant)!=64 ) ) && ( op3code == 'l' ) ) ||
+ ( ( sexpon==15 ) && ((shidden+smant)==113 ) && ( op3code != 'q' ) ) ||
+ ( ( ( sexpon!=15 ) || ((shidden+smant)!=113 ) ) && ( op3code == 'q' ) ) ||
+ ( ( sexpon==15 ) && ((shidden+smant)==240 ) && ( op3code != 'm' ) ) ||
+ ( ( ( sexpon!=15 ) || ((shidden+smant)!=240 ) ) && ( op3code == 'm' ) ) ) {
+ while ( ( c = mygetc( input ) ) != '\n' ) /* Skip rest of line. */
+ ;
+ return 1; // precision dependent test vectors
+ }
+ }
+ c = mygetc( input );
+ if ( op3code !='z' && op3code !='e' && op3code!='o' )
+ {
+ switch ( c )
+ {
+ case 'i':
+ isIeeeVector= 1;
+ while ( !isspace( c ) ) c= mygetc( input ); // read the eee and throw it away!
+ break;
+ }
+ }
+
+ myungetc( c, input);
+ skipSpace( );
+ getModes( );
+ skipSpace( );
+
+ if ( opcode == 'b' )
+ {
+ source=1; //for source
+ initialize_values(source);
+ getbinary(operand1);
+ for ( long i=0; i<slength;i++ ) // init operand2
+ operand2[ i ] =0;
+ } else if ( opcode == 'd' ) {
+ getdecimal( );
+ for ( long i=0; i<slength;i++ ) // init operand2
+ operand2[ i ] =0;
+ } else
+ {
+ source=1; //for source
+ initialize_values(source);
+ getNumber(operand1);
+
+ if ( NaNresult )
+ NaN1 = 1;
+
+ if ( wrong_input )
+ err1=1;
+
+ skipSpace( );
+ source=1; //for source
+ initialize_values(source);
+ getNumber(operand2);
+
+ if ( NaNresult )
+ NaN2 = 1;
+
+ if ( wrong_input )
+ err2=1;
+ }
+
+ skipSpace( );
+ getExceptions( );
+ skipSpace( );
+
+ if ( opcode == 'b' )
+ {
+ getdecimal( );
+ }
+ else if ( opcode == 'd' )
+ {
+ source=1; //for source
+ initialize_values(source);
+ getbinary(result);
+ }
+ else
+ {
+ source=0; //for destination
+ initialize_values(source);
+
+ getNumber(result);
+ if ( NaNresult )
+ NaN3 = 1;
+ if ( wrong_input )
+ err3=1;
+ if ( opcode != 'C' )
+ comp_sort=6;
+ }
+ writeUCB();
+ if ( err_form )
+ printf( "\nWrong input on line %ld\n",lines_in+readings+1 );
+ while ( c != '\n' )
+ c = mygetc( input );
+ return 1;
+}
+
+
+/*-----------------------------------------------------------------------------
+ name :writeUCB
+ description :writes the test vector in UCB fromat
+ called from :readAline()
+ calls fns :writeUCBopcode(),writeUCBprecision(),writeUCBround(),
+ writeUCBexcep(),writeUCBoperand,writeUCBresult()
+ writeUCBcomutaitive()
+ Global var. used :/
+ -----------------------------------------------------------------------------*/
+void writeUCB()
+{
+ int m;
+ if ( ( ( ( smant + shidden ) % 2 == 0 ) && ( testFormats == TESTEVEN ) ) |
+ ( ( ( smant + shidden ) % 2 != 0 ) && ( testFormats == TESTODD ) ) |
+ ( testFormats == ALL_FORMATS ) )
+ {
+ for ( m=0;m<4;m++ )
+ {
+ ostrstream stream;
+
+ if ( ( testModes >> m ) & 0x1 )
+ {
+ writeUCBopcode(stream);
+ writeUCBprecision(stream);
+ writeUCBround(m,stream);
+ writeUCBexcep(stream);
+ writeUCBoperand(stream);
+ writeUCBresult(m,stream);
+ stream<<endl<<ends;
+ writeUCBcomutative(stream);
+ }
+ }
+ if ( intstr != NULL )
+ {
+ delete [ ] intstr;
+ intstr = NULL;
+ }
+ }
+
+}
+
+
+/*-----------------------------------------------------------------------------
+ name :writeUCBopcode()
+ description :writes opcode of testvector in the UCB format
+ called from :writeUCB
+ calls fns :
+ Global var. used :/
+ -----------------------------------------------------------------------------*/
+void writeUCBopcode(ostrstream &stream)
+{
+
+ switch ( opcode ) {
+ case '+' :
+ stream << "add";
+ break;
+ case '-' :
+ stream << "sub";
+ break;
+ case '*' :
+ stream << "mul";
+ break;
+ case '/' :
+ stream << "div";
+ break;
+ case '%' :
+ stream << "rem";
+ break;
+ case 'V' :
+ stream <<"sqrt";
+ break;
+ case 'S' :
+ stream <<"sqrt";
+ break;
+ case 'r':
+ switch ( op2code ) {
+ case ' ':
+ stream <<"rt";
+ break;
+ case 'i':
+ stream <<"ri";
+ break;
+ case 'u':
+ stream <<"ru";
+ break;
+ case 'I':
+ stream <<"rI";
+ break;
+ case 'U':
+ stream <<"rU";
+ break;
+ } // switch
+ break;
+ case 'c':
+ switch ( op2code ) {
+ case ' ':
+ stream <<"ct";
+ break;
+ case 'i':
+ stream <<"ci";
+ break;
+ case 'u':
+ stream <<"cu";
+ break;
+ case 'I':
+ stream <<"cI";
+ break;
+ case 'U':
+ stream <<"cU";
+ break;
+ } // switch
+ break;
+ case 'i':
+ stream <<"i";
+ break;
+ case 'b':
+ stream <<"b2d";
+ break;
+ case 'd':
+ stream << "d2b";
+ break;
+ default:
+ printf( "\n\nError on line %ld of inputfile.",lines_in+readings+1 );
+ printf( "\nERROR: unrecognizable operation: %c\n", opcode );
+ printf( "\n\nDone with %ld readings.\n", readings );
+ exit( EXIT_SUCCESS );
+ }
+
+}
+
+/*-----------------------------------------------------------------------------
+ name :writeUCBprecision()
+ description :writes precision of testvector in the UCB format
+ called from :writeUCB
+ calls fns :
+ Global var. used :/
+ -----------------------------------------------------------------------------*/
+void writeUCBprecision(ostrstream &stream)
+{
+ if ( ( shidden ) && ( sexpon==8 ) && ( smant==23 ) )
+ if ( !isIeeeVector )
+ stream <<"s ";
+ else
+ stream <<"S ";
+ else if ( ( shidden ) && ( sexpon==11 ) && ( smant==52 ) )
+ if ( !isIeeeVector )
+ stream <<"d ";
+ else
+ stream <<"D ";
+ else if ( !( shidden ) && ( sexpon==15 ) && ( smant==64 ) )
+ if ( !isIeeeVector )
+ stream <<"l ";
+ else
+ stream <<"L ";
+ else if ( ( shidden ) && ( sexpon==15 ) && ( smant==112 ) )
+ if ( !isIeeeVector )
+ stream <<"q ";
+ else
+ stream <<"Q ";
+ else if ( !( shidden ) && ( sexpon==15 ) && ( smant==240 ) )
+ if ( !isIeeeVector )
+ stream <<"m ";
+ else
+ stream <<"M ";
+ else
+ stream << sexpon << " "<< shidden <<" "<< smant <<" " ;
+
+
+ if ( ( ( opcode == 'r' ) || ( opcode == 'c' ) ) && ( op2code == ' ' ) )
+ if ( ( dhidden ) && ( dexpon==8 ) && ( dmant==23 ) )
+ stream <<"s ";
+ else if ( ( dhidden ) && ( dexpon==11 ) && ( dmant==52 ) )
+ stream <<"d ";
+ else if ( !( dhidden ) && ( dexpon==15 ) && ( dmant==64 ) )
+ stream <<"l ";
+ else if ( ( dhidden ) && ( dexpon==15 ) && ( dmant==112 ) )
+ stream <<"q ";
+ else if ( !( dhidden ) && ( dexpon==15 ) && ( dmant==240 ) )
+ stream <<"m ";
+ else
+ stream << dexpon << " "<< dhidden <<" "<< dmant <<" " ;
+
+}
+
+
+/*-----------------------------------------------------------------------------
+ name :writeUCBround
+ description :writes rounding mode of the test vector in the UCB format
+ called from :writeUCB
+ calls fns :
+ Global var. used :/
+ -----------------------------------------------------------------------------*/
+void writeUCBround(int m,ostrstream &stream)
+{
+ switch( m ) {
+ case 0 :
+ stream <<"n ";
+ break;
+ case 1 :
+ stream <<"z ";
+ break;
+ case 2 :
+ stream <<"p ";
+ break;
+ case 3 :
+ stream <<"m ";
+ break;
+ }
+}
+
+
+/*-----------------------------------------------------------------------------
+ name :writeUCBexcep()
+ description :writes exceptions of the testvector in the UCB format
+ called from :
+ calls fns :
+ Global var. used :/
+ -----------------------------------------------------------------------------*/
+void writeUCBexcep(ostrstream &stream)
+{
+ if ( !killerVector )
+ stream <<"eq ";
+ else
+ stream <<"uo ";
+
+ if ( xcp==0 )
+ stream <<"-";
+ if ( xcp & long( TD_INVALID ) )
+ stream <<"v";
+ if ( xcp & long( TD_INEXACT ) )
+ stream <<"x";
+ if ( xcp & long( TD_OVERFLOW ) )
+ stream <<"o";
+ if ( xcp & long( TD_UNDERFLOW ) )
+ stream <<"u";
+ if ( xcp & long( TD_UNDERFLOWV ) )
+ stream <<"a";
+ if ( xcp & long( TD_UNDERFLOWW ) )
+ stream <<"b";
+ if ( xcp & long( TD_DIVBYZERO ) )
+ stream <<"d";
+}
+
+
+/*-----------------------------------------------------------------------------
+ name :writeUCBoperand()
+ description :writes operannds or source for the operation in UCB format
+ called from :writeUCB
+ calls fns :
+ Global var. used :/
+ -----------------------------------------------------------------------------*/
+void writeUCBoperand(ostrstream &stream)
+{
+char *tmp;
+ if ( ( intstr != NULL ) && ( opcode == 'c' ) )
+ {
+ stream << " ";
+ stream << intstr;
+ if ( NaN2 )
+ NaNresult = 1;
+ else
+ NaNresult = 0;
+ tmp = WriteNumber( operand2,sexpon,shidden,smant,slength,err1 );
+ stream << tmp;
+ delete [ ] tmp;
+
+ } else
+ {
+
+ if ( NaN1 )
+ NaNresult = 1;
+ else
+ NaNresult = 0;
+
+ if ( opcode == 'd' )
+ {
+ stream << " ";
+ stream << decimal;
+ } else
+ {
+ tmp = WriteNumber( operand1,sexpon,shidden,smant,slength,err1 );
+ stream << tmp;
+ delete [ ] tmp;
+ }
+
+ if ( NaN2 )
+ NaNresult = 1;
+ else
+ NaNresult = 0;
+ tmp = WriteNumber( operand2,sexpon,shidden,smant,slength,err1 );
+ stream << tmp;
+ delete [ ] tmp;
+ }
+}
+
+
+/*-----------------------------------------------------------------------------
+ name :writeUCBresult()
+ description :writes result or destination of the operation in UCB format
+ called from :writeUCB
+ calls fns :writeUCBresultBin(),writeUCBresultDec(),writeUCBresultNum()
+ Global var. used :/
+ -----------------------------------------------------------------------------*/
+void writeUCBresult(int m,ostrstream &stream)
+{
+ if ( ( intstr != NULL ) && ( opcode == 'r' ) )
+ {
+ stream << " ";
+ if ( pre )
+ stream << "?";
+ stream << intstr;
+ if ( post )
+ stream << "?";
+ } else if ( opcode == 'b' )
+ {
+ writeUCBresultBin(m,stream);
+ }else if ( opcode == 'd' )
+ {
+ writeUCBresultDec(m,stream);
+ }else
+ {
+ writeUCBresultNum(stream);
+ }
+}
+
+
+/*-----------------------------------------------------------------------------
+ name :writeUCBresultBin()
+ description :round and write the destination for binary to decimal conversion
+ called from :writeUCBresult()
+ calls fns :
+ Global var. used :/
+ -----------------------------------------------------------------------------*/
+void writeUCBresultBin(int m,ostrstream &stream)
+{
+ // check rounding mode
+ stream << " ";
+ switch( m ) {
+ case 0 :
+ switch ( nextdig ) {
+ case 0:
+ case 1:
+ case 2:
+ case 3:
+ case 4:
+ stream << decimal;
+ break;
+ default:
+ stream << updecimal;
+ break;
+ }
+ break;
+ case 1 :
+ stream << decimal;
+ break;
+ case 2 :
+ if ( mysignbit ) // negative
+ stream << decimal;
+ else
+ stream << updecimal;
+ break;
+ case 3 :
+ if ( mysignbit )
+ stream << updecimal;
+ else
+ stream << decimal;
+ break;
+ default:
+ exit( 1 );
+ }
+}
+
+/*-----------------------------------------------------------------------------
+ name :writeUCBresultDec()
+ description :writes deatination for decimal to binary conversion
+ called from :writeUCBresult()
+ calls fns :
+ Global var. used :/
+ -----------------------------------------------------------------------------*/
+void writeUCBresultDec(int m,ostrstream &stream)
+{
+int source;
+char *tmp;
+ // check rounding mode
+ if ( pre )
+ stream << "?";
+
+ if ( NaN3 )
+ NaNresult = 1;
+ else
+ NaNresult = 0;
+
+ for ( long i = 0; i < dlength; i++ )
+ operand1[ i ] = result[ i ];
+
+ if ( nextdig )
+ {
+ source=0; //for destination
+ initialize_values(source);
+ Incr( operand1, 1);
+ }
+ switch( m ) {
+ case 0 :
+ switch ( nextdig ) {
+ case 0:
+ case 1:
+ tmp = WriteNumber( result,dexpon,dhidden,dmant,dlength,err3 );
+ stream << tmp;
+ delete [ ] tmp;
+ break;
+ default:
+ tmp = WriteNumber( operand1,dexpon,dhidden,dmant,dlength,err3 );
+ stream << tmp;
+ delete [ ] tmp;
+ break;
+ }
+ break;
+ case 1 :
+ tmp = WriteNumber( result,dexpon,dhidden,dmant,dlength,err3 );
+ stream << tmp;
+ delete [ ] tmp;
+ break;
+ case 2 :
+ if ( mysignbit )
+ {// negative
+ tmp = WriteNumber( result,dexpon,dhidden,dmant,dlength,err3 );
+ stream << tmp;
+ delete [ ] tmp;
+ } else
+ {
+ tmp = WriteNumber( operand1,dexpon,dhidden,dmant,dlength,err3 );
+ stream << tmp;
+ delete [ ] tmp;
+ }
+ break;
+ case 3 :
+ if ( mysignbit )
+ {
+ tmp = WriteNumber( operand1,dexpon,dhidden,dmant,dlength,err3 );
+ stream << tmp;
+ delete [ ] tmp;
+ } else
+ {
+ tmp = WriteNumber( result,dexpon,dhidden,dmant,dlength,err3 );
+ stream << tmp;
+ delete [ ] tmp;
+ }
+ break;
+ default:
+ exit( 1 );
+ }
+ if ( post )
+ stream << "?";
+}
+
+/*-----------------------------------------------------------------------------
+ name :writeUCBresultNum()
+ description :writes desination for operations other than b2d and d2b
+ called from :writeUCBresult()
+ calls fns :
+ Global var. used :/
+ -----------------------------------------------------------------------------*/
+void writeUCBresultNum(ostrstream &stream)
+{
+ char *tmp;
+ if ( pre )
+ stream << "?";
+ if ( NaN3 )
+ NaNresult = 1;
+ else
+ NaNresult = 0;
+ tmp = WriteNumber( result,dexpon,dhidden,dmant,dlength,err3 );
+
+ stream << tmp;
+ delete [ ] tmp;
+ if ( post )
+ stream << "?";
+}
+
+/*-----------------------------------------------------------------------------
+ name :writeUCBcomutative()
+ description :if + or * then writes test vector to check comutativity and
+ calls functions to check the test vectors generated
+ called from :writeUCB
+ calls fns :ucb.ReadLine(),ucb.DoLine()
+ Global var. used :/
+ -----------------------------------------------------------------------------*/
+void writeUCBcomutative(ostrstream &stream)
+{
+ char* outputStream = stream.str( );
+ string outputStream2;
+ string op1,op2;
+
+ if ( opcode=='+' || opcode=='*' )
+ {
+ // if the operation is add or mult we have to
+ // generate second line with operands switched places
+ // in order to check correctness with concern to
+ // commutativity law.
+
+ int i,j,k;
+ outputStream2 = string( stream.str( ) );
+
+ switch (outputStream2[3])
+ {
+ case 's':
+ i= FindNextSpace( outputStream2,10,1 );
+ j= FindNextSpace( outputStream2,i+1,1 );
+ op1= outputStream2.substr( i+1,j-i );
+ k= FindNextSpace( outputStream2, j+1,1 );
+ op2= outputStream2.substr( j+1,k-j );
+ outputStream2.replace( i+1,op2.length( ),op2 );
+ outputStream2.replace( i+1+op2.length( ),op1.length( ),op1 );
+ break;
+
+ case 'd':
+ i= FindNextSpace( outputStream2,10,1 );
+ j= FindNextSpace( outputStream2,i+1,2 );
+ op1= outputStream2.substr( i+1,j-i );
+ k= FindNextSpace( outputStream2, j+1,2 );
+ op2= outputStream2.substr( j+1,k-j );
+ outputStream2.replace( i+1,op2.length( ),op2 );
+ outputStream2.replace( i+1+op2.length( ),op1.length( ),op1 );
+ break;
+
+ case 'q':
+ i= FindNextSpace( outputStream2,10,1 );
+ j= FindNextSpace( outputStream2,i+1,4 );
+ op1= outputStream2.substr( i+1,j-i );
+ k= FindNextSpace( outputStream2, j+1,4 );
+ op2= outputStream2.substr( j+1,k-j );
+ outputStream2.replace( i+1,op2.length( ),op2 );
+ outputStream2.replace( i+1+op2.length( ),op1.length( ),op1 );
+ break;
+
+ case 'l':
+ i= FindNextSpace( outputStream2,10,1 );
+ j= FindNextSpace( outputStream2,i+1,3 );
+ op1= outputStream2.substr( i+1,j-i );
+ k= FindNextSpace( outputStream2, j+1,3 );
+ op2= outputStream2.substr( j+1,k-j );
+ outputStream2.replace( i+1,op2.length( ),op2 );
+ outputStream2.replace( i+1+op2.length( ),op1.length( ),op1 );
+ break;
+
+ case 'm':
+ i= FindNextSpace( outputStream2,10,1 );
+ j= FindNextSpace( outputStream2,i+1,8 );
+ op1= outputStream2.substr( i+1,j-i );
+ k= FindNextSpace( outputStream2, j+1,8 );
+ op2= outputStream2.substr( j+1,k-j );
+ outputStream2.replace( i+1,op2.length( ),op2 );
+ outputStream2.replace( i+1+op2.length( ),op1.length( ),op1 );
+
+ default:
+ // mantsize and expsize were given explicitly
+
+ int opLength=smant+sexpon+1;
+ int blocks;
+
+ // Calculate operand length as multiple of 32
+ opLength= ( opLength/32 ) *32 + ( !( !( opLength%32 ) ) ) * 32;
+
+ // Calculate nr of 32 bit blocks for operand
+ blocks=opLength/32;
+
+ // grep operand 1 out of the outputstream
+ i= FindNextSpace( outputStream2,0,6 ); // find 6th space
+ j= FindNextSpace( outputStream2,i+1,blocks );
+ op1= outputStream2.substr( i+1,j-i );
+
+ // grep operand 2 out of the outputstream
+ k= FindNextSpace( outputStream2, j+1, blocks );
+ op2= outputStream2.substr( j+1,k-j );
+
+ // switch operand1 and operand2
+ outputStream2.replace( i+1,op2.length( ),op2 );
+ outputStream2.replace( i+1+op2.length( ),op1.length( ),op1 );
+
+ break;
+ }
+ }
+ if ( check == 0 && !skipVector )
+ {
+ fprintf( output,outputStream );
+ if ( opcode=='+' || opcode=='*' )
+ {
+ if ( !( op1==op2 ) )
+ {
+ // generate line with operands switched to test commutivity
+ fprintf( output,outputStream2.c_str( ) );
+ }
+ }
+ } else
+ {
+ if (!skipVector)
+ {
+ int tempLines=( int ) lines_in+readings+1;
+
+ ucb.ReadLine( outputStream,signedZero,noFlags,&tempLines );
+ ucb.DoLine( tiny,inf,NaN );
+
+ if ( opcode=='+' || opcode=='*' )
+ {
+ if ( !( op1==op2 ) )
+ {
+ // generate line with operands switched to test commutivity
+ ucb.ReadLine( ( char* ) outputStream2.c_str( ), signedZero, noFlags, &tempLines );
+ ucb.DoLine( tiny,inf,NaN);
+ }
+ }
+ }
+ }
+ delete [ ] outputStream;
+}
+
+
+
+
+
+/*-----------------------------------------------------------------------------
+name :putDot()
+description :Slam a dot out to show some life
+called from :readAline()
+call fns :/
+exceptions :/
+algorithm :/
+Global var. used :/
+-----------------------------------------------------------------------------*/
+
+
+void putDot( )
+{
+ cout << '.' << flush;
+ ++dots;
+ if ( dots > 78 )
+ {
+ cout << endl;
+ dots = 0;
+ }
+}
+
+
+
+
+
+/*-----------------------------------------------------------------------------
+name :FindNextSpace()
+description :to find location to stream with proper spaces
+called from :readAline()
+call fns :/
+exceptions :/
+algorithm :
+Global var. used :/
+-----------------------------------------------------------------------------*/
+
+int FindNextSpace( string pstring , int beginpos, int occurance )
+{
+
+ int i=beginpos;
+ while ( i<pstring.length( ) )
+ {
+ if ( pstring[ i ] ==' ' )
+ {
+ occurance--;
+ if ( occurance==0 )
+ return i;
+ }
+ i++;
+ }
+ return i;
+}
+
+
+
+/*-----------------------------------------------------------------------------
+name :skipSpace()
+description :avoid spaces while reading a vector
+called from :readAline()
+call fns :mygetc(),myungetc()
+exceptions :/
+algorithm :/
+Global var. used :/
+-----------------------------------------------------------------------------*/
+void skipSpace( )
+{
+ char c;
+ while ( isspace( c = mygetc( input ) ) ) {
+ if ( c=='\n' )
+ lines_in++;
+ ;
+ }
+ myungetc( c, input );
+}
+
+
+
+
+
+/*-----------------------------------------------------------------------------
+name :getModes()
+description :get rounding modes from the test vector
+called from :readAline()
+call fns :mygetc(),myungetc()
+exceptions :/
+algorithm :
+Global var. used :round,testmodes,flushVector
+-----------------------------------------------------------------------------*/
+
+void getModes( )
+{
+ char c;
+ testModes = flushVector = 0;
+ while ( !isspace( c = mygetc( input ) ) )
+ switch ( c ) {
+ case 'A': // all rounding modes
+ c = mygetc( input ); /* skip 'LL' */
+ case 'U':
+ if ( Round & ROUND_ZERO )
+ testModes |= ( 1 << TD_TOWARDZERO );
+ if ( Round & ROUND_NEAREST )
+ testModes |= ( 1 << TD_TONEAREST );
+ if ( Round & ROUND_DOWN )
+ testModes |= ( 1 << TD_DOWNWARD );
+ if ( Round & ROUND_UP )
+ testModes |= ( 1 << TD_UPWARD );
+ c = mygetc( input );
+ break;
+ case '0':
+ if ( Round & ROUND_ZERO )
+ testModes |= ( 1 << TD_TOWARDZERO );
+ break;
+ case '=':
+ if ( Round & ROUND_NEAREST )
+ testModes |= ( 1 << TD_TONEAREST );
+ break;
+ case '<':
+ if ( Round & ROUND_DOWN )
+ testModes |= ( 1 << TD_DOWNWARD );
+ break;
+ case '>':
+ if ( Round & ROUND_UP )
+ testModes |= ( 1 << TD_UPWARD );
+ break;
+ case 'o':
+ testFormats = TESTODD;
+ break;
+ case 'e':
+ testFormats = TESTEVEN;
+ break;
+ default:
+ printf( "\n\nError on line %ld of inputfile.",lines_in+readings+1 );
+ printf( "\nERROR: unrecognizable mode character: %c\n", c );
+ printf( "\n\nDone with %ld readings.\n", readings );
+ exit( EXIT_SUCCESS );
+ break;
+ }
+ myungetc( c, input );
+ if ( testFormats == 0 )
+ testFormats = ALL_FORMATS;
+}
+
+
+/*-----------------------------------------------------------------------------
+name :initialize_values()
+description :assigns values to global variables for precision parsed
+ from the command line.
+called from :readAline()
+call fns :/
+exceptions :/
+algorithm :
+Global var. used :expon,hidden,mant,length,rest,sign_exp_length,
+ kl_biased_exp,exp_rest.
+-----------------------------------------------------------------------------*/
+void initialize_values( int source)
+{
+ if (source ==1)
+ {
+ expon = sexpon;
+ hidden = shidden;
+ mant = smant;
+ length = slength;
+ rest = srest;
+ sign_exp_length = ssign_exp_length;
+ kl_biased_exp = skl_biased_exp;
+ sign_exp_rest = ssign_exp_rest ;
+ }
+
+ else //destnation
+ {
+ expon = dexpon;
+ hidden = dhidden;
+ mant = dmant;
+ length = dlength;
+ rest = drest;
+ sign_exp_length = dsign_exp_length;
+ kl_biased_exp = dkl_biased_exp;
+ sign_exp_rest = dsign_exp_rest ;
+ }
+}
+
+
+
+
+
+/*-----------------------------------------------------------------------------
+name :getExceptions()
+description :gets exceptions raised for the test vector
+called from :readAline()
+call fns :
+exceptions :/
+algorithm :
+Global var. used :skipVector,jumpOverflow,jumpUnderflow,jumpInvalid,jumpDivZero
+-----------------------------------------------------------------------------*/
+void getExceptions( )
+{
+ char c;
+
+ xcp = 0;
+ while ( !isspace( c = mygetc( input ) ) ) {
+ switch ( c ) {
+ case 'x':
+ xcp |= ( long ) TD_INEXACT;
+ break;
+ /*
+ * In the Metro case, checking tininess before rounding to detect
+ * underflow means that all possible cases of underflow apply.
+ * (By contrast, checking AFTER rounding lets some boundary cases
+ * slip by, and checking for EXTRAORDINARY error due to subnormalization
+ * lets some tiny cases through that happen to round the same in
+ * spite of subnormalization.
+ */
+
+ case 'u':
+ xcp |= ( long ) TD_UNDERFLOW;
+ if (jumpUnderflow)
+ skipVector=1;
+ break;
+ case 'v':
+ xcp |= ( long ) TD_UNDERFLOWV;
+ if (jumpUnderflow)
+ skipVector=1;
+ break;
+ case 'w':
+ xcp |= ( long ) TD_UNDERFLOWW;
+ if (jumpUnderflow)
+ skipVector=1;
+ break;
+ case 'o':
+ xcp |= ( long ) TD_OVERFLOW;
+ if (jumpOverflow)
+ skipVector=1;
+ break;
+ case 'i':
+ xcp |= ( long ) TD_INVALID;
+ if (jumpInvalid)
+ skipVector=1;
+ break;
+ case 'z':
+ xcp |= ( long ) TD_DIVBYZERO;
+ if (jumpDivZero)
+ skipVector=1;
+ break;
+ case 'O':
+ c = mygetc( input );
+ /* skip the 'OK' */
+ break;
+ default:
+ printf( "\n\nError on line %ld of inputfile.",lines_in+readings+1 );
+ printf( "\nERROR: unrecognizable exception character: %c\n", c );
+ printf( "\n\nDone with %ld readings.\n", readings );
+ exit( EXIT_SUCCESS );
+ break;
+ }
+ }
+ myungetc( c, input );
+}
+
+
+/*-----------------------------------------------------------------------------
+name :getbinary()
+description :reads the binary coded number form the test set //ONLY FOR CONVERSIONS
+called from :readAline()
+call fns :mygetc(),myungetc(),skipSpaces()
+exceptions :/
+algorithm :
+Global var. used :length,rest,sign_exp_length,exp_rest,pre,binary,upbinary,nextdig
+-----------------------------------------------------------------------------*/
+void getbinary( unsigned long *number)
+{
+ long i= 0;
+ NaNresult = 0;
+
+ for ( i=0; i<length;i++ ) // init number
+ number[ i ] =0;
+
+ mysignbit=getSign();
+
+ getBsignificant(number);
+
+ getBbias(number);
+
+/* Stuff the sign nonarithmetically, to protect signaling NaNs. */
+ if ( mysignbit )
+ number[ 0 ] |= 0x80000000L;
+}
+
+
+/*-----------------------------------------------------------------------------
+ name :getBsignificant()
+ description :get significant of the binary number
+ called from :getbinary()
+ calls fns :
+ exceptions :/
+ algorithm :
+Global var. used :/
+ -----------------------------------------------------------------------------*/
+void getBsignificant(unsigned long *number)
+{
+ int i,j,k=0,val=0;
+ char c=mygetc(input);
+ binary = new char[ maxstr ];
+
+ i = 0;
+ while ( !isspace( c ) && ( c != '_' ) )
+ {
+ binary[ i++ ] = c;
+ c = mygetc( input );
+ }
+ nextdig = 0; // exact
+ if ( c == '_' )
+ {
+ if ( mygetc( input ) == '1' )
+ {
+ nextdig = 2;
+ if ( mygetc( input ) == '1' )
+ nextdig++;
+ } else
+ nextdig = 1;
+ }
+ while ( !isspace( c ) ) c = mygetc( input ); // skip tail
+ skipSpace( );
+
+ // copy binary per 4 bits for each hex input character
+ i--; // binary length (times 4 bits)
+ j = length - 1;
+
+ while ( i - 7 >= 0 )
+ {
+ if ( isdigit( binary[ i-7 ] ) )
+ val = binary[ i-7 ] - '0';
+ else
+ val = 0xa + ( binary[ i-7 ] - 'a' );
+ number[ j ] += val;
+ for ( k = 6;k >= 0;k-- )
+ {
+ number[ j ] *= 16;
+ if ( isdigit( binary[ i-k ] ) )
+ val = binary[ i-k ] - '0';
+ else
+ val = 0xa + ( binary[ i-k ] - 'a' );
+ number[ j ] += val;
+ }
+
+ i -= 8;
+ j--;
+ }
+ if ( i >= 0 )
+ {
+ for ( k = 0;k < i;k++ )
+ {
+ if ( isdigit( binary[ k ] ) )
+ val = binary[ k ] - '0';
+ else
+ val = 0xa + ( binary[ k ] - 'a' );
+ number[ j ] += val;
+ number[ j ] *= 16;
+ }
+
+ if ( isdigit( binary[ k ] ) )
+ val = binary[ k ] - '0';
+ else
+ val = 0xa + ( binary[ k ] - 'a' );
+ number[ j ] += val;
+ }
+ if ( rest != 0 )
+ {
+ i = sign_exp_length - 1;
+ for ( ; i<length-1;i++ )
+ for ( j = 0;j < NO_OF_BITS - rest;j++ )
+ {
+ number[ i ] *= 2;
+ if ( number[ i+1 ] & ( 1L << ( (NO_OF_BITS-1) - j ) ) )
+ number[ i ] ++;
+ }
+ for ( j = 0;j < NO_OF_BITS - rest;j++ )
+ number[ i ] *= 2;
+ }
+
+ if ( ( hidden ) && ( number[ 0 ] != 0 ) ) // remove leading bit, if not zero!
+ {
+ if ( sign_exp_rest==(NO_OF_BITS-1) )
+ number[ sign_exp_length ] -= ( 1L<<(NO_OF_BITS-1) );
+ else
+ number[ sign_exp_length-1 ] -= ( 1L<<( NO_OF_BITS-sign_exp_rest-1 ) );
+ }
+}
+
+
+/*-----------------------------------------------------------------------------
+ name :getBbias()
+ description :gets bias for the binary number
+ called from :getbinary()
+ calls fns :getBexpon()
+ exceptions :/
+ algorithm :
+Global var. used :/
+ -----------------------------------------------------------------------------*/
+void getBbias(unsigned long *number)
+{
+ int i,j,k;
+ long u=0;
+
+ u=getBexpon();
+
+ unsigned long * bias = new unsigned long[ sign_exp_length ];
+ if ( bias == NULL )
+ exitmem( );
+ for ( i=1; i<sign_exp_length;i++ )
+ bias[ i ] =0xFFFFFFFFL;
+ bias[ 0 ] =0x3FFFFFFFL;
+ if ( sign_exp_length > 1 )
+ bias[ sign_exp_length-1 ] <<= ( NO_OF_BITS-sign_exp_rest-1 );
+ else
+ bias[ 0 ] =( unsigned long ) ( ((unsigned long)1 << (expon-1)) -1 ) << ( NO_OF_BITS-sign_exp_rest-1 );
+ // add exp to bias
+ while ( u > 0 )
+ { // positive exp
+ bias[ sign_exp_length-1 ] += ( 1L << ( NO_OF_BITS-sign_exp_rest-1 ) );
+ k=sign_exp_length-1;
+ while ( bias[ k ] ==0 )
+ {
+ k--;
+ bias[ k ] += 1;
+ }
+ k=sign_exp_length-1;
+ u--;
+ }
+ while ( u < 0 )
+ { // negative exp
+ k=sign_exp_length-1;
+ while ( bias[ k ] ==0 )
+ {
+ k--;
+ bias[ k ] -= 1;
+ }
+ bias[ sign_exp_length-1 ] -= ( 1L << ( NO_OF_BITS-sign_exp_rest-1 ) );
+ u++;
+ }
+
+ // copy bias into number
+ for ( i=0;i<sign_exp_length-1;i++ )
+ number[ i ] = bias[ i ];
+ /*
+ if (kl_biased_exp > 0) // change kl_biased_exp
+ number[sign_exp_length-1] &= kl_biased_exp-1;
+ */
+ number[ sign_exp_length-1 ] |= bias[ sign_exp_length-1 ];
+ delete[ ] bias;
+
+}
+
+
+/*-----------------------------------------------------------------------------
+ name :getBexpon
+ description :gets exponent for the binary number
+ called from :getBbias()
+ calls fns :
+ exceptions :/
+ algorithm :
+ Global var. used :/
+ -----------------------------------------------------------------------------*/
+long int getBexpon()
+{
+ char c;
+ unsigned long signexp = 0;
+ long u=0;
+ c=mygetc( input ); // skip 'E' character
+ c=mygetc( input );
+ if ( c == '-' )
+ {
+ signexp = 1;
+ c = mygetc( input );
+ } else if ( c == '+' )
+ {
+ c = mygetc( input );
+ }
+
+ while ( isdigit( c ) )
+ {
+ u = ( u * 10 ) + ( c - '0' );
+ c = mygetc( input );
+ } // while
+ myungetc( c, input ); // for EOL
+ if ( signexp )
+ u = -u;
+ return u;
+}
+
+
+
+
+
+/*-----------------------------------------------------------------------------
+name :getdecimal()
+description :get decimal coded number form testset // ONLY FOR CONVERSION
+called from :readAline()
+call fns :getDsignificand(),getDexpon
+exceptions :/
+algorithm :
+Global var. used :decimal,updecimal,nextdig
+-----------------------------------------------------------------------------*/
+
+void getdecimal( )
+{
+ getDsignificand(); //i is the position till which
+ //significant has occupied decimal[]
+ getDexpon();
+}
+
+
+
+/*-----------------------------------------------------------------------------
+name :getDsignificand()
+description :get significand of decimal coded number
+called from :getdecimal()
+call fns :mygetc(),myungetc()
+exceptions :/
+algorithm :
+Global var. used :decimal,updecimal,nextdig,incexp
+-----------------------------------------------------------------------------*/
+
+void getDsignificand()
+{ // get significand
+ posDec = 0,posUpDec = 0;
+ incexp = 0;
+ char c;
+ c = mygetc( input );
+
+ while ( !isspace( c ) && ( c != '_' ) )
+ {
+ decimal[ posDec ] = c;
+ updecimal[ posDec++ ] = c;
+ c = mygetc( input );
+ }
+ if ( c == '_' ) //find next number for case of 9's in end
+ {
+ posUpDec = posDec-1; // or all 9's .
+ while ( ( posUpDec > 1 ) && ( updecimal[ posUpDec ] == '9' ) )
+ updecimal[ posUpDec-- ] = '0';
+ if ( updecimal[ posUpDec ] == '9' )
+ {
+ updecimal[ 1 ] = '1';
+ for ( posUpDec = 2; posUpDec <= posDec; posUpDec++ )
+ updecimal[ posUpDec ] = '0';
+ incexp = 1;
+ } else
+ updecimal[ posUpDec ] = ( int ) updecimal[ posUpDec ] + 1;
+ nextdig = mygetc( input ) - '0';
+ c = mygetc( input );
+ while ( !isspace( c ) ) c = mygetc( input ); // skip tail
+ } else
+ {
+ nextdig = 0;
+ }
+}
+
+/*-----------------------------------------------------------------------------
+name :getDexpon()
+description :get exponent of decimal coded number
+called from :getdecimal()
+call fns :mygetc(),myungetc(),exceptions :/
+algorithm :
+Global var. used :decimal,updecimal,nextdig,incexp
+-----------------------------------------------------------------------------*/
+void getDexpon()
+{
+ char signexp,c;
+ c = mygetc( input );
+
+ if ( c == 'E' ) // get exponent
+ {
+ decimal[ posDec ] = c;
+ updecimal[ posDec++ ] = c;
+ c = mygetc( input );
+ signexp = c;
+ while ( !isspace( c ) )
+ {
+ decimal[ posDec ] = c;
+ updecimal[ posDec++ ] = c;
+ c = mygetc( input );
+ }
+ decimal[ posDec ] = '\0';
+ posUpDec = posDec;
+
+ if ( incexp )
+ {
+ if ( signexp != '-' ) // inc exponent
+ {
+ posDec--;
+ while ( updecimal[ posDec ] == '9' )
+ {
+ updecimal[ posDec ] = 0;
+ posDec--;
+ }
+ if ( updecimal[ posDec ] == 'E' )
+ {
+ updecimal[ posDec+1 ] = '1';
+ updecimal[ posUpDec++ ] = '0';
+ } else
+ {
+ updecimal[ posDec ] = ( int ) updecimal[ posDec ] + 1;
+ }
+ } else // dec exponent
+ {
+ posDec--;
+ while ( updecimal[ posDec ] == '0' )
+ {
+ updecimal[ posDec ] = 9;
+ posDec--;
+ }
+ updecimal[ posDec ] = ( int ) updecimal[ posDec ] - 1;
+ }
+ } // if
+ }else
+ {
+ myungetc( c,input );
+ }
+ updecimal[ posUpDec ] = '\0';
+ myungetc( c, input );
+}
+
+
+/*-----------------------------------------------------------------------------
+name :getNumber
+description :takes the coded number and precsion to get the number
+called from :readAline()
+call fns :getSign(), getFPRootNumber(),getModifier()
+exceptions :/
+algorithm :
+Global var. used :HexNoIsGiven,cant_infinity,small_norm,NaNresult
+-----------------------------------------------------------------------------*/
+
+
+void getNumber( unsigned long *number)
+{
+
+ unsigned long i, k, pos;
+ char c,capc,d,ch;
+
+ int signbit=0;
+ HexNoIsGiven=0; //initialize global variable
+ cant_infinity=0, small_norm=0; //initialize global variable
+ NaNresult = 0; // change DV
+
+ for ( i=0; i<length;i++ ) // number initialized to 0
+ number[ i ] =0;
+
+ signbit=getSign();
+
+ getFPRootNumber(number);
+
+ if (HexNoIsGiven) return ;
+ /* if hexadecimal number is given as operand then save
+ the number to the global char *intstr and exit this function */
+
+ getModifier(number);
+
+ /* Stuff the sign nonarithmetically, to protect signaling NaNs. */
+ if (signbit) // checksign() is to get the sign of sign of number
+ number[ 0 ] |= 0x80000000L;
+}
+
+
+
+/*-----------------------------------------------------------------------------
+name :WriteNumber()
+description :Inserts correct number of zeros at most significant posiotion.
+called from :readAline()
+call fns :/
+Global var. used :length,nanresult
+-----------------------------------------------------------------------------*/
+
+
+char* WriteNumber( const unsigned long *number, unsigned long expon,
+ unsigned long hidden, unsigned long mant, unsigned long length,const int err )
+{
+ unsigned long i;
+ ostrstream stream;
+
+ if ( !err ) {
+ for ( i=0; i<length;i++ )
+ // stream << " "<< setw(8) << setfill('0') << hex << number[i];
+ if ( number[ i ] >= 0x10000000 )
+ stream << " " << hex << number[ i ];
+ else if ( number[ i ] >= 0x01000000 ) {
+ stream << " 0" << hex << number[ i ];
+ } else if ( number[ i ] >= 0x00100000 ) {
+ stream << " 00" << hex << number[ i ];
+ } else if ( number[ i ] >= 0x00010000 ) {
+ stream << " 000" << hex << number[ i ];
+ } else if ( number[ i ] >= 0x00001000 ) {
+ stream << " 0000" << hex << number[ i ];
+ } else if ( number[ i ] >= 0x00000100 ) {
+ stream << " 00000" << hex << number[ i ];
+ } else if ( number[ i ] >= 0x00000010 ) {
+ stream << " 000000" << hex << number[ i ];
+ } else {
+ stream << " 0000000" << hex << number[ i ];
+ }
+ } else {
+ stream<< " Fout invoernumber";
+ err_form=1;
+ }
+ if ( NaNresult )
+ stream << '?';
+
+ stream << ends;
+ return stream.str( );
+}
+
+
+
+/*-----------------------------------------------------------------------------
+name :getSign()
+description :checks if the sign of a number is + or negative ... by default it returns + .
+called from :getNumber()
+call fns :/ //mygetc()
+exceptions :/
+algorithm :
+Global var. used :pre
+-----------------------------------------------------------------------------*/
+int getSign(){
+ char c;
+ int signBit=0; //default takes positive
+ c = mygetc( input );
+ switch(c){
+ case '-' :
+ signBit=1;
+ return signBit;
+ break;
+ case '+' :
+ signBit=0;
+ return signBit;
+ break;
+ case '?' :
+ pre=1;
+ break;
+
+ default :
+ myungetc(c,input);
+ return signBit;
+ break;
+ }
+}
+
+/*-----------------------------------------------------------------------------
+name :getFPRootNumber
+description :extracts the rootnumber from the coded number
+called from :getNumber()
+calls fns :Infinity(),Quiet_NaN(),Signaling_NaN(),smallest_Norm(),getFPHexNo(),getFPInteger()
+exceptions :/
+algorithm :
+Global var. used :cant_infinity,killerVector,small_norm,NaNresult,HexNoIsGiven
+-----------------------------------------------------------------------------*/
+void getFPRootNumber( unsigned long *number)
+{
+ char c,d;
+ c = mygetc( input );
+ switch (c)
+ {
+ case 'H':
+ Infinity( number);
+ cant_infinity=1;
+ break;
+ case 'Q':
+ Quiet_NaN( number);
+ killerVector = 1; /* change BV */
+ NaNresult = 1; // change DV
+ break;
+ case 'S':
+ Signaling_NaN( number);
+ killerVector = 1; /* change BV */
+ NaNresult = 1;
+ break;
+ case 'E': // this 'E' is given for compatibility with Coonen vectors
+ case 'T':
+ Smallest_Norm( number);
+ small_norm=1; // indien er een number volgt op T, dan kan via deze
+ // variabele gezien worden of er een plus (voor T)
+ // of een minus (voor H, zie aldaar) moet gebeuren
+ break;
+ case '0':
+ d = mygetc( input );
+ if ( d == 'x' ) //hexadecimal number
+ {
+ getFPHexNo(); //save Hexadecimal no. in intstr[]
+ HexNoIsGiven=1;
+ }
+ else
+ {
+ myungetc(d,input);
+ myungetc(c,input);
+ getFPInteger( number);
+ }
+ break;
+ default:
+ if ( isdigit( c ) )
+ {
+ myungetc(c,input);
+ getFPInteger( number);
+ } else
+ {
+ printf( "\n\nError on line %ld of inputfile.",lines_in+readings+1 );
+ printf( "\ngetNumber() ERROR: %c is an unknown number specifier in getNumber\n", c );
+ printf( "\n\nDone with %ld readings.\n", readings );
+ exit( EXIT_SUCCESS );
+ }
+ }
+}
+
+
+/*-----------------------------------------------------------------------------
+ name :getModifier
+ description :Modifies the rootnumber
+ called from :getNumber()
+ calls fns :ModifierPorM(),ModifierIorD(),ModifierU()
+ exceptions :/
+ algorithm :
+Global var. used :/
+ -----------------------------------------------------------------------------*/
+
+
+
+void getModifier(unsigned long *number)
+{
+ unsigned long k;
+ int McasePorM,McaseIorD;
+ char c;
+
+ while ( !isspace( c = mygetc( input ) ) )
+ {
+ switch ( c ) {
+ case 'p':
+ McasePorM=0;
+ ModifierPorM(number,McasePorM);
+ break;
+ case 'm' :
+ McasePorM=1;
+ ModifierPorM(number,McasePorM);
+ break;
+ case 'i' :
+ McaseIorD=0;
+ ModifierIorD(number,McaseIorD);
+ break;
+ case 'd' :
+ McaseIorD=1;
+ ModifierIorD(number,McaseIorD);
+ break;
+ case 'u' :
+ k = getinteger( );
+ ModifierU( number,k);
+ break;
+
+
+ case '0':
+ case '1':
+ case '2':
+ case '3': // indien er hier een cijfer wordt ingelezen, dan
+
+ case '4': // kan dat enkel voorafgegaan zijn door een
+
+ case '5': // H (infinity) of een T (smallest normalized)
+
+ case '6': // if here a figure is read in , then that can
+ // can only be preceded by H(infinty )
+ //or T (smallest normalised)
+ case '7':
+ case '8':
+ case '9':
+ case 't':
+ case 'B':
+ case 'C':
+ if ( ( c != 't' ) && ( c != 'u' ) && ( c!='B' ) && ( c != 'C' ) )
+ k=( long ) atoi( &c );
+ else if ( c == 't' )
+ k = mant + hidden;
+ else if ( c == 'B' )
+ {
+ // k = (unsigned long) (((unsigned long)1 << (expon-1)) - 1);
+ k = ULONG_MAX;
+ cout << "ULONG_MAX :" << ULONG_MAX << endl;
+ } else if ( c == 'u' )
+ k = dmant + dhidden;
+ else if ( c == 'C' )
+ // k = (unsigned long) (((unsigned long)1 << (dexpon-1)) - 1);
+ k = ULONG_MAX;
+ if ( cant_infinity ) // if H
+ Minus(number,k);
+ // PlusBk( number,k);
+ if ( small_norm ) // if T
+ Plus( number,k);
+ break;
+
+
+ default:
+ printf( "\n\nError on line %ld of inputfile.",lines_in+readings+1 );
+ printf( "\ngetNumber() ERROR: unrecognizable modifier character: %c\n", c );
+ printf( "\n\nDone with %ld readings.\n", readings );
+ exit( EXIT_SUCCESS );
+ }
+ }
+ myungetc( c, input );
+}
+
+
+
+
+
+/*-----------------------------------------------------------------------------
+name :getFPHexNo()
+description :this is called if the coded number is hexadecimal . This stores hexadecimal number in intstr[] and quits getNumber().
+called from :getFPRootNumber()
+calls fns :/
+exceptions :/
+algorithm :
+Global var. used : intstr[]
+-----------------------------------------------------------------------------*/
+void getFPHexNo(){
+ long i;
+ char c, capc ;
+ intstr = new char[ 64 ];
+ intstr[ 0 ] = '0';
+ intstr[ 1 ] = 'x';
+ i = 2;
+ for ( capc = toupper( c = mygetc( input ) );
+ ( '0' <= capc && capc <= '9' ) || ( 'A' <= capc && capc <= 'F' );
+ capc = toupper( c = mygetc( input ) ) )
+ {
+ intstr[ i ] = c;
+ i++;
+ }
+ intstr[ i ] = '\0';
+ myungetc(c,input);
+}
+
+
+
+/*-----------------------------------------------------------------------------
+ name :ModifierIorD
+ description :Modifies the rootnumber for case 'i'-increment or case 'd'-decrement
+ called from :getModifier()
+ calls fns :Incr_at_pos(), Incr(),Decr_at_pos(),Decr(),getInteger()
+ exceptions :/
+ algorithm :
+ Global var. used :/
+ -----------------------------------------------------------------------------*/
+
+void ModifierIorD(unsigned long *number,int McaseIorD) {
+ char c;
+
+ unsigned long pos,k;
+ c = mygetc( input );
+ switch ( c ) {
+
+ case '(':
+ pos = getinteger( );
+ c = mygetc( input );
+ switch ( c ) {
+
+ case '+':
+ pos += getinteger( );
+ c = mygetc( input );
+ if ( c == ')' )
+ {
+ k = getinteger( );
+ if (McaseIorD)
+ Decr_at_pos( number,pos,k);
+ else
+ Incr_at_pos( number,pos,k);
+ } else
+ {
+ printf( "\n\nError on line %ld of inputfile.",lines_in+readings+1 );
+ printf( "\ngetNumber() ERROR: unexpected character: %c\n", c );
+ printf( "\n\nDone with %ld readings.\n", readings );
+ exit( EXIT_SUCCESS );
+ } // end if
+ break;
+
+ case '-':
+ pos -= getinteger( );
+ c = mygetc( input );
+ if ( c == ')' )
+ {
+ k = getinteger( );
+ if (McaseIorD)
+ Decr_at_pos( number,pos,k);
+ else
+ Incr_at_pos( number,pos,k);
+ } else
+ {
+ printf( "\n\nError on line %ld of inputfile.",lines_in+readings+1 );
+ printf( "\ngetNumber() ERROR: unexpected character: %c\n", c );
+ printf( "\n\nDone with %ld readings.\n", readings );
+ exit( EXIT_SUCCESS );
+ } // end if
+ break;
+
+ case ')':
+ k = getinteger( );
+ if (McaseIorD)
+ Decr_at_pos( number,pos,k);
+ else
+ Incr_at_pos( number,pos,k);
+ break;
+
+ default:
+ printf( "\n\nError on line %ld of inputfile.",lines_in+readings+1 );
+ printf( "\ngetNumber() ERROR: unexpected character: %c\n", c );
+ printf( "\n\nDone with %ld readings.\n", readings );
+ exit( EXIT_SUCCESS );
+ } // end if
+ break;
+
+ default:
+ myungetc( c, input );
+ k = getinteger( );
+ if (McaseIorD)
+ Decr( number,k);
+ else
+ Incr( number,k);
+ break;
+ } // switch case 'i'
+
+}
+
+
+
+/*-----------------------------------------------------------------------------
+ name :ModifierPorM
+ description :Modifies the rootnumber for case 'p'-plus or case 'm'-minus
+ called from :getModifier()
+ calls fns :Plus(),PLusBk(),Minus(),MinusBk()
+ exceptions :/
+ algorithm :
+ Global var. used :/
+ -----------------------------------------------------------------------------*/
+void ModifierPorM(unsigned long *number,int McasePorM)
+{
+char c,ch;
+unsigned long k=0;
+
+c = mygetc( input );
+ if (c== 'B' || c== 'C' ) //Bias (C is only for conversions)
+ {
+ ch=c;
+ c= mygetc(input);
+ if ((c - '0')>0 && (c - '0')<10)
+ {
+ k=c-'0' ;
+ if (McasePorM)
+ MinusBk( number,k);
+ else
+ PlusBk( number,k);
+ return;
+ } else if ((c - '0') != 0 ) //makes B0 as B
+ myungetc(c,input) ;
+ c=ch;
+ }
+ myungetc( c,input );
+ k = getinteger( );
+ if (McasePorM)
+ Minus(number,k);
+ else
+ Plus(number,k);
+}
+
+
+
+
+/*-----------------------------------------------------------------------------
+name :ModifierU()
+description :operates u<digit>
+called from :getModifier()
+call fns :null_exp(),one_exp()
+exceptions :/
+algorithm :
+Global var. used :sign_exp_length,exp_rest,length,rest,hidden,kl_biased_exp,mant
+-----------------------------------------------------------------------------*/
+
+void ModifierU( unsigned long *number, unsigned long ulps)
+{
+ unsigned long *e, i, exp_all_null, bits_ulps, k, shift_part;
+ int not_done;
+
+ e = new unsigned long[ sign_exp_length ];
+
+ if ( e == NULL ) {
+ printf( "\nNot enough memory in procedure ModifierU!!!\n" );
+ printf( "Program aborted.\n" );
+ fclose( input );
+ fclose( output );
+ delete[ ] operand1;
+ delete[ ] operand2;
+ delete[ ] result;
+ printf( "\n\nError on line %ld of inputfile.",lines_in+readings+1 );
+ printf( "\n\nDone with %ld readings.\n", readings );
+ exit( EXIT_SUCCESS );
+ }
+
+ for ( i=0;i<sign_exp_length-1;i++ )
+ e[ i ] =number[ i ];
+ e[ sign_exp_length-1 ] = ( number[ sign_exp_length-1 ] >> ( (NO_OF_BITS-1)-sign_exp_rest ) );
+ e[ sign_exp_length-1 ] <<= ( (NO_OF_BITS-1)-sign_exp_rest );
+
+
+
+ if ( null_exp( e) ||
+ one_exp( e) )
+ {
+ for ( i=0;i<length;i++ )
+ number[ i ] =0;
+ if ( ulps != 0 )
+ {
+ bits_ulps = ( unsigned long ) floor( ::log10( ulps ) / ::log10( 2 ) ) +1;
+ if ( bits_ulps > mant )
+ {
+ ulps=0;
+ wrong_input=1;
+ }
+ }
+ number[ length-1 ] =ulps;
+
+ if ( rest!=0 )
+ {
+ if ( ( ( bits_ulps > rest ) && hidden ) || ( ( bits_ulps+1 > rest ) && ( !hidden ) ) )
+ number[ length-2 ] = ( ulps >> rest );
+ number[ length-1 ] <<= ( NO_OF_BITS-rest );
+ }
+ }
+ else
+ {
+
+ for ( i=0;i<length;i++ )
+ number[ i ] =0;
+ if ( ulps != 0 )
+ {
+ bits_ulps = ( unsigned long ) floor( ::log10( ulps ) / ::log10( 2 ) ) +1;
+ if ( bits_ulps > mant )
+ {
+ ulps=0;
+ wrong_input=1;
+ }
+ }
+ number[ length-1 ] =ulps;
+
+ if ( rest!=0 )
+ {
+ if ( ( ( bits_ulps > rest ) && hidden ) || ( ( bits_ulps+1 > rest ) && ( !hidden ) ) )
+ number[ length-2 ] = ( ulps >> rest );
+ number[ length-1 ] <<= ( NO_OF_BITS-rest );
+ }
+
+ k=sign_exp_length-1;
+ shift_part=length-1;
+
+ while ( ( hidden && !( number[ sign_exp_length-1 ] & kl_biased_exp ) ) ||
+ ( !hidden && ( ( ( !( number[ sign_exp_length ] & ( 1L<<(NO_OF_BITS-1) ) ) ) &&
+ ( sign_exp_rest == (NO_OF_BITS-1) ) ) ||
+ ( !( number[ sign_exp_length-1 ] & ( kl_biased_exp>>1 ) ) &&
+ ( sign_exp_rest != (NO_OF_BITS-1) ) ) ) )
+ ) {
+ e[ sign_exp_length-1 ] -= ( 1L << ( (NO_OF_BITS-1)-sign_exp_rest ) );
+ k=sign_exp_length-1;
+ while ( k==sign_exp_length-1 ? e[ k ] ==( 0xFFFFFFFFL << ( NO_OF_BITS-sign_exp_rest-1 ) ) : e[ k ] ==0xFFFFFFFFL )
+ {
+ k--;
+ e[ k ] -= 1;
+ }
+ // shift left
+ if ( shift_part!=0 )
+ number[ shift_part-1 ] = ( number[ shift_part-1 ] << 1 ) | ( ( number[ shift_part ] >> (NO_OF_BITS-1) ) & 0x01L );
+ number[ shift_part ] <<= 1;
+ if ( number[ shift_part ] ==0 )
+ shift_part--;
+ i++;
+ } // while
+
+ for ( i=0; i<sign_exp_length-1; i++ )
+ number[ i ] = e[ i ];
+ number[ i ] &= kl_biased_exp-1;
+ number[ i ] |= e[ sign_exp_length-1 ];
+ }
+
+ delete[ ] e;
+}
+
+
+
+
+
+/*-----------------------------------------------------------------------------
+name :getinteger()
+description :gets integer value from the string (also checks for hex no.)
+called from :Modifier(),ModifierIorD(),ModifierPorM()
+call fns :mygetc(),myungetc()
+exceptions :/
+algorithm :
+Global var. used :
+-----------------------------------------------------------------------------*/
+/* Peruse the input stream for an unsigned integer.
+ * Allow the 0xddddd syntax of C integers, and also decimals.
+ */
+
+unsigned long getinteger()
+{
+ char c;
+ unsigned long u = 0;
+
+ u=getHex(); //returns integer value if Hex
+ if (u != 0) return u; // hex no. is given
+
+ //Now the input character c is either a decimal
+ //digit or a terminal. A null number returns as zero.
+
+ c=mygetc(input);
+ switch(c){
+ case 't':
+ u = smant + shidden;
+ break;
+
+
+ case 'B' :
+ u = ( unsigned long ) ( ((unsigned long)1 << (sexpon-1)) - 1 );
+ break;
+
+ case 'u' :
+ u = dmant + dhidden;
+ break;
+
+
+ case 'C' :
+ u = ( unsigned long ) ( ((unsigned long)1 << (dexpon-1)) - 1 );
+ // u = ULONG_MAX;
+ break;
+
+ case 'h' :
+ u = ( mant + hidden + 1 ) / 2 - 1;
+ break;
+
+ default:
+ while ( isdigit( c ) ) {
+ u = ( u * 10 ) + ( c - '0' );
+ c = mygetc( input );
+ }
+ myungetc( c, input );
+ }
+ return u;
+}
+
+
+/*-----------------------------------------------------------------------------
+name :getHex()
+description :gets integer value of Hex no.
+called from :getinteger()
+call fns :mygetc(),myungetc()
+Global var. used :
+-----------------------------------------------------------------------------*/
+unsigned long getHex()
+{
+char c,capc;
+unsigned long u=0;
+c = mygetc( input );
+ if ( c == '0' ) {
+ c = mygetc( input );
+ if ( c == 'x' ) {
+ for ( capc = toupper( c = mygetc( input ) );
+ ( '0' <= capc && capc <= '9' ) || ( 'A' <= capc && capc <= 'F' ); capc = toupper( c = mygetc( input ) ) ) {
+ u <<= 4;
+ if ( isdigit( capc ) )
+ u |= capc - '0';
+ else
+ u |= 0xa + ( capc - 'A' );
+ }
+ myungetc( c, input );
+ return u;
+ }
+ }
+myungetc(c,input);
+return u;
+
+}
+
+
+/*-----------------------------------------------------------------------------
+name :getFPInteger()
+description :get floating ponit integer in IEEE format
+called from :getFPRootNumber()
+call fns :mygetc(),myungetc()
+exceptions :/
+algorithm :
+Global var. used :wrong_input
+-----------------------------------------------------------------------------*/
+
+void getFPInteger( unsigned long *number)
+{
+ char c;
+ unsigned long bits_u, ex, *bias, u=0;
+ long k, i;
+
+ wrong_input=0;
+ c=mygetc( input );
+ while ( isdigit( c ) )
+ {
+ u = ( u * 10 ) + ( c - '0' );
+ c = mygetc( input );
+ } // while
+
+ myungetc( c, input );
+
+ if ( u != 0 )
+ { // determine no. of bits for u
+ bits_u = ( unsigned long ) floor( ::log10( u ) / ::log10( 2 ) ) + 1;
+ if ( bits_u> mant+hidden )
+ {
+ u=0;
+ wrong_input=1; // u greater than maximal value of significand
+ }
+
+ }
+ u &= 0x00FFFFFFL; // limited to 24-bit integer
+ if ( u != 0 )
+ {
+ //determine no. of bits for u (now less than 24)
+ bits_u = ( unsigned long ) floor( ::log10( u ) / ::log10( 2 ) ) + 1;
+
+ if ( !hidden )
+ u |= ( 1L << bits_u ); // put hidden bit in front
+
+ number[ length-1 ] =u;
+
+ if ( rest != 0 )
+ {
+ if ( ( ( bits_u > rest ) && hidden ) || ( ( bits_u+1 > rest ) && ( !hidden ) ) )
+ number[ length-2 ] =( u >> rest ); // if the 2 parts overlap
+ // then the (bits_u-rest) bits that
+ //follow will be added to the previous part
+ number[ length-1 ] <<= ( NO_OF_BITS-rest );
+ }
+
+ if ( hidden )
+ ex=mant;
+ else
+ ex=mant-1;
+
+ k=length-1;
+
+ while ( ( number[ sign_exp_length-1 ] & kl_biased_exp ) ==0 )
+ {
+ if ( k!=0 )
+ number[ k-1 ] = ( number[ k-1 ] << 1 ) | ( ( number[ k ] >> (NO_OF_BITS-1) ) & 0x01L );
+
+ number[ k ] <<= 1;
+ ex--;
+
+ if ( number[ k ] ==0 )
+ k--;
+ }
+
+ bias = new unsigned long[ sign_exp_length ];
+
+ if ( bias == NULL )
+ {
+ printf( "\nNot enough memory in procedure getFPInteger!!!\n" );
+ printf( "Program aborted.\n" );
+ fclose( input );
+ fclose( output );
+ delete[ ] operand1;
+ delete[ ] operand2;
+ delete[ ] result;
+ printf( "\n\nError on line %ld of inputfile.",lines_in+readings+1 );
+ printf( "\n\nDone with %ld readings.\n", readings );
+ exit( EXIT_SUCCESS );
+ }
+
+ for ( i=0; i<sign_exp_length;i++ )
+ bias[ i ] =0;
+
+ for ( i=1; i<sign_exp_length;i++ )
+ bias[ i ] =0xFFFFFFFFL;
+ bias[ 0 ] =0x3FFFFFFFL;
+
+ if ( sign_exp_length > 1 )
+ bias[ sign_exp_length-1 ] <<= ( NO_OF_BITS-sign_exp_rest-1 );
+ else
+ bias[ 0 ] =( unsigned long ) ( ((unsigned long)1 << (expon-1)) -1 ) << ( NO_OF_BITS-sign_exp_rest-1 );
+
+ //add rest of exponent to bias
+ k=sign_exp_length-1;
+
+ for ( i=0;i<ex;i++ )
+ {
+ bias[ sign_exp_length-1 ] += ( 1L << ( NO_OF_BITS-sign_exp_rest-1 ) );
+ while ( bias[ k ] ==0 )
+ {
+ k--;
+ bias[ k ] += 1;
+ }
+ k=sign_exp_length-1;
+ }
+
+ // determine Exponent of number[] by assigning number[] =bias[]
+ for ( i=0;i<sign_exp_length-1;i++ )
+ number[ i ] =bias[ i ];
+
+ if ( kl_biased_exp > 0 ) // change kl_biased_exp
+ number[ sign_exp_length-1 ] &= kl_biased_exp-1;
+
+ number[ sign_exp_length-1 ] |= bias[ sign_exp_length-1 ];
+
+ delete[ ] bias;
+ }
+}
+
+
+
+/*-----------------------------------------------------------------------------
+name :Infinity()
+description :Sets a number to infinty according to precision
+called from :getFPRootNumber()
+call fns :
+exceptions :/
+algorithm :
+Global var. used :sign_exp_length,exp_rest,hidden
+-----------------------------------------------------------------------------*/
+
+
+void Infinity( unsigned long *number)
+{
+ long j;
+
+ if ( sign_exp_length==1 )
+ number[ 0 ] =0x7FFFFFFFL<<( NO_OF_BITS-sign_exp_rest-1 ) ;
+ else
+ number[ 0 ] =0x7FFFFFFFL;
+
+ if ( ( sign_exp_length==1 ) && ( sign_exp_rest!=(NO_OF_BITS-1) ) )
+ number[ 0 ] -= ( 1L << (NO_OF_BITS-1) );
+
+ for ( j=sign_exp_length-2;j>0;j-- )
+ number[ j ] += 0xFFFFFFFFL;
+
+ if ( sign_exp_length != 1 )
+ number[ sign_exp_length-1 ] = ( 0xFFFFFFFFL<<( NO_OF_BITS-sign_exp_rest-1 ) );
+
+ if ( !hidden ) {
+ if ( sign_exp_rest==(NO_OF_BITS-1) )
+ number[ sign_exp_length ] += ( 1L<<(NO_OF_BITS-1) );
+ else
+ number[ sign_exp_length-1 ] += ( 1L<<( NO_OF_BITS-sign_exp_rest-2 ) );
+ }
+}
+
+
+
+/*-----------------------------------------------------------------------------
+name :Quiet_NaN()
+description :sets a number to Q
+called from :getFPRootNumber()
+call fns :/
+exceptions :/
+algorithm :
+Global var. used :sign_exp_length,exp_rest,hidden
+-----------------------------------------------------------------------------*/
+
+
+void Quiet_NaN( unsigned long *number)
+{
+ long j;
+ if ( sign_exp_length==1 )
+ number[ 0 ] =0x7FFFFFFFL<<( NO_OF_BITS-sign_exp_rest-1 );
+ else
+ number[ 0 ] =0x7FFFFFFFL;
+
+ if ( ( sign_exp_length==1 ) && ( sign_exp_rest!=(NO_OF_BITS-1) ) )
+ number[ 0 ] -= ( 1L << (NO_OF_BITS-1) );
+
+ for ( j=sign_exp_length-2;j>0;j-- )
+ number[ j ] += 0xFFFFFFFFL;
+ if ( sign_exp_length != 1 )
+ number[ sign_exp_length-1 ] = ( 0xFFFFFFFFL<<( NO_OF_BITS-sign_exp_rest-1 ) );
+
+ if ( !hidden ) {
+ if ( sign_exp_rest==(NO_OF_BITS-1) )
+ number[ sign_exp_length ] += ( 1L<<30 );
+ else if ( sign_exp_rest==30 )
+ number[ sign_exp_length ] += ( 1L<<(NO_OF_BITS-1) );
+ else
+ number[ sign_exp_length-1 ] += ( 1L<<( NO_OF_BITS-sign_exp_rest-3 ) );
+ } else {
+ if ( sign_exp_rest==(NO_OF_BITS-1) )
+ number[ sign_exp_length ] += ( 1L<<(NO_OF_BITS-1) );
+ else
+ number[ sign_exp_length-1 ] += ( 1L<<( NO_OF_BITS-sign_exp_rest-2 ) );
+ }
+ if ( !hidden ) {
+ if ( sign_exp_rest==(NO_OF_BITS-1) )
+ number[ sign_exp_length ] += ( 1L<<(NO_OF_BITS-1) );
+ else
+ number[ sign_exp_length-1 ] += ( 1L<<( NO_OF_BITS-sign_exp_rest-2 ) );
+ }
+}
+
+/*-----------------------------------------------------------------------------
+name :Signaling_NaN()
+description :sets number to S
+called from :getFPRootNumber()
+call fns :/
+exceptions :/
+algorithm :
+Global var. used :sign_exp_length,exp_rest,hidden
+-----------------------------------------------------------------------------*/
+
+void Signaling_NaN( unsigned long *number)
+{
+ long j;
+ if ( sign_exp_length==1 )
+ number[ 0 ] =0x7FFFFFFFL<<( NO_OF_BITS-sign_exp_rest-1 );
+ else
+ number[ 0 ] =0x7FFFFFFFL;
+
+ if ( ( sign_exp_length==1 ) && ( sign_exp_rest!=(NO_OF_BITS-1) ) )
+ number[ 0 ] -= ( 1L << (NO_OF_BITS-1) );
+ for ( j=sign_exp_length-2;j>0;j-- )
+ number[ j ] += 0xFFFFFFFFL;
+ if ( sign_exp_length != 1 )
+ number[ sign_exp_length-1 ] = ( 0xFFFFFFFFL<<( NO_OF_BITS-sign_exp_rest-1 ) );
+
+ if ( rest )
+ number[ length-1 ] += ( 1L<<( NO_OF_BITS-rest ) );
+ else
+ number[ length-1 ] += 1;
+
+ if ( !hidden ) {
+ if ( sign_exp_rest==(NO_OF_BITS-1) )
+ number[ sign_exp_length ] += ( 1L<<(NO_OF_BITS-1) );
+ else
+ number[ sign_exp_length-1 ] += ( 1L<<( NO_OF_BITS-sign_exp_rest-2 ) );
+ }
+}
+
+
+/*-----------------------------------------------------------------------------
+name :Smallest_Norm()
+description :sets number to samllest normal (or tiny T)
+called from :getFPRootNumber()
+call fns :/
+exceptions :/
+algorithm :
+Global var. used :sign_exp_length,exp_rest,hidden
+-----------------------------------------------------------------------------*/
+
+void Smallest_Norm( unsigned long *number)
+{
+ // if (hidden) // change DV
+ number[ sign_exp_length-1 ] += ( 1L<<( NO_OF_BITS-sign_exp_rest-1 ) );
+ if ( ( !hidden ) && ( sign_exp_rest==(NO_OF_BITS-1) ) )
+ number[ sign_exp_length ] += ( 1L<<(NO_OF_BITS-1) );
+ else if ( !hidden )
+ number[ sign_exp_length-1 ] += ( 1L<<( NO_OF_BITS-sign_exp_rest-2 ) );
+}
+
+
+
+/*-----------------------------------------------------------------------------
+name :Plus()
+description :operates p<digit> operation in the coded number
+called from :ModifierPorM()
+call fns :null_exp()
+exceptions :/
+algorithm :
+Global var. used :sign_exp_length,exp_rest
+-----------------------------------------------------------------------------*/
+
+void Plus( unsigned long *number, unsigned long k)
+{
+ unsigned long pre_zero, j, i;
+ pre_zero = null_exp( number);
+
+ //bij de exponent 1'tje optellen en dit k keer
+ for ( i=0;i<k;i++ ) {
+ j = sign_exp_length-1;
+ number[ j ] += ( 1L<<( (NO_OF_BITS-1)-sign_exp_rest ) );
+ if ( ( ( number[ j ] >>( NO_OF_BITS-sign_exp_rest-1 ) ) == 0 ) && ( j!=0 ) ) //enkel exponent_stuk
+ {
+ j--;
+ number[ j ] += 1;
+ }
+ if ( j>0 )
+ if ( number[ j ] ==0 ) {
+ j--;
+ number[ j ] += 1;
+ } // if
+ }
+}
+
+/*-----------------------------------------------------------------------------
+name :Minus()
+description :operates m<digits> operation in coded number
+called from :ModifierPorM
+call fns :null_exp()
+exceptions :/
+algorithm :
+Global var. used :sign_exp_length,exp_rest
+-----------------------------------------------------------------------------*/
+
+void Minus( unsigned long *number, unsigned long k)
+{
+ unsigned long pre_zero, j, i;
+
+ pre_zero = null_exp( number);
+ //bij de exponent 1'tje aftrekken en dit k keer
+ // Only works for e<=31
+ for ( i=0;i<k;i++ ) {
+ j = sign_exp_length-1;
+ number[ j ] -= ( 1L<<( NO_OF_BITS-sign_exp_rest-1 ) );
+ if ( ( number[ j ] >>( NO_OF_BITS-sign_exp_rest-1 ) ) == ( 0xFFFFFFFFL>>( NO_OF_BITS-sign_exp_rest-1 ) ) && ( j!=0 ) ) {
+ j--;
+ number[ j ] -= 1;
+ }
+ while ( ( j>0 ) && ( number[ j ] == 0xFFFFFFFFL ) ) {
+ j--;
+ number[ j ] -= 1;
+ }
+ }
+}
+
+/*-----------------------------------------------------------------------------
+name :MinusBk()
+description :divide Bias by 2^k ... operation mB<digits>
+called from :ModifierPorM
+call fns :/
+exceptions :/
+algorithm :
+Global var. used :
+-----------------------------------------------------------------------------*/
+
+
+void MinusBk( unsigned long *number, unsigned long k)
+{
+ // incorrect, only for e <= 31 // for exp <= 2^31
+ unsigned long Bk = 0;
+ int i;
+
+ // Calc Bk
+ Bk = 0x40000000L;
+ /* Divide (Bias + 1) by k */
+ for ( i=1;i<=k;i++ ) // shift exponent k places to the right
+ Bk = Bk >> 1;
+
+ // Sub Bk
+ number[ 0 ] -= Bk;
+}
+
+
+/*-----------------------------------------------------------------------------
+name :PlusBk()
+description :multiply B by 2^k ... operation pB<digits>
+called from :ModifierPorM()
+call fns :/
+exceptions :/
+algorithm :
+Global var. used :
+-----------------------------------------------------------------------------*/
+
+
+void PlusBk( unsigned long *number, unsigned long k)
+{
+ // incorrect only works for e<=31 // for exp <= 2^31
+ unsigned long Bk = 0;
+ int i;
+
+ // Calc Bk
+ Bk = 0x40000000L;
+ /* Divide (Bias + 1) by k */
+ for ( i=1;i<=k;i++ ) // shift exponent k places to the right
+ Bk = Bk >> 1;
+
+ // Add Bk
+ number[ 0 ] += Bk;
+
+}
+
+
+/*-----------------------------------------------------------------------------
+name :Incr_at_pos()
+description :operates i(<pos>)<digit>
+called from :ModifierIorD()
+call fns :null_exp()
+exceptions :/
+algorithm :
+Global var. used :sign_exp_length,exp_rest,hidden,expon
+-----------------------------------------------------------------------------*/
+
+
+void Incr_at_pos( unsigned long *number, unsigned long pos, unsigned long k)
+{
+ unsigned long leading, j, i,position,pos_part,pos_rest;
+
+ // determine leading bit if not hidden
+ if ( ( sign_exp_rest!=(NO_OF_BITS-1) ) && ( !hidden ) )
+ leading = ( number[ sign_exp_length-1 ] >>( NO_OF_BITS-sign_exp_rest-2 ) ) & 1L;
+ else if ( !hidden )
+ leading = ( number[ sign_exp_length ] >>(NO_OF_BITS-1) ) & 1L;
+
+ // calculate position
+ position = expon + pos + 1 - hidden;
+ pos_part = position / NO_OF_BITS + 1;
+ pos_rest = position % NO_OF_BITS + 1;
+
+ //Increment significand by 1, k times
+ for ( i=0;i<k;i++ ) {
+ if ( pos_rest==0 ) {
+ number[ pos_part-2 ] += 1;
+ j = pos_part-3;
+ while ( ( j>0 ) && ( number[ j ] ==0 ) ) {
+ j--;
+ number[ j ] += 1;
+ }
+ } // if
+ else {
+ number[ pos_part-1 ] += ( 1L<<( NO_OF_BITS-pos_rest ) );
+ j = pos_part-1;
+ if ( ( number[ j ] >>( NO_OF_BITS-pos_rest ) ) == 0 ) {
+ j--;
+ number[ j ] += 1;
+ while ( ( j>0 ) && ( number[ j ] ==0 ) ) {
+ j--;
+ number[ j ] += 1;
+ }
+ } // if
+ } // else
+ } //for
+
+ // replace hidden bit
+
+ if ( ( !hidden ) && ( j<sign_exp_length ) ) {
+ if ( ( sign_exp_rest==(NO_OF_BITS-1) ) && ( ( number[ sign_exp_length ] ) ==0 ) ) {
+ if ( leading==0 )
+ number[ sign_exp_length-1 ] += 1; //exp+1
+ else if ( !null_exp( number) )
+ number[ sign_exp_length ] |= ( 1L<<(NO_OF_BITS-1) ); //leading 1
+ }
+ else if ( ( number[ sign_exp_length-1 ] << ( sign_exp_rest+2 ) ) ==0 ) {
+ if ( leading==0 )
+ number[ sign_exp_length-1 ] += 1L<<( NO_OF_BITS-sign_exp_rest-1 ); //exp+1
+ else if ( !null_exp( number) )
+ number[ sign_exp_length-1 ] |= ( 1L<<( NO_OF_BITS-sign_exp_rest-2 ) ); //leading 1
+ }
+
+ } else if ( ( !hidden ) && ( j==sign_exp_length ) ) {
+ if ( ( sign_exp_rest==(NO_OF_BITS-1) ) && ( ( number[ sign_exp_length ] ) ==0 ) ) {
+ if ( leading==0 )
+ number[ sign_exp_length-1 ] += 1;
+ else if ( !null_exp( number) )
+ number[ sign_exp_length-1 ] |= ( 1L << (NO_OF_BITS-1) );
+ }
+ }
+}
+
+
+/*-----------------------------------------------------------------------------
+name :Incr()
+description :operates i<digit> on the coded number
+called from :ModifierIorD()
+call fns :null_exp()
+exceptions :/
+algorithm :
+Global var. used :length,hidden,sign_exp_length,exp_rest,rest
+-----------------------------------------------------------------------------*/
+
+void Incr( unsigned long *number, unsigned long k)
+{
+ unsigned long leidende, j, i;
+
+ //bepalen van leidende bit als deze niet hidden is
+ if ( ( sign_exp_rest!=(NO_OF_BITS-1) ) && ( !hidden ) )
+ leidende = ( number[ sign_exp_length-1 ] >>( NO_OF_BITS-sign_exp_rest-2 ) ) & 1L;
+ else if ( !hidden )
+ leidende = ( number[ sign_exp_length ] >>(NO_OF_BITS-1) ) & 1L;
+
+ //1 optellen bij de significand en dit k keer
+ for ( i=0;i<k;i++ ) {
+ if ( rest==0 )
+ number[ length-1 ] += 1;
+ else
+ number[ length-1 ] += ( 1L<<( NO_OF_BITS-rest ) );
+ j = length-1;
+ while ( ( j>0 ) && ( number[ j ] ==0 ) ) // carry propagation
+ {
+ j--;
+ number[ j ] += 1;
+ }
+ }
+
+ if ( ( !hidden ) && ( j<sign_exp_length ) ) {
+ if ( ( sign_exp_rest==(NO_OF_BITS-1) ) && ( ( number[ sign_exp_length ] ) ==0 ) ) {
+ if ( leidende==0 )
+ number[ sign_exp_length-1 ] += 1; //exp+1
+ else if ( !null_exp( number) )
+ number[ sign_exp_length ] |= ( 1L<<(NO_OF_BITS-1) ); //leidende 1
+ }
+ else if ( ( number[ sign_exp_length-1 ] << ( sign_exp_rest+2 ) ) ==0 ) {
+ if ( leidende==0 )
+ number[ sign_exp_length-1 ] += 1L<<( NO_OF_BITS-sign_exp_rest-1 ); //exp+1
+ else if ( !null_exp( number ) )
+ number[ sign_exp_length-1 ] |= ( 1L<<( NO_OF_BITS-sign_exp_rest-2 ) ); //leidende 1
+ }
+
+ } else if ( ( !hidden ) && ( j==sign_exp_length ) ) {
+ if ( ( sign_exp_rest==(NO_OF_BITS-1) ) && ( ( number[ sign_exp_length ] ) ==0 ) ) {
+ if ( leidende==0 )
+ number[ sign_exp_length-1 ] += 1;
+ else if ( !null_exp( number) )
+ number[ sign_exp_length-1 ] |= ( 1L << (NO_OF_BITS-1) );
+ }
+ }
+}
+
+
+/*-----------------------------------------------------------------------------
+name :Decr_at_pos()
+description :operates d(<pos>)<digit> on the coded number
+called from :ModifierIorD()
+call fns :null_exp()
+exceptions :/
+algorithm :
+Global var. used :hidden,sign_exp_length,exp_rest,expon
+-----------------------------------------------------------------------------*/
+
+
+void Decr_at_pos( unsigned long *number, unsigned long pos, unsigned long k)
+{
+ unsigned long leading, j, i,position,pos_part,pos_rest;
+
+ // determine leading bit if not hidden
+ if ( ( sign_exp_rest!=(NO_OF_BITS-1) ) && ( !hidden ) )
+ leading = ( number[ sign_exp_length-1 ] >>( NO_OF_BITS-sign_exp_rest-2 ) ) & 1L;
+ else if ( !hidden )
+ leading = ( number[ sign_exp_length ] >>(NO_OF_BITS-1) ) & 1L;
+
+ // calculate position
+ position = expon + pos + 1 - hidden;
+ pos_part = position / NO_OF_BITS + 1;
+ pos_rest = position % NO_OF_BITS + 1;
+
+ for ( i=0;i<k;i++ ) {
+ if ( pos_rest==0 ) {
+ number[ pos_part-2 ] -= 1;
+ j = pos_part-3;
+ while ( ( j>0 ) && ( number[ j ] == 0xFFFFFFFFL ) ) {
+ j--;
+ number[ j ] -= 1;
+ } // while
+ }
+ else {
+ number[ pos_part-1 ] -= ( 1L<<( NO_OF_BITS-pos_rest ) );
+ j = pos_part-1;
+ if ( ( number[ j ] >>( NO_OF_BITS-pos_rest ) ) == ( 0xFFFFFFFFL>>( NO_OF_BITS-pos_rest ) ) ) {
+ j--;
+ number[ j ] -= 1;
+ while ( ( j>0 ) && ( number[ j ] == 0xFFFFFFFFL ) ) {
+ j--;
+ number[ j ] -= 1;
+ } // while
+ } // if
+ } // else
+ } // for
+
+ // bepalen van leidende bit als deze niet hidden is
+ // change DV
+
+ if ( ( !hidden ) && ( !null_exp( number) ) ) {
+ j = sign_exp_length-1;
+
+ if ( ( number[ j ] >> ( 30-sign_exp_rest ) ) % 2 == 0 ) {
+ j = sign_exp_length-1;
+ number[ j ] -= ( 1L<<( (NO_OF_BITS-1) - sign_exp_rest ) );
+ if ( number[ j ] >>( (NO_OF_BITS-1)-sign_exp_rest ) == 0xFFFFFFFFL>>( (NO_OF_BITS-1)-sign_exp_rest ) ) {
+ j--;
+ number[ j ] -= 1;
+ }
+ while ( ( j>0 ) && ( number[ j ] == 0xFFFFFFFFL ) ) {
+ j--;
+ number[ j ] -= 1;
+ }
+ // replace leading bit if necessary
+ if ( sign_exp_rest==(NO_OF_BITS-1) )
+ number[ sign_exp_length ] |= 1L<<(NO_OF_BITS-1);
+ else
+ number[ sign_exp_length-1 ] |= 1L<<( 30-sign_exp_rest );
+ }
+ } // if
+}
+
+/*-----------------------------------------------------------------------------
+name :Decr()
+description :operates d<digit> on the coded number
+called from :ModifierIorD()
+call fns :null_exp()
+exceptions :/
+algorithm :
+Global var. used :length,hidden,sign_exp_length,exp_rest,rest
+-----------------------------------------------------------------------------*/
+
+
+void Decr( unsigned long *number, unsigned long k)
+{
+ unsigned j, i;
+ int carry = 0;
+
+ //decrement significand k times
+ for ( i=0;i<k;i++ ) {
+ j = length-1;
+ if ( rest==0 )
+ number[ j ] -= 1;
+ else {
+ number[ j ] -= ( 1L<<( NO_OF_BITS-rest ) );
+ if ( ( number[ j ] >>( NO_OF_BITS-rest ) ) == ( 0xFFFFFFFFL>>( NO_OF_BITS-rest ) ) && ( j!=0 ) ) {
+ j--;
+ number[ j ] -= 1;
+ }
+ }
+ while ( ( j>0 ) && ( number[ j ] == 0xFFFFFFFFL ) ) {
+ j--;
+ number[ j ] -= 1;
+ }
+ }
+
+ // change DV
+ if ( ( !hidden ) &&
+ ( !null_exp( number) ) ) {
+ // leading bit = zero ?
+ j = sign_exp_length-1;
+
+ if ( ( ( sign_exp_rest < (NO_OF_BITS-1) ) && !( number[ j ] & ( 1L << 30 - sign_exp_rest ) ) ) ||
+ ( ( sign_exp_rest == (NO_OF_BITS-1) ) && !( number[ j ] & ( 1L << (NO_OF_BITS-1) ) ) ) ) {
+ // leading bit == 0
+
+ if ( sign_exp_rest == (NO_OF_BITS-1) ) {
+ j++;
+ number[ j ] -= 1L;
+ if ( ( j > 0 ) && ( number[ j ] == 0xFFFFFFFFL ) ) {
+ j--;
+ number[ j ] -= 1;
+ }
+ } else {
+ /// change DV 28/01/2000
+
+ if ( hidden && ( !( ( number[ j ] >> ( (NO_OF_BITS-1) - sign_exp_rest ) ) & 1L ) ) ) {
+ // trailing exp bit == 0
+ number[ j ] += 1L << ( (NO_OF_BITS-1) - sign_exp_rest );
+ j--;
+ number [ j ] -= 1;
+
+ while ( ( j>0 ) && ( number[ j ] == 0xFFFFFFFFL ) ) {
+ j--;
+ number[ j ] -= 1;
+ }
+ } else if ( sign_exp_rest == 0 ) { // change DV 8/3/2000
+ if ( !( number[ j ] & ( 1L << ( (NO_OF_BITS-1) - sign_exp_rest ) ) ) ) { // leading exp. bit = 0
+ number[ j-1 ] -= 1; // borrow carry
+ number[ j ] += ( 1L << ( (NO_OF_BITS-1) - sign_exp_rest ) );
+ } else
+ number[ j ] -= ( 1L << ( (NO_OF_BITS-1) - sign_exp_rest ) );
+
+ }
+ else {
+ number[ j ] -= ( 1L << ( (NO_OF_BITS-1) - sign_exp_rest ) );
+
+ }
+
+ }
+ }
+ }
+ // replace leading bit if necessary
+ if ( ( !hidden ) && ( !null_exp( number) ) ) {
+ if ( sign_exp_rest==(NO_OF_BITS-1) )
+ number[ sign_exp_length ] |= 1L<<(NO_OF_BITS-1);
+ else
+ number[ sign_exp_length-1 ] |= 1L<<( 30-sign_exp_rest );
+ }
+}
+
+
+/*-----------------------------------------------------------------------------
+name :exitmem()
+description :exit if less memory to store number
+ //but why only getbinary() (have to figure out)
+called from :getbinary()
+call fns :
+Global var. used :
+-----------------------------------------------------------------------------*/
+
+
+void exitmem( )
+{
+ printf( "\nNot enough memory\n" );
+ printf( "Program aborted.\n" );
+ fclose( input );
+ fclose( output );
+ delete[ ] operand1;
+ delete[ ] operand2;
+ delete[ ] result;
+ printf( "\n\nError on line %ld of inputfile.",lines_in+readings+1 );
+ printf( "\n\nDone with %ld readings.\n", readings );
+ exit( 1 );
+}
+
+
+
+/*-----------------------------------------------------------------------------
+name :null_exp()
+description :checks if exponent is zero
+called from :Plus(),Minus(),Incr_at_pos(),Incr(),Decr_at_pos(),
+ Decr(),ModifierU().
+call fns :/
+exceptions :/
+algorithm :
+Global var. used :sign_exp_length,exp_rest,length
+-----------------------------------------------------------------------------*/
+
+unsigned long null_exp( const unsigned long *number)
+{
+ unsigned long m, null=1;
+
+ for ( m=1;m<sign_exp_length-1;m++ ) {
+ if ( number[ m ] !=0 )
+ null = 0;
+ }
+ if ( ( sign_exp_rest==0 ) && ( ( ( number[ 0 ] & 0x7FFFFFFFL ) << 1 ) != 0 ) )
+ null=0;
+ if ( ( ( number[ 0 ] & 0x7FFFFFFFL ) >> ( NO_OF_BITS-sign_exp_rest-1 ) ) != 0 )
+ null=0;
+ if ( ( length != 1 ) && ( sign_exp_length !=1 ) && ( ( number[ sign_exp_length-1 ] >> ( NO_OF_BITS-sign_exp_rest-1 ) ) != 0 ) )
+ null=0;
+
+ return null;
+}
+
+/*-----------------------------------------------------------------------------
+name :one_exp()
+description :checks if exponent is one
+called from :ModifierU()
+call fns :/
+exceptions :/
+algorithm :
+Global var. used :sign_exp_length,exp_rest
+-----------------------------------------------------------------------------*/
+
+
+unsigned long one_exp( const unsigned long *number)
+{
+ unsigned long m, one=0;
+
+ if ( ( ( number[ sign_exp_length-1 ] >> ( NO_OF_BITS - sign_exp_rest - 1 ) ) | 1L ) == 1L )
+ one = 1;
+
+ for ( m=0;m<sign_exp_length-1;m++ ) {
+ if ( number[ m ] != 0 )
+ one = 0;
+ }
+ if ( ( sign_exp_length > 1 ) && ( ( number[ 0 ] & 0x7FFFFFFFL ) != 0 ) )
+ one = 0;
+
+ return one;
+}
+
+
+
+
+/*-----------------------------------------------------------------------------
+name :mygetc()
+description :apply getc() of <stdio.h> to the present location of file in use
+called from :whole program
+call fns :/
+exceptions :/
+algorithm :/
+Global var. used :/
+-----------------------------------------------------------------------------*/
+
+int mygetc( FILE *f )
+{
+ int c;
+ c = getc( f );
+ return c;
+}
+
+
+/*-----------------------------------------------------------------------------
+name :myungetc()
+description :apply ungetc() of <stdio.h> to the present location of file in use
+called from :whole program
+call fns :/
+exceptions :/
+algorithm :/
+Global var. used :/
+-----------------------------------------------------------------------------*/
+
+void myungetc( int c, FILE *f )
+{
+ ungetc( c, f );
+}
+
+
+
+/* ============================ END OF FILE ============================*/
--- /dev/null
+/*
+##########################################################################
+# #
+# Program: IeeeCC754 #
+# #
+# Description: #
+# IeeeCC754 or IEEE 754 Compliance Checker is a precision and range #
+# independent tool to test whether an implementation of #
+# floating-point arithmetic (in hardware or software) is compliant #
+# with the principles of the IEEE 754-854 floating-point standards. #
+# You can find out more about the testing tool IeeeCC754 at #
+# #
+# http://win-www.uia.ac.be/u/cant/ieeecc754.html #
+# #
+# This tool is in parts based on and greatly benefited from the #
+# the program FPTEST developed by Jerome Coonen. For a full #
+# description of the extensions to FPTEST and a reference to #
+# the original Coonen program, please refer to the URL given above. #
+# For the options available with the program IeeeCC754 and its #
+# compatibility with David Hough's hexadecimal UCB format, we #
+# also refer to the file readme.usage. #
+# #
+# Usage: see readme.usage #
+# #
+# Responsible authors: #
+# Brigitte Verdonk #
+# Annie Cuyt #
+# #
+# Contributors: #
+# Tarun Agarwal(05-07/2002) #
+# Johan Bogo (1998-1999) #
+# Tim Gevers (10-12/2000) #
+# Debby Ooms (1996-1997) #
+# Geert Vermuyten (1996-1997) #
+# Dennis Verschaeren (09/1996-06/2000) #
+# #
+# Copyright (C) 2000 University of Antwerp #
+# #
+# This program can be obtained from the authors, free, but WITHOUT ANY #
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or #
+# FITNESS FOR A PARTICULAR PURPOSE. #
+# #
+# Contact: #
+# Brigitte.Verdonk@uia.ua.ac.be #
+# Department of Mathematics and Computer Science #
+# University of Antwerp (UIA) #
+# Universiteitsplein 1 #
+# B2610 Antwerp, BELGIUM #
+# #
+##########################################################################
+
+Filename:
+ $RCSfile$
+
+Last updated:
+ $Date$
+
+*/
+#include <string.h>
+#include <Bitstring.h>
+#include <stdio.h>
+
+/*class implementation*/
+
+/***********************************************************************
+* Member: GetPattern(unsigned long res)
+* Purpose: returns a Bitstring with the first "res" bits set.
+* Return: Bitstring with first "res" bits set.
+***********************************************************************/
+unsigned long Bitstring::GetPattern(unsigned long rest)
+{
+ unsigned long pattern =(unsigned long) ((unsigned long) 1 << lengthT) -1;
+ pattern = pattern >> ((lengthT) -rest);
+ return pattern;
+}
+
+
+/***********************************************************************
+* Member: Convert()
+* Purpose: returns the first block of bitstr. Its only defined to be used
+* in PutByte so the ^= operator would work.
+* Return: first block of bitstr -> bitstr[0].
+***********************************************************************/
+unsigned long Bitstring::Convert()
+{
+ return bitstr[0];
+}
+
+
+
+/***********************************************************************
+* Member: Bitstring() Constructor
+* Purpose: Create empty bitstring
+* Return: Nothing
+***********************************************************************/
+Bitstring::Bitstring()
+{
+ length=lengthBlock=0;
+ lengthT = sizeof(unsigned long)*8;
+ bitstr = NULL;
+}
+
+/***********************************************************************
+* Member: Bitstring(unsigned long size) Constructor
+* Purpose: Create bitstring of size "size" and initiate it with zeros
+* Return: Nothing
+***********************************************************************/
+Bitstring::Bitstring(unsigned long size)
+{
+ int i;
+ length= size;
+ lengthT = sizeof(unsigned long )*8;
+ if (size % lengthT == 0)
+ lengthBlock = (size /lengthT);
+ else
+ lengthBlock= (size /lengthT) + 1;
+ bitstr = new unsigned long [lengthBlock];
+ for (i=0;i<lengthBlock;i++)
+ bitstr[i]=0;
+}
+
+/***********************************************************************
+* Member: Bitstring(char * str) Constructor
+* Purpose: Create bitstring with "str" as initiale value
+* Return: Nothing
+***********************************************************************/
+Bitstring::Bitstring(char * str)
+{
+
+ long i;
+
+ length = strlen(str);
+ lengthT =sizeof(unsigned long )*8;
+
+ if (length % lengthT == 0)
+ lengthBlock = (length /lengthT);
+ else
+ lengthBlock= (length /lengthT) + 1;
+
+ bitstr = new unsigned long [lengthBlock];
+
+ for (i=0;i<lengthBlock;i++)
+ bitstr[i]=0;
+
+ for (i= length -1; i >= 0; i--)
+ {
+ if (str[i]=='1')
+ bitstr [(length -1 -i)/lengthT] |= 1 << ((length-1 -i)%lengthT);
+ }
+}
+
+/***********************************************************************
+* Member: Bitstring(Bitstring & copy) Copy constructor
+* Purpose: Create a bitstring with initiale value the bitstring "copy"
+* Return: Nothing
+***********************************************************************/
+Bitstring::Bitstring(const Bitstring & copy)
+{
+ length = copy.length;
+ lengthT = copy.lengthT;
+ lengthBlock = copy.lengthBlock;
+ if (length > 0) {
+ bitstr = new unsigned long [lengthBlock];
+ for (int i=0 ; i< lengthBlock; i++)
+ bitstr[i]= copy.bitstr[i];
+ }
+ else
+ bitstr = NULL;
+}
+
+
+/***********************************************************************
+* Member: ~Bitstring() Deconstructor
+* Purpose: Remove bitstr from memory
+* Return: Nothing
+***********************************************************************/
+Bitstring::~Bitstring()
+{
+ delete [] bitstr;
+}
+
+/***********************************************************************
+* Member: Length()
+* Purpose: Get the length of the bitstring
+* Return: Length of bitstring
+***********************************************************************/
+unsigned long Bitstring::Length() const
+{
+ return length;
+}
+
+/***********************************************************************
+* Member: Resize (unsigned long len)
+* Purpose: Change the length of the bitstring to "len". If "len" is
+* larger then the length, the bitstring is appended with 0, else
+* the bitstring is truncated to the new length "len"
+* Return: Previous length
+***********************************************************************/
+unsigned long Bitstring::Resize(unsigned long len)
+{
+ unsigned long * temp;
+ long tmplenBlock,tmpMinlen,i,rest,prevLen;
+ unsigned long value;
+
+ if (len > 0) {
+ /*create bitstr with new size*/
+ if (len % lengthT == 0)
+ tmplenBlock = (len /lengthT);
+ else
+ tmplenBlock= (len /lengthT) + 1;
+
+ temp = new unsigned long [tmplenBlock];
+
+ /*get length to copy*/
+ if (lengthBlock <= tmplenBlock)
+ tmpMinlen = lengthBlock;
+ else
+ tmpMinlen = tmplenBlock;
+
+ /*copy bitstr*/
+ for (i=0; i < tmpMinlen; i++)
+ temp[i] = bitstr[i] ;
+
+
+ /*delete old bitstr*/
+ if (bitstr != NULL)
+ delete [] bitstr;
+
+ if (len % lengthT != 0) {
+ rest = len % lengthT;
+ value = GetPattern (rest);
+ temp[len/lengthT] &= value;
+ }
+
+ /*append with 0*/
+ if(lengthBlock < tmplenBlock)
+ {
+ for (i = lengthBlock; i < tmplenBlock; i++)
+ temp[i]=0;
+ }
+
+ /*change size */
+ bitstr = temp;
+ prevLen = length;
+ length= len ;
+ lengthBlock=tmplenBlock;
+}
+else {
+ length=lengthBlock=0;
+ lengthT = sizeof(unsigned long)*8;
+ delete [] bitstr;
+ bitstr = NULL;
+}
+ return prevLen;
+}
+
+/***********************************************************************
+* Member: GetBit(unsigned long bit)
+* Purpose: Get the bit value at position "bit"
+* Return: 0 <= "bit" < length -> The bit value
+* else -> 0
+***********************************************************************/
+int Bitstring::GetBit(long bit) const
+{ unsigned long tmp;
+
+ if ((0 <= bit) && (bit < length)) {
+ tmp = bitstr[bit/lengthT];
+ if (tmp & (1L << lengthT - 1 - (bit% lengthT)))
+ return 1;
+ }
+ return 0;
+}
+
+/***********************************************************************
+* Member: PutBit (unsigned long bit, unsigned int bitvalue)
+* Purpose: Replace the bit value at position "bit" with the new "bitvalue"
+* Return: Previous bit value
+***********************************************************************/
+int Bitstring::PutBit(unsigned long bit,unsigned int bitvalue)
+{
+ int prevBit;
+
+ /*get current bit value*/
+ prevBit = GetBit(bit);
+ // cout << "bit = " << bit << " " << bitvalue << endl;
+ // cout << "bitstr = " << bitstr[bit/lengthT] << endl;
+ if (bitvalue == 0) {
+ if (bitstr[bit/lengthT] & (1L << (lengthT - 1 - (bit%lengthT))))
+ bitstr[bit/lengthT] -= (1L << (lengthT - 1 - (bit%lengthT)));
+ }
+ else
+ bitstr[bit/lengthT] |= (1L << (lengthT - 1 - (bit%lengthT)));
+ // cout << "bitstr = " << bitstr[bit/lengthT] << endl;
+ return prevBit;
+}
+
+/***********************************************************************
+* Member: Set (unsigned long bit)
+* Purpose: Replace the bit value at position "bit" with the 1
+* Return: Previous bit value
+***********************************************************************/
+int Bitstring::Set(long bit)
+{
+ return PutBit(bit,1);
+}
+/***********************************************************************
+* Member: Clear (unsigned long bit)
+* Purpose: Replace the bit value at position "bit" with the 0
+* Return: Previous bit value
+***********************************************************************/
+int Bitstring::Clear(long bit)
+{
+ return PutBit(bit,0);
+}
+
+/***********************************************************************
+* Member: ClearBitString ()
+* Purpose: Clears the bitstring
+* Return: Cleared bitstring
+***********************************************************************/
+Bitstring Bitstring::ClearBitString()
+{
+ int i ;
+ for (i =0; i< lengthBlock; i++)
+ bitstr[i] = 0;
+
+ return *this;
+}
+
+/***********************************************************************
+* Member: GetByte (unsigned long byte)
+* Purpose: Get the byte value at position "byte"
+* Return: The byte value
+***********************************************************************/
+void Bitstring::GetByte(unsigned long byte, Bitstring sub) const
+{
+ SubBitstring(byte*8,sub);
+}
+
+/***********************************************************************
+* Member: PutByte (unsigned long byte, Bitstring bytevalue)
+* Purpose: Replace the byte value at position "byte" with the new "bytevalue"
+* Return: Previous byte value
+***********************************************************************/
+void Bitstring::PutByte(unsigned long byte,Bitstring bytevalue)
+{
+ long sizeT;
+
+ sizeT=sizeof(unsigned long);
+
+ // GetByte(byte,prevByte);
+ // prevByte.Resize(lengthT);
+ // bytevalue.Resize(8);
+ // bytevalue.Resize(lengthT);
+
+ /* replace value by "bytevalue" using xor*/
+ // cout << bitstr << endl;
+ // cout << bytevalue << endl << flush;
+ bitstr[byte/sizeT] ^= (bytevalue.Convert() << ((byte%sizeT)*8));
+ // bitstr[byte/sizeT] ^= (prevByte.Convert() << ((byte%sizeT)*8));
+ // cout << bitstr << endl << flush;
+}
+
+/***********************************************************************
+* Member: Inc ()
+* Purpose: Increase the bitstring value by 1
+* Return: Carry after most significant bit
+***********************************************************************/
+int Bitstring::Inc()
+{
+ int i = 0;
+
+ while ((i <length) && (GetBit(i)== 1))
+ Clear(i++);
+
+ if (i < length)
+ Set(i);
+ else
+ return 1;
+
+ return 0;
+
+}
+
+/***********************************************************************
+* Member: Dec ()
+* Purpose: Decrease the bitstring value by 1
+* Return: 1 -> wrap around (negative)
+* 0 -> OK
+***********************************************************************/
+int Bitstring:: Dec()
+{
+ int i = 0;
+
+ while ((i<length) && (GetBit(i) == 0))
+ Set(i++);
+
+ if (i< length)
+ Clear(i);
+ else
+ return 1;
+
+ return 0;
+}
+
+/***********************************************************************
+* Member: BitstrToString()
+* Purpose: Converts a bitstring to a C-string
+* Return: length >0 -> The C-string
+* else -> "Bitstring is empty"
+***********************************************************************/
+void Bitstring::BitstrToString(char str[256]) const
+{
+ long place, i;
+ unsigned long block;
+
+
+ if (length > 0)
+ {
+ /*convert bitstring*/
+ for (i=0; i <length;i++)
+ {
+ place = i%lengthT;
+ block = 1 << place;
+ if ((bitstr[i/lengthT] & block) == 0)
+ str[length-1 -i]='0';
+ else
+ str[length-1 -i]='1';
+ }
+ str[length]='\0';
+ }
+ else
+ {
+ /*empty bitstring*/
+ // str = new char [25];
+ // strcpy(str,"Bitstring is empty!\n");
+ str[0]='\0';
+ }
+}
+
+
+/***********************************************************************
+* Member: StringToBitstr(char *str)
+* Purpose: Converts a C-string to a bitstring
+* Return: converted bitstring
+***********************************************************************/
+void Bitstring::StringToBitstr(char *str)
+{
+
+ long i;
+
+ length = strlen(str);
+ lengthT =sizeof(unsigned long)*8;
+ lengthBlock = (length/lengthT)+1;
+ if(bitstr)
+ delete [] bitstr;
+ bitstr = new unsigned long [lengthBlock];
+
+ for (i=0;i<lengthBlock;i++)
+ bitstr[i]=0;
+
+ for (i= length -1; i >= 0; i--)
+ {
+ if (str[i]=='1')
+ bitstr [(length -1 -i)/lengthT] |= 1 << ((length-1 -i)%lengthT);
+ }
+}
+
+
+
+/***********************************************************************
+* Member: Concat(const Bitstring &b2)
+* Purpose: Puts bitstring *this in front of b2 -> so the first bit of b2
+* becomes the first bit of *thisb2
+* Return: *this -> *thisb2
+***********************************************************************/
+void Bitstring::Concat(const Bitstring &b2)
+{
+ Resize(length+b2.length);
+ for (int i = length;i < length + b2.length;i++) {
+ bitstr[i] = b2[i-length];
+ }
+}
+
+
+/***********************************************************************
+* Member: SubBitstring(unsigned long begin, unsigned long count)
+* Purpose: Returns the substring defined by position "begin" to "count"
+* Return: substring from bitstring
+***********************************************************************/
+void Bitstring::SubBitstring(unsigned long begin, Bitstring &sub) const
+{
+ Bitstring temp(*this);
+ int i;
+ // cout << "temp = " << temp << endl << flush;
+ temp << begin;
+ // cout << "temp = " << temp << endl << flush;
+ for (i = 0;i < sub.lengthBlock-1;i++)
+ sub.bitstr[i] = temp[i];
+ sub.bitstr[i] = ((temp[i] >> (32 - (sub.length % lengthT))) << (32 - (sub.length % lengthT)));
+ // cout << sub << endl << flush;
+}
+
+/***********************************************************************
+* Member: operator = (const Bitstring ©)
+* Purpose: Overloads the assign operator. Makes the bistring equal to "copy"
+* Return: The changed bitstring
+***********************************************************************/
+Bitstring& Bitstring::operator = (const Bitstring ©)
+{
+ int i=0;
+ // unsigned long * tmp;
+
+ /*change lengths*/
+ length = copy.length;
+ lengthT = copy.lengthT;
+ lengthBlock = copy.lengthBlock;
+
+ if(bitstr)
+ // tmp = bitstr;
+ delete [] bitstr;
+
+
+ //check length of copy
+ if (length >0)
+ {
+ bitstr = new unsigned long [lengthBlock];
+
+ /*copy the bitstring*/
+ for (i=0 ; i< lengthBlock; i++)
+ bitstr[i]= copy.bitstr[i];
+ }
+ else
+ bitstr= NULL;
+
+ // if (tmp)
+ // delete [] tmp;
+
+ return *this;
+}
+
+/***********************************************************************
+* Member: operator == (const Bitstring & b) const
+* Purpose: Overloads the equal operator.
+* Return: equal -> 1
+* not equal -> 0
+***********************************************************************/
+int Bitstring::operator == (const Bitstring &b) const
+{
+ int i=0, value = 1;
+
+ /*if lengths not equal than the bitstrings not equal */
+ if (length != b.length)
+ value = 0;
+
+
+ while ((i<lengthBlock ) && (value))
+ {
+ if (bitstr[i] != b[i])
+ value =0;
+ i++;
+ }
+ return value;
+}
+
+/***********************************************************************
+* Member: operator != (const Bitstring &b) const
+* Purpose: Overloads the not equal operator.
+* Return: not equal -> 1
+* equal -> 0
+***********************************************************************/
+int Bitstring::operator != (const Bitstring &b) const
+{
+
+ int i=0, value = 0;
+
+ if (length != b.length) {
+ value = 1;
+ }
+ while ((i<lengthBlock ) && (!value))
+ {
+ if (bitstr[i] != b[i]) {
+ value = 1;
+ }
+ i++;
+ }
+
+ // cout << *this << endl;
+ // cout << b << endl;
+ return value;
+}
+
+/***********************************************************************
+* Member: operator > (const Bitstring &b) const
+* Purpose: Overloads the greater than operator.
+* Return: greater -> 1
+* not greater -> 0
+***********************************************************************/
+int Bitstring::operator > (const Bitstring &b) const
+{
+ Bitstring temp;
+ int i;
+
+ if (*this == b)
+ return 0;
+
+ if (Length() > b.Length())
+ {
+ temp = b;
+ temp.Resize(Length());
+ }
+
+ if (Length() < b.Length())
+ {
+ temp = *this;
+ temp.Resize(b.Length());
+ }
+
+ i = Length()-1;
+
+ while (i>=0)
+ {
+ if (GetBit(i)!= b.GetBit(i))
+ {
+ if (GetBit(i) == 1)
+ return 1;
+ else
+ return 0;
+ }
+ i--;
+ }
+ return 0;
+}
+
+/***********************************************************************
+* Member: operator < (const Bitstring &b) const
+* Purpose: Overloads the smaller than operator.
+* Return: smaller -> 1
+* not smaller -> 0
+***********************************************************************/
+int Bitstring::operator < (const Bitstring &b) const
+{
+ Bitstring temp;
+ int i;
+
+ if (*this == b)
+ return 0;
+
+ if (Length() > b.Length())
+ {
+ temp = b;
+ temp.Resize(Length());
+ }
+
+ if (Length() < b.Length())
+ {
+ temp = *this;
+ temp.Resize(b.Length());
+ }
+
+ i = Length()-1;
+
+ while (i>=0)
+ {
+ if (GetBit(i)!= b.GetBit(i))
+ {
+ if (GetBit(i) == 1)
+ return 0;
+ else
+ return 1;
+ }
+ i--;
+ }
+ return 0;
+}
+
+
+
+/***********************************************************************
+* Member: operator << (unsigned long count)
+* Purpose: Overloads the shift left operator. Shifts the bitstring "count"
+* bits to the left
+* Return: shifted bitstring
+***********************************************************************/
+void Bitstring::operator <<(long count)
+{
+ int i,j, rest;
+
+ /*if count > lengthT -> copy blocks*/
+ if ((count/lengthT) > 0)
+ {
+ for (j=0; j <lengthBlock ; j++)
+ {
+ if (j+(count/lengthT) < (unsigned long)(lengthBlock))
+ bitstr[j]=bitstr[j+(count/lengthT)];
+ else
+ bitstr[j]= 0;
+ }
+
+ //make lastblocks = 0
+ for (j= lengthBlock - (count/lengthT); j < lengthBlock ; j++)
+ bitstr[j]= 0;
+ }
+ /* if count < lengthT -> shift bitwise*/
+ rest = count % lengthT;
+
+ unsigned long leading = (1L << lengthT-1);
+ for (i=0; i < rest ; i++)
+ {
+ for (j=0; j < lengthBlock-1; j++)
+ {
+ bitstr[j] <<= 1;
+ //check for carry
+ if (bitstr[j+1] & leading)
+ bitstr[j] += 1L;
+ }
+ bitstr[lengthBlock-1] <<=1;
+ }
+}
+
+/***********************************************************************
+* Member: operator >> (unsigned long count)
+* Purpose: Overloads the shift right operator. Shifts the bitstring "count"
+* bits to the right
+* Return: shifted bitstring
+***********************************************************************/
+void Bitstring::operator >>(unsigned long count)
+{
+ int i,j, rest,carry = 0;
+
+ /*if count > lengthT -> copy blocks*/
+ if ((count/lengthT) > 0)
+ {
+ // cout << "copy blocks" << endl << flush;
+ for (j=0; j <lengthBlock ; j++)
+ {
+ if (j+(count/lengthT) < (unsigned long)(lengthBlock))
+ bitstr[j]=bitstr[j+(count/lengthT)];
+ else
+ bitstr[j]= 0;
+ }
+
+ //make lastblocks = 0
+ for (j= lengthBlock - (count/lengthT); j < lengthBlock ; j++)
+ bitstr[j]= 0;
+
+ }
+
+
+ /* if count < lengthT -> shift bitwise*/
+ rest = count % lengthT;
+ // cout << "rest = " << rest << endl << flush;
+ for (i=0; i < rest; i++)
+ {
+ carry = 0;
+ for (j=lengthBlock-1;j > 0; j--)
+ {
+ bitstr[j] >>= 1;
+ if ((bitstr[j-1] & 1L) == 1L)
+ bitstr[j] |= (1 <<( lengthT-1));
+ }
+ bitstr[0] >>= 0;
+ }
+}
+
+
+/***********************************************************************
+* Member: operator [] (unsigned long n)
+* Purpose: Overloads the array operator. Returns/change block "n"
+* Return: block "n"
+***********************************************************************/
+unsigned long& Bitstring::operator [](unsigned long n) const
+{
+ //if(( n < 0) || (n > lengthBlock))
+ return bitstr[n];
+}
+
+/***********************************************************************
+* Member: operator &(const Bitstring &bitst)
+* Purpose: Overloads the bitwise and operator. Does a bitwise and with
+* "bitstr" and "bitst". Makes the size of bitst equal to the
+* bitstring.
+* Return: bitwised and -> *this & bitst
+***********************************************************************/
+Bitstring Bitstring::operator &(const Bitstring &bitst)
+{
+
+ long i;
+ Bitstring temp1(*this),temp2(bitst);
+
+ //make size bitst equal to *this
+ if (lengthBlock > bitst.lengthBlock)
+ temp2.Resize(length);
+
+ //bitwise and
+ for (i = 0; i<lengthBlock ; i++ )
+ temp1[i] &= temp2[i];
+
+ return temp1;
+
+}
+
+/***********************************************************************
+* Member: operator |(const Bitstring &bitst)
+* Purpose: Overloads the bitwise or operator. Does a bitwise or with
+* "bitstr" and "bitst". Makes the size of bitst equal to the
+* bitstring.
+* Return: bitwised or -> *this | bitst
+***********************************************************************/
+Bitstring Bitstring::operator |(const Bitstring &bitst)
+{
+ long i;
+ Bitstring temp1(*this),temp2(bitst);
+
+ //make size bitst equal to *this
+ if (lengthBlock > bitst.lengthBlock)
+ temp2.Resize(length);
+
+ //bitwise or
+ for (i = 0; i<lengthBlock ; i++ )
+ temp1[i] |= temp2[i];
+
+ return temp1;
+}
+
+
+/***********************************************************************
+* Member: operator ^ (const Bitstring &bitst)
+* Purpose: Overloads the bitwise xor operator. Does a bitwise xor with
+* "bitstr" and "bitst". Makes the size of bitst equal to the
+* bitstring.
+* Return: bitwised xor -> *this ^ bitst
+***********************************************************************/
+Bitstring Bitstring::operator ^( const Bitstring &bitst)
+{
+ long i;
+ Bitstring temp1(*this),temp2(bitst);
+
+ //make size bitst equal to *this
+ if (lengthBlock > bitst.lengthBlock)
+ temp2.Resize(length);
+
+ //bitwise xor
+ for (i = 0; i<lengthBlock ; i++ )
+ temp1[i] ^= temp2[i];
+
+ return temp1;
+}
+
+/***********************************************************************
+* Member: operator ~ ()
+* Purpose: Overloads the bitwise not operator. Does a bitwise not with
+* "bitstr".
+* Return: bitwised not -> ~(*this)
+***********************************************************************/
+Bitstring Bitstring::operator ~()
+{
+ long i;
+ Bitstring temp1(*this);
+
+
+ //bitwise not
+ for (i = 0; i<lengthBlock ; i++ )
+ temp1[i] = ~temp1[i];
+
+ temp1.Resize(this->Length());
+ return temp1;
+
+}
+
+
+
+/***********************************************************************
+* Member: operator << (ostream& outs, Bitstring &strout)
+* Purpose: Overloads the stream output operator. Converts the bitstring to a
+* C-string and returns it to "ostream".
+* Return: outs -> converted bitstring
+***********************************************************************/
+ostream& operator << (ostream& outs, const Bitstring &strout)
+{
+ // convert bitstring
+
+/*
+ char tmp[256];
+ strout.BitstrToString(tmp);
+ outs << tmp;
+*/
+ char tmp[9];
+ for (int i = 0; i < strout.lengthBlock;i++) {
+ sprintf(tmp,"%08x",strout[i]);
+ outs << tmp;
+ }
+ // outs << hex << setw(8) << setfill('0') << strout[i];
+ return outs;
+}
+
+
+/***********************************************************************
+* Member: operator >> (istream& ins, Bitstring &instr)
+* Purpose: Overloads the stream input operator. Converts the C-string to a
+* bitstring.
+* Return: ins
+***********************************************************************/
+istream& operator >> (istream& ins, Bitstring &instr)
+{
+ char str[255];
+
+ cin>> str;
+ instr.StringToBitstr(str);
+
+ return ins;
+}
--- /dev/null
+/*
+##########################################################################
+# #
+# Program: IeeeCC754 #
+# #
+# Description: #
+# IeeeCC754 or IEEE 754 Compliance Checker is a precision and range #
+# independent tool to test whether an implementation of #
+# floating-point arithmetic (in hardware or software) is compliant #
+# with the principles of the IEEE 754-854 floating-point standards. #
+# You can find out more about the testing tool IeeeCC754 at #
+# #
+# http://win-www.uia.ac.be/u/cant/ieeecc754.html #
+# #
+# This tool is in parts based on and greatly benefited from the #
+# the program FPTEST developed by Jerome Coonen. For a full #
+# description of the extensions to FPTEST and a reference to #
+# the original Coonen program, please refer to the URL given above. #
+# For the options available with the program IeeeCC754 and its #
+# compatibility with David Hough's hexadecimal UCB format, we #
+# also refer to the file readme.usage. #
+# #
+# Usage: see readme.usage #
+# #
+# Responsible authors: #
+# Brigitte Verdonk #
+# Annie Cuyt #
+# #
+# Contributors: #
+# Johan Bogo (1998-1999) #
+# Tim Gevers (10-12/2000) #
+# Debby Ooms (1996-1997) #
+# Geert Vermuyten (1996-1997) #
+# Dennis Verschaeren (09/1996-06/2000) #
+# #
+# Copyright (C) 2000 University of Antwerp #
+# #
+# This program can be obtained from the authors, free, but WITHOUT ANY #
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or #
+# FITNESS FOR A PARTICULAR PURPOSE. #
+# #
+# Contact: #
+# Brigitte.Verdonk@uia.ua.ac.be #
+# Department of Mathematics and Computer Science #
+# University of Antwerp (UIA) #
+# Universiteitsplein 1 #
+# B2610 Antwerp, BELGIUM #
+# #
+##########################################################################
+
+Filename:
+ $RCSfile$
+
+Last updated:
+ $Date$
+
+*/
+#include "Fp.h"
+
+#ifdef IntelPentium
+#include <string.h>
+#endif
+
+
+int FP::Endian = NOT_KNOWN;
+Bitstring FP::fpEnv(32);
+
+int FP::GetFPRound()
+{
+ Bitstring temp(2);
+ //cout << "fpEnv = " << fpEnv << endl;
+ fpEnv.SubBitstring(21,temp);
+ //cout << "temp = " << temp << endl;
+ return (temp[0]>>30);
+}
+
+void FP::ClearFPEnvironment()
+{
+ fpEnv.Clear(0);
+ fpEnv.Clear(1);
+ fpEnv.Clear(2);
+ fpEnv.Clear(3);
+ fpEnv.Clear(4);
+}
+
+/***********************************************************************
+* Member: CheckEndian()
+* Purpose:
+* Return: void
+***********************************************************************/
+void FP::CheckEndian()
+{
+ // char *tmp = new char[4];
+ char *tmp;
+ unsigned long tmplong =1;
+
+ if (FP::Endian == NOT_KNOWN)
+ {
+ tmp= (char*)&tmplong;
+ if (tmp[0]== 1)
+ Endian= MYLITTLE_ENDIAN;
+ else
+ Endian= MYBIG_ENDIAN;
+ }
+
+ // delete tmp;
+}
+
+
+/***********************************************************************
+* Member: FP () Constructor
+* Purpose: Create a floating point number
+* Return: Nothing
+***********************************************************************/
+FP::FP()
+{
+ CheckEndian();
+ sign= -1;
+ hidden =-1;
+ sizeMant=0;
+ sizeExp=0;
+ decimal = NULL;
+ // fpEnv.Resize(32);
+}
+
+/***********************************************************************
+* Member: FP (int sizeM, int sizeE, int hiddenbit=0) Constructor
+* Purpose: Create a floating point number with the size of the exponent
+* and the mantissa defined and if the there is a hidden bit
+* 0 -> false
+* 1 -> true
+* Return: Nothing
+***********************************************************************/
+FP::FP(int sizeM, int sizeE,int hiddenbit)
+{
+ CheckEndian();
+ sign= -1;
+ hidden=hiddenbit;
+ sizeMant=sizeM;
+ sizeExp=sizeE;
+ decimal = NULL;
+ mant.Resize(sizeM);
+ exp.Resize(sizeE);
+ // fpEnv.Resize(32);
+}
+
+/***********************************************************************
+* Member: FP (Bitstring &fp,int sizeM,int sizeE,int hiddenbit=0) Constructor
+* Purpose: Create a floating point number with the size of the exponent
+* and the mantissa defined and if the there is a hidden bit
+* 0 -> false, 1 -> true and initialize it with "fp" as a
+* bit representation of a IEEE 754 floating point number
+* Return: Nothing
+***********************************************************************/
+
+FP::FP(Bitstring &fp,int sizeM, int sizeE,int hiddenbit)
+{
+ CheckEndian();
+ // fpEnv.Resize(32);
+ sign= -1;
+ hidden =hiddenbit;
+ sizeMant=sizeM;
+ sizeExp=sizeE;
+ decimal = NULL;
+
+ mant = Bitstring(sizeMant);
+ if (sizeExp > 0)
+ exp = Bitstring(sizeExp);
+ else
+ exp = Bitstring();
+
+ sign = fp.GetBit(0);
+ // cout << "exp (voor) = " << exp << endl;
+ if (sizeExp > 0) {
+ fp.SubBitstring(1,exp);
+ fp.SubBitstring(sizeExp+1,mant);
+ }
+ else // integer
+ fp.SubBitstring(0,mant);
+}
+
+/***********************************************************************
+* Member: FP(FP & copy) Copy constructor
+* Purpose: Create a floating point number with initiale value the
+* floating point "copy"
+* Return: Nothing
+***********************************************************************/
+FP::FP(FP & copy)
+{
+ CheckEndian();
+ // fpEnv.Resize(32);
+ sign = copy.sign;
+ hidden = copy.hidden;
+ sizeExp = copy.sizeExp;
+ sizeMant = copy.sizeMant;
+ mant = copy.mant;
+ exp = copy.exp;
+ if (copy.decimal != NULL) {
+ decimal = new char[256];
+ strcpy(decimal,copy.decimal);
+ }
+ else
+ decimal = NULL;
+ // cout << "copy decimal" << decimal << endl << flush;
+}
+
+
+
+FP& FP::operator = ( const FP ©)
+{
+ sign = copy.sign;
+ hidden = copy.hidden;
+ sizeExp = copy.sizeExp;
+ sizeMant = copy.sizeMant;
+ mant = copy.mant;
+ exp = copy.exp;
+ if (copy.decimal != NULL) {
+ decimal = new char[maxstr];
+ strcpy(decimal,copy.decimal);
+ }
+ else
+ decimal = NULL;
+ // cout << "copy decimal" << decimal << endl << flush;
+ return *this;
+}
+
+
+int FP::Sign(int sgn)
+{
+ int temp = sign;
+ if (sgn != -1)
+ {
+ if ((sgn == 0)||(sgn==1))
+ sign = sgn;
+ }
+ return temp;
+}
+
+Bitstring & FP::GetMantissa()
+{
+ // cout << "sizeMant = " << sizeMant << endl;
+ return mant;
+}
+
+Bitstring & FP::GetExponent()
+{
+ return exp;
+}
+
+Bitstring FP::PutMantissa(Bitstring &mantissa)
+{
+ Bitstring temp(mant);
+
+ mant=mantissa;
+ // mant.Resize(sizeMant+hidden); //in case the mantisa is too big
+ return temp;
+}
+
+Bitstring FP::PutExponent(Bitstring &exponent)
+{
+ Bitstring temp(exp);
+
+ exp=exponent;
+ exp.Resize(sizeExp); //in case the mantisa is too big
+ return temp;
+}
+
+int FP::IsNaN()
+{
+ int i;
+ Bitstring fullExp(sizeExp);
+ Bitstring fullMant(sizeMant+hidden);
+
+ if (sizeExp > 0) {
+ for (i=0; i < sizeExp ; i++)
+ fullExp.PutBit(i,1);
+ if (fullExp != exp)
+ return 0;
+ for (i=0; i < sizeMant ; i++)
+ fullMant.PutBit(i,0);
+ if (!hidden)
+ fullMant.PutBit(0,1);
+ return(fullMant != mant);
+ }
+ else
+ return 0;
+}
+
+int FP::istiny()
+{
+ int i;
+ Bitstring fullExp(sizeExp);
+ Bitstring fullMant(sizeMant);
+ if ((sizeMant > 0) && (sizeExp > 0)) {
+ for (i=0; i < sizeExp; i++)
+ fullExp.PutBit(i,0);
+ for (i=0; i < sizeMant ; i++)
+ fullMant.PutBit(i,0);
+ return ((fullExp == exp) && (fullMant != mant));
+ }
+ else
+ return 0;
+}
+
+int FP::isInf()
+{
+ int i;
+ Bitstring fullExp(sizeExp);
+ Bitstring fullMant(sizeMant);
+ if ((sizeMant > 0) && (sizeExp > 0)) {
+ for (i=0; i < sizeExp ; i++)
+ fullExp.PutBit(i,1);
+ if (fullExp == exp) {
+ i = 0;
+ if (!hidden)
+ i++;
+ for (;i < sizeMant;i++)
+ if (mant.GetBit(i) != 0)
+ return 0;
+ return 1;
+ }
+ else
+ return 0;
+ }
+ else
+ return 0;
+}
+
+int FP::isNan()
+{
+ int i;
+ Bitstring fullExp(sizeExp);
+ Bitstring fullMant(sizeMant);
+ if ((sizeMant > 0) && (sizeExp > 0)) {
+ for (i=0; i < sizeExp ; i++)
+ fullExp.PutBit(i,1);
+ if (fullExp == exp) {
+ i = 0;
+ if (!hidden)
+ i++;
+ for (;i < sizeMant;i++)
+ if (mant.GetBit(i) != 0)
+ return 1;
+ return 0;
+ }
+ else
+ return 0;
+ }
+ else
+ return 0;
+}
+
+
+void FP::CreateQFPNan()
+{
+
+ int i;
+ for (i=0; i < sizeExp ; i++)
+ exp.PutBit(i,1);
+
+ mant.PutBit(sizeMant-1,1); //PLAATS
+}
+
+
+FP& FP::operator = (const Bitstring ©)
+{
+ copy.SubBitstring(0,mant);
+ copy.SubBitstring(sizeMant,exp);
+ sign = copy.GetBit(sizeMant+sizeExp);
+/*
+ if (hidden)
+ {
+ mant.Resize(sizeMant+1);
+
+ Bitstring emptyExp(sizeExp);
+ for (int i=0; i< sizeExp; i++)
+ emptyExp.PutBit(i,0);
+
+ if (emptyExp != exp) //denormalized
+ mant.PutBit(sizeMant,1);
+ }
+*/
+ return *this;
+}
+
+
+void FP::SetFPRound (int rm)
+{
+ fpEnv.Clear(21);
+ fpEnv.Clear(22);
+ // cout << "fpEnv (SetFPR) = " << fpEnv << endl;
+ switch (rm)
+ {
+ case RM_UP:
+ fpEnv.Set(21);
+ break;
+ case RM_DOWN:
+ fpEnv.Set(22);
+ break;
+ case RM_ZERO:
+ fpEnv.Set(21);
+ fpEnv.Set(22);
+ break;
+ }
+ // cout << "fpEnv = " << fpEnv << endl;
+}
+
+void FP::GetFPExceptions(Bitstring E)
+{
+ fpEnv.SubBitstring(0,E);
+}
+
+ostream& operator << (ostream& outs, FP &strout)
+{int i;
+
+ if (strout.decimal != NULL) // decimal representation
+ outs << strout.decimal;
+ else {
+/*
+ if (strout.sizeExp > 0) {
+ if (strout.sign)
+ outs << '1';
+ else
+ outs << '0';
+ outs << " " << hex << strout.exp << " " << strout.mant;
+ }
+ else
+ outs << hex << strout.mant;
+*/
+ int size;
+ if (strout.sizeExp > 0)
+ size = 1+strout.sizeExp+strout.sizeMant;
+ else
+ size = strout.sizeMant;
+ Bitstring merge(size);
+ if (strout.sizeExp > 0) {
+ if (strout.sign)
+ merge.PutBit(0,1);
+ else
+ merge.PutBit(0,0);
+ for (i = 0; i < strout.sizeExp;i++)
+ merge.PutBit(i+1,strout.exp.GetBit(i));
+ for (i = 0; i < strout.sizeMant;i++)
+ merge.PutBit(1+strout.sizeExp+i,strout.mant.GetBit(i));
+ }
+ else { // integer
+ for (i = 0; i < strout.sizeMant;i++)
+ merge.PutBit(i,strout.mant.GetBit(i));
+ }
+ outs << merge;
+ }
+ return outs;
+}
+
+/*
+istream& operator >> (istream& ins, FP &instr)
+{
+ char str[255];
+
+ cin>> str;
+ instr.StringToBitstr(str);
+
+ return ins;
+}*/
+
+int FP::IsZero()
+{
+ int i;
+ if ((sizeMant > 0) && (sizeExp > 0)) {
+ for (i=0; i < sizeExp ; i++)
+ if ( exp.GetBit(i) != 0 ){
+ return 0;
+ }
+ i=0;
+ if (!hidden)
+ i++;
+ for (;i < sizeMant;i++)
+ if (mant.GetBit(i) != 0)
+ return 0;
+ }
+ return 1;
+}
+
+int FP::IsNegZero()
+{
+ return 0;
+ if ( sign == 0 )
+ return 0;
+ int i;
+ if ((sizeMant > 0) && (sizeExp > 0)) {
+ for (i=0; i < sizeExp ; i++)
+ if ( exp.GetBit(i) != 0 ){
+ return 0;
+ }
+ i=0;
+ if (!hidden)
+ i++;
+ for (;i < sizeMant;i++)
+ if (mant.GetBit(i) != 0)
+ return 0;
+ }
+ return 1;
+}
--- /dev/null
+/*
+##########################################################################
+# #
+# Program: IeeeCC754 #
+# #
+# Description: #
+# IeeeCC754 or IEEE 754 Compliance Checker is a precision and range #
+# independent tool to test whether an implementation of #
+# floating-point arithmetic (in hardware or software) is compliant #
+# with the principles of the IEEE 754-854 floating-point standards. #
+# You can find out more about the testing tool IeeeCC754 at #
+# #
+# http://win-www.uia.ac.be/u/cant/ieeecc754.html #
+# #
+# This tool is in parts based on and greatly benefited from the #
+# the program FPTEST developed by Jerome Coonen. For a full #
+# description of the extensions to FPTEST and a reference to #
+# the original Coonen program, please refer to the URL given above. #
+# For the options available with the program IeeeCC754 and its #
+# compatibility with David Hough's hexadecimal UCB format, we #
+# also refer to the file readme.usage. #
+# #
+# Usage: see readme.usage #
+# #
+# Responsible authors: #
+# Brigitte Verdonk #
+# Annie Cuyt #
+# #
+# Contributors: #
+# Johan Bogo (1998-1999) #
+# Tim Gevers (10-12/2000) #
+# Debby Ooms (1996-1997) #
+# Geert Vermuyten (1996-1997) #
+# Dennis Verschaeren (09/1996-06/2000) #
+# #
+# Copyright (C) 2000 University of Antwerp #
+# #
+# This program can be obtained from the authors, free, but WITHOUT ANY #
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or #
+# FITNESS FOR A PARTICULAR PURPOSE. #
+# #
+# Contact: #
+# Brigitte.Verdonk@uia.ua.ac.be #
+# Department of Mathematics and Computer Science #
+# University of Antwerp (UIA) #
+# Universiteitsplein 1 #
+# B2610 Antwerp, BELGIUM #
+# #
+##########################################################################
+
+Filename:
+ $RCSfile$
+
+Last updated:
+ $Date$
+
+*/
+#include <Hex.h>
+
+#ifdef IntelPentium
+#include <string.h>
+#endif
+
+/*class implementation*/
+
+/***********************************************************************
+* Member: GetBin(char v)
+* Purpose: returns a Bitstring with the corresponding binary value of "v"
+* Return: Bitstring with binary value of "v"
+***********************************************************************/
+void Hex::GetBin(char v)
+{
+ // cout << "char = " << v << endl;
+ switch (v)
+ {
+ case '0':
+ bitstr[0] = 0;
+ // Bitstring::StringToBitstr("0000");
+ break;
+ case '1':
+ bitstr[0] = 1;
+ // StringToBitstr("0001");
+ break;
+ case '2':
+ bitstr[0] = 2;
+ // StringToBitstr("0010");
+ break;
+ case '3':
+ bitstr[0] = 3;
+ // StringToBitstr("0011");
+ break;
+ case '4':
+ bitstr[0] = 4;
+ // StringToBitstr("0100");
+ break;
+ case '5':
+ bitstr[0] = 5;
+ // StringToBitstr("0101");
+ break;
+ case '6':
+ bitstr[0] = 6;
+ // StringToBitstr("0110");
+ break;
+ case '7':
+ bitstr[0] = 7;
+ // StringToBitstr("0111");
+ break;
+ case '8':
+ bitstr[0] = 8;
+ // StringToBitstr("1000");
+ break;
+ case '9':
+ bitstr[0] = 9;
+ // StringToBitstr("1001");
+ break;
+ case 'A':
+ case 'a':
+ bitstr[0] = 10;
+ // StringToBitstr("1010");
+ break;
+ case 'B':
+ case 'b':
+ bitstr[0] = 11;
+ // StringToBitstr("1011");
+ break;
+ case 'C':
+ case 'c':
+ bitstr[0] = 12;
+ // StringToBitstr("1100");
+ break;
+ case 'D':
+ case 'd':
+ bitstr[0] = 13;
+ // StringToBitstr("1101");
+ break;
+ case 'E':
+ case 'e':
+ bitstr[0] = 14;
+ // StringToBitstr("1110");
+ break;
+ case 'F':
+ case 'f':
+ bitstr[0] = 15;
+ // StringToBitstr("1111");
+ break;
+ }
+}
+
+
+/***********************************************************************
+* Member: GetHex(Bitstring &b)
+* Purpose: It gives the character that is represented in "b"
+* Return: returns b as a character
+***********************************************************************/
+char Hex::GetHex(Bitstring &b) const
+{
+
+ Bitstring temp(4);
+
+
+ temp.StringToBitstr("0000");
+ if(temp == b)
+ return '0';
+
+ temp.StringToBitstr("0001");
+ if(temp == b)
+ return '1';
+
+ temp.StringToBitstr("0010");
+ if(temp== b)
+ return '2';
+
+ temp.StringToBitstr("0011");
+ if(temp == b)
+ return '3';
+
+ temp.StringToBitstr("0100");
+ if(temp == b)
+ return '4';
+
+ temp.StringToBitstr("0101");
+ if(temp == b)
+ return '5';
+
+ temp.StringToBitstr("0110");
+ if(temp == b)
+ return '6';
+
+ temp.StringToBitstr("0111");
+ if(temp == b)
+ return '7';
+
+ temp.StringToBitstr("1000");
+ if(temp == b)
+ return '8';
+
+ temp.StringToBitstr("1001");
+ if(temp == b)
+ return '9';
+
+ temp.StringToBitstr("1010");
+ if(temp == b)
+ return 'A';
+
+ temp.StringToBitstr("1011");
+ if(temp == b)
+ return 'B';
+
+ temp.StringToBitstr("1100") ;
+ if(temp == b)
+ return 'C';
+
+ temp.StringToBitstr("1101");
+ if(temp == b)
+ return 'D';
+
+ temp.StringToBitstr("1110");
+ if(temp == b)
+ return 'E';
+
+ temp.StringToBitstr("1111");
+ if(temp == b)
+ return 'F';
+
+ return '\0';
+
+}
+
+
+/***********************************************************************
+* Member: Hex() Constructor
+* Purpose: Create empty hexadecimal bitstring
+* Return: Nothing
+***********************************************************************/
+Hex::Hex()
+{ }
+
+
+/***********************************************************************
+* Member: Bitstring(unsigned long size) Constructor
+* Purpose: Create a hexadecimal bitstring of size "size"*4
+* Return: Nothing
+***********************************************************************/
+Hex::Hex(unsigned long size)
+{
+ Resize(size);
+}
+
+
+/***********************************************************************
+* Member: Hex(char * str) Constructor
+* Purpose: Create hexadecimal bitstring with "str" as initiale value
+* Return: Nothing
+***********************************************************************/
+Hex::Hex(char *hstr)
+{
+ long i,j;
+ Hex t1(4),t2(4);
+
+ length = strlen(hstr)*4;
+ lengthT= sizeof(unsigned long) * 8;
+ lengthBlock = (length/lengthT)+1;
+
+ bitstr = new unsigned long [lengthBlock];
+
+ for (i=0;i<lengthBlock;i++)
+ bitstr[i]=0;
+
+ j=0;
+ for (i= (length/4) -1; i >= 0; i--)
+ {
+ t1.GetBin(hstr[i--]);
+ if (i >= 0)
+ {
+ t2.GetBin(hstr[i]);
+ t2.Concat(t1);
+ PutByte(j,t2);
+ }
+ else
+ PutByte(j,t1);
+ j++;
+ }
+}
+
+
+/***********************************************************************
+* Member: Hex(Bitstring & copy)
+* Purpose: Create a hexadecimal bitstring with initiale value the bitstring
+* "copy"
+* Return: Nothing
+***********************************************************************/
+Hex::Hex(const Bitstring ©)
+{
+ int i=0;
+
+ length = copy.Length();
+ lengthT = sizeof(unsigned long)*8;
+ lengthBlock = (length /lengthT) +1;
+
+ bitstr = new unsigned long [lengthBlock];
+
+ for (i=0 ; i< lengthBlock; i++)
+ bitstr[i]= copy[i];
+
+ if ((length%4)!= 0)
+ Resize(length/4 +1);
+
+}
+
+
+/***********************************************************************
+* Member: Resize (unsigned long len)
+* Purpose: Change the length of the bitstring to "len"*4. If the new length is
+* larger then the length, the bitstring is appended with 0, else
+* the bitstring is truncated to the new length "len"*4
+* Return: Previous length
+***********************************************************************/
+unsigned long Hex::Resize(unsigned long len)
+{
+ return Bitstring::Resize(len*4);
+}
+
+/***********************************************************************
+* Member: BitstrToString()
+* Purpose: Converts a hexadecimal bitstring to a C-string
+* Return: length >0 -> The C-string
+* else -> "Bitstring is empty"
+***********************************************************************/
+void Hex::BitstrToString(char* out) const
+{
+ Bitstring temp(4);
+ int i;
+
+ out= new char[(length/4)+2];
+ for (i = 0 ;i< length/4; i++)
+ {
+ // cout << "i = " << i << endl << flush;
+ SubBitstring(i*4,temp);
+ // cout << "temp = " << temp << endl << flush;
+ out[length/4 -i -1]=GetHex(temp);
+ }
+ out[(length/4)]='\0';
+}
+
+/***********************************************************************
+* Member: StringToBitstr(char *str)
+* Purpose: Converts a C-string to a hexadecimal bitstring
+* Return: converted bitstring
+***********************************************************************/
+void Hex::StringToBitstr(char *hstr)
+{
+ long i,j,k;
+ Bitstring t1(4),t2(4);
+ unsigned long tmp;
+
+ length = strlen(hstr)*4;
+ lengthT= sizeof(unsigned long) * 8;
+ if (length % lengthT == 0)
+ lengthBlock = length/lengthT;
+ else
+ lengthBlock = (length/lengthT)+1;
+ if (bitstr)
+ delete [] bitstr;
+ // cout << "lengthBlock = " << lengthBlock << endl << flush;
+ bitstr = new unsigned long [lengthBlock];
+ for (i=0;i<lengthBlock;i++)
+ bitstr[i]=0;
+ j=0;
+ for (i= 0; i < length/4;) {
+ // cout << "hstr[i] = " << hstr[i] << endl << flush;
+ tmp = 0;
+ for (k = 0; k < 7;k++) {
+ if (hstr[i] <= '9')
+ tmp += hstr[i++] - '0';
+ else
+ tmp += hstr[i++] - 'a' + 10;
+ // cout << hex << tmp << endl;
+ tmp *= 16;
+ }
+ if (hstr[i] <= '9')
+ tmp += hstr[i++] - '0';
+ else
+ tmp += hstr[i++] - 'a' + 10;
+ // cout << "tmp = " << hex << tmp << endl;
+ bitstr[j] = tmp;
+ // cout << hex << bitstr[j] << " " << flush;
+ j++;
+ }
+/*
+for (i= (length/4) -1; i >= 0; i--)
+ {
+ t1.GetBin(hstr[i--]);
+ // cout << "t1 = " << t1 << endl << flush;
+ if (i >= 0)
+ {
+ t2.GetBin(hstr[i]);
+ // cout << "t2 = " << t2 << endl << flush;
+ t2.Concat(t1);
+ // cout << "t2 = " << t2 << endl << flush;
+ PutByte(j,t2);
+ }
+ else
+ PutByte(j,t1);
+ j++;
+ }
+*/
+}