ࡱ; vT  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuwxyz{|}~R F'CompObj^WordDocumentObjectPool9^9^  FMicrosoft Word 6.0 (dokument)NB6WWord.Document.6;  Oh+'0/Hg m y   &PowerMac:Microsoft Word:Mallar:Normala============Suggested LIA-2 section 5.3 (1/2), elementary transcendental operations=============Gran SchumacherܥhQe XTVVZZZZZ]F]vvv4B]6vv"  &X6ZUv5UU6UZZvUUUUZZZ [ZZZZĪUUSuggested LIA-2 section 5.3: elementary transcendental operations on floating point type values In this document invalid is used instead of undefined. The reason is that undefined should be interpreted as invalid or pole (a.k.a. divide-by-zero). They were joined in LIA-1 because some hardware still in use cannot make the distinction. But when they can be distinguished, they are allowed, in LIA-1, to be distinguished (see sections A.6.1.2 and C.2 of LIA-1). For LIA-2, I see no reason to join them up. The term subnormal is used to mean denormal or zero (including negative zero). Elementary transcendental floating point operations I is an LIA-1 conforming integer type. F is an LIA-1 conforming floating point type. The operations in this section are specified using the trans_resultF helper function and an approximation helper function for each operation. The approximation helper functions return a result in R. They may be literally undefined for some arguments, just like, e.g., arcsin(2) is undefined. The operations return a result in F ( {(,0,+(} or cause a notification. They are defined for all arguments in F (and I in the case of ipowerFI), plus all IEC 559 special values (infinities, negative zero and nans). Note: The approximating helper functions never deal with notifications or IEC 559 special values. One can thus think of the approximating helper functions as a version of the corresponding mathematical function, that just need not always be exact. Notifications are dealt with either explicitly in the operation definitions (invalid, pole, angle_too_big), or via the trans_resultF helper function detailed below (floating_overflow, underflow). IEC 559 special values are dealt with explicitly in the operation definitions. The approximation helper functions for the individual operations in this subclause have maximum error parameters that describe the maximum relative error of the helper function composed with nearestF, for normalised results. The maximum error parameter also describe the maximum absolute error for subnormal continuation values if denormF=true. The maximum error parameters shall be available to programs. That for an helper function hF, approximating f, the maximum error is max_error_opF means that |f(x, ...) nearestF(hF(x, ...))| ( max_error_opF * reF(f(x, ...))p Note: Partially conforming implementations may have greater values for maximum error parameters than stipulated below. The results of the approximating helper functions in this clause must be exact for certain arguments, and may be exact for all arguments. If the approximating helper function is exact for all arguments, then the corresponding maximum error parameter should be 0.5. The approximation helper functions in this clause are required to be monotonous on the same intervals as the mathematical function they are approximating are (strictly) monotonous. There is no general requirement that the approximation helper functions are strictly monotonous, however. The unit argument trigonometric and inverse trigonometric approximating helper functions are excepted from the monotonicity requirement for the unit argument (but not for the other argument(s)). For the radian trigonometric helper functions, this requirement is imposed only for arguments, x, such that |x| ( big_anglerF. The approximation helper functions are required to be zero exactly at the points where the approximated mathematical function is exactly zero. At points where the approximation helper functions are not zero, they are required to have the same sign as the approximated mathematical function at that point. For the radian trigonometric helper functions, this requirement is imposed only for arguments, x, such that |x| ( big_anglerF. Note: For the operations the continuation value after an underflow may be zero (or negative zero) as given by trans_resultF, even though the approximation helper function is not zero at that point. Such zero results are required to be accompanied by an underflow notification. When appropriate zero may also be returned for IEC 559 infinities arguments. See the individual specifications. The trans_resultF helper function trans_resultF is like resultF extended with specifications for the continuation value on overflow, but simplified concerning underflow: it always underflows for nonzero results that have an absolute value less than fminNF. It also returns 0 for negative underflows that round (or are flushed) to zero, if possible. Also, the rounding is fixed to nearestF. This is user visible only in the cases where the operations approximation helper function is (required to be) exact, but where that value is not representable in F, e.g. e or (. [One could, e.g., parametrise trans_resultF like resultF on the rounding function. There may be reason to do so for the unit arg. inv. trig. ops.] trans_resultF : R ( F ({underflow, floating_overflow} trans_resultF(x) = nearestF(x) if fminNF ( |nearest(FD(x)| ( fmaxF trans_resultF(x) = 0 if x = 0 trans_resultF(x) = floating_overflow(+() if nearestF(x) > fmaxF trans_resultF(x) = floating_overflow(() if nearestF(x) < fmaxF trans_resultF(x) = underflow(nearestF(x)) if denormF=true and (nearestF(x) < 0 or x > 0) and |nearestF(x)| < fminNF trans_resultF(x) = underflow(0) if denormF=true and 0 is available and nearestF(x) = 0 and x < 0 trans_resultF(x) = underflow(0) if denormF=true and 0 is not available and nearestF(x) = 0 and x < 0 trans_resultF(x) = underflow(0) if denormF=false and 0 < x and nearestF(FD(x) < fminNF trans_resultF(x) = underflow(0) if denormF=false and 0 is available and fminNF < nearestF(FD(x) and x < 0 trans_resultF(x) = underflow(0) if denormF=false and 0 is not available and fminNF < nearestF(FD(x) and x < 0 Note: This specifies underflow after rounding (considering denormal values even if denormF=false). Operations for exponentiations The power*F and powerm1*F helper functions below need be defined only for first arguments that are (0, and need not be defined when both of the arguments are zero. Note: There are two advantages with expm1F (and powerm1F) operation below: Firstly, expm1F(x) (and powerm1F(b,x)) is much more accurate than subF(expF(x),1) (and subF(powerm1F(b,x),1)) when the exponent argument is close to zero. Secondly, the expm1F operation does not underflow for very negative exponent arguments. Something which may be advantageous if underflow handling is slow, and high accuracy for very negative arguments is not needed. There are two maximum error parameters for approximate exponentiations: max_error_expF ( F max_error_powerF ( F The max_error_expF parameter is required to be in the interval [0.5, 1.5*rnd_errorF]. The max_error_powerF parameter is required to be in the interval [max_error_expF,2*rnd_errorF]. [Any ranges of arguments for which the accuracy requirements maybe should be relaxed? Make the max_error_powerF parameter depend upon the arguments (cmp. Ada.)? And/or a notification when the accuracy may be very degraded? Ada (but no accessible parameter): max_error_powerF(x,y) ( [0.5, 4+|y*ln(x)/32|], if x > 0. What about max_error_powerF(x,y) ( [max_error_expF, 2*rnd_errorF+|y*ln(x)/32|]???] Powerof argument base The power*F approximation helper function: power*F : F ( R ( R [split into power*F:F(F(R and ipower*FI:F(I(R?] power*F(x,y) returns a close approximation to xy in R, with maximum error max_error_powerF. Further requirements on the power*F approximation helper function: power*F(1,y) = 1 if y ( R power*F(x,0) = 1 if x ( F and x > 0 power*F(x,1) = x if x ( F and x ( 0 power*F(x,y) < fminDF/2 if x ( F and x > 0 and y ( R and xy < fminDF/3 The powerF operation: powerF : F ( F ( F ( {invalid, underflow, floating_overflow, pole} powerF(x,y) = trans_resultF(power*F(x,y)) if x ( F and x>0 and y ( F = powerF(0,y) if x = 0 and y ( F ( {(, 0, +(} = powerF(x,0) if y = 0 and x ( F ( {(, +(} = 0 if x = 0 and y ( F and y>0 = invalid(1) if x = 0 and y = 0 [no notification?] = pole(+() if x = 0 and y ( F and y<0 = 0 if x ( F and 0(x<1 and y=+( = +( if x ( F and 0(x<1 and y=( = invalid(1) if x =1 and (y=+( or y=() [no notification?] = +( if x ( F and x>1 and y=+( = 0 if x ( F and x>1 and y=( = +( if x=+( and ((y ( F and y>0) or y=+() = invalid(1) if x=+( and y = 0 [no notification?] = 0 if x=+( and ((y ( F and y<0) or y=() = invalid(qnan) if ((x ( F and x<0) or x=() and y ( F ( {+(,(} = qnan if x is a quiet nan and y is not a signalling nan = qnan if y is a quiet nan and x is not a signalling nan = invalid(qnan) if x is a signalling nan or y is a signalling nan Note: powerF(x,y) will overflow approximately when xy > fmaxF, i.e., if x > 1, approximately when y > logx(fmaxF), and if 0 < x < 1, approximately when y < logx(fmaxF) (which is a negative number). It will not overflow when x = 0 or when x= 1. The ipowerFI operation: ipowerFI : F ( I ( F ( {invalid, underflow, floating_overflow, pole} ipowerFI(x,y) = trans_resultF(power*F(x,y)) if x ( F and x>0 and y ( I = trans_resultF(power*F(x,y)) if x ( F and x<0 and y ( I and 2|y = trans_resultF(power*F(x,y)) if x ( F and x<0 and y ( I and not 2|y = 0 if x = 0 and y ( I and y > 0 = invalid(1) if x = 0 and y = 0 [no notification?] = pole(+() if x = 0 and y ( I and y < 0 = 0 if x = 0 and y ( I and y > 0 and 2|y = 0 if x = 0 and y ( I and y > 0 and not 2|y = invalid(1) if x = 0 and y = 0 [no notification?] = pole(+() if x = 0 and y ( I and y < 0 and 2|y = pole(() if x = 0 and y ( I and y < 0 and not 2|y = +( if x = +( and y ( I and y>0 = invalid(1) if x = +( and y = 0 [no notification?] = 0 if x = +( and y ( I and y < 0 = +( if x = ( and y ( I and y > 0 and 2|y = ( if x = ( and y ( I and y > 0 and not 2|y = invalid(1) if x = ( and y = 0 [no notification?] = 0 if x = ( and y ( I and y < 0 and 2|y = 0 if x = ( and y ( I and y < 0 and not 2|y = qnan if x is a quiet nan = invalid(qnan) if x is a signalling nan Note: powerI (in clause 5.1) does not allow negative exponents since the exact result then is not in I. powerF (here) does not allow (any) negative bases since the (exact) result is not in R unless the exponent is integer. ipowerFI takes care of this latter case. A binding may combine powerF and ipowerFI to a power operation that checks if the floating point exponent has an integer value when the base argument is negative. Note: ipowerF(x,y) will overflow approximately when xy > fmaxF, i.e., if x > 1, approximately when y > logx(fmaxF), and if 0 < x < 1, approximately when y < logx(fmaxF). It will not overflow when x = 0 or when x= 1. Powerof argument base, minus one The powerm1*F approximation helper function: powerm1*F : F ( F ( R powerm1*F(x, y) returns a close approximation to xy1 in R, with maximum error max_error_powerF. Further requirements on the powerm1*F approximation helper function: powerm1*F(0, y) = 1 if y ( F and y > 0 powerm1*F(x, y) = 1 if x ( F and x > 0 and y ( F and powerm1*F(x,y) ( xy1 and xy < epsilonF/(3*rF) powerm1*F(x, 1) = x1 if x ( F and x ( 0 powerm1*F(x, y) ( power*F(x, y) if x ( F and x > 0 and y ( F Note: powerm1*F(x, y) ( y*ln x if x ( F and x > 0 and y ( F and |y*ln x| < epsilonF/rF The powerm1F operation: powerm1F : F ( F ( F ( {invalid, underflow, floating_overflow, pole} powerm1F(x,y) = trans_resultF(powerm1*F(x,y)) if x ( F and x>0 and y ( F and y ( 0 = powerm1F(0,y) if x = 0 and y ( F ( {(, 0, +(} = 0 if y = 0 and x ( F and 0 < x < 1 = 0 if y = 0 and x ( F and 1 ( x = 0 if y = 0 and x = +( = 0 if y = 0 and x ( F and 0 < x < 1 = 0 if y = 0 and x ( F and 1 ( x = 0 if y = 0 and x = +( = 1 if x = 0 and y ( F and y>0 = invalid(0) if x = 0 and y = 0 [no notification?] = invalid(0) if x = 0 and y = 0 [no notification?] = pole(+() if x = 0 and y ( F and y<0 = 1 if x ( F and 0(x<1 and y=+( = +( if x ( F and 0(x<1 and y=( = invalid(0) if x =1 and (y=+( or y=() [no notification?] = +( if x ( F and x>1 and y=+( = 1 if x ( F and x>1 and y=( = +( if x=+( and ((y ( F and y>0) or y=+() = invalid(0) if x=+( and y = 0 [no notification?] = 1 if x=+( and ((y ( F and y<0) or y=() = invalid(qnan) if ((x ( F and x<0) or x=() and y ( F ( {+(,0,(} = qnan if x is a quiet nan and y is not a signalling nan = qnan if y is a quiet nan and x is not a signalling nan = invalid(qnan) if x is a signalling nan or y is a signalling nan Note: powerm1F(x,y) will overflow approximately when xy > fmaxF, i.e., if x > 1, approximately when y>logx(fmaxF), and if 0 < x < 1, approximately when y < logx(fmaxF). It will not overflow when x = 0 or when x= 1. Powerof 2 The exp2*F approximation helper function: exp2*F : F ( R exp2*F(x) returns a close approximation to 2x in R, with maximum error max_error_expF. Further requirements on the exp2*F approximation helper function: exp2*F(x) = 1 if x ( F and exp2*F(x) ( 2x and log2(1(epsilonF/(2*rF))) < x < log2(1+(epsilonF/2)) exp2*F(x) = 2x if x ( (F ( Z) and 2x ( F exp2*F(x) < fminDF/2 if x ( F and x < log2(fminDF)3 The exp2F operation: exp2F : F ( F ( {underflow, floating_overflow} exp2F(x) = trans_resultF(exp2*F(x)) if x ( F = 1 if x = 0 = +( if x = +( = 0 if x = ( = qnan if x is a quiet nan = invalid(qnan) if x is a signalling nan Note: exp2F(x) will overflow approximately when x > log2(fmaxF). Powerof 10 The exp10*F approximation helper function: exp10*F : F ( R exp10*F(x) returns a close approximation to 10x in R, with maximum error max_error_expF. Further requirements on the exp10*F approximation helper function: exp10*F(x) = 1 if x ( F and exp10*F(x) ( 10x and log10(1(epsilonF/(2*rF))) < x < log10(1+(epsilonF/2)) exp10*F(x) = 10x if x ( (F (Z) and 10x ( F exp10*F(x) < fminDF/2 if x ( F and x < log10(fminDF)3 The exp10F operation: exp10F : F ( F ( {underflow, floating_overflow} exp10F(x) = trans_resultF(exp10*F(x)) if x ( F = 1 if x = 0 = +( if x = +( = 0 if x = ( = qnan if x is a quiet nan = invalid(qnan) if x is a signalling nan Note: exp10F(x) will overflow approximately when x > log10(fmaxF). Powerof e (natural exponentiation) The exp*F approximation helper function: exp*F : F ( R exp*F(x) returns a close approximation to ex in R, with maximum error max_error_expF. Further requirements on the exp*F approximation helper function: exp*F(1) = e exp*F(x) = 1 if x ( F and exp*F(x) ( ex and ln(1(epsilonF/(2*rF))) < x < ln(1+(epsilonF/2)) exp*F(x) < fminDF/2 if x ( F and x < ln(fminDF)3 The expF operation: expF : F ( F ( {underflow, floating_overflow} expF(x) = trans_resultF(exp*F(x)) if x ( F = 1 if x = 0 = +( if x = +( = 0 if x = ( = qnan if x is a quiet nan = invalid(qnan) if x is a signalling nan Note: expF(1) = nearestF(e). Note: expF(x) will overflow approximately when x > ln(fmaxF). Powerof e, minus one (natural exponentiation, minus one) The expm1*F approximating helper function: expm1*F : F ( R expm1*F(x) returns a close approximation to ex1 in R, with maximum error max_error_expF. Further requirements on the expm1*F approximation helper function: expm1*F(1) = e1 expm1*F(x) = x if x ( F and expm1*F(x) ( ex1 and epsilonF/rF ( x < 0.5*epsilonF/rF [0.5?] expm1*F(x) = 1 if x ( F and expm1*F(x) ( ex1 and x < ln(epsilonF/(3*rF)) expm1*F(x) ( exp*F(x) if x ( F The expm1F operation: expm1F : F ( F ( {underflow, floating_overflow} expm1F(x) = trans_resultF(expm1*F(x)) if x ( F and |x| ( 0.5*epsilonF/rF = x [don't have as spec. case!?] if x ( F and |x| < 0.5*epsilonF/rF = 0 if x = 0 = +( if x = +( = 1 if x = ( = qnan if x is a quiet nan = invalid(qnan) if x is a signalling nan Note: underflow is explicitly avoided, when possible. LIA-1 requires that fminNF ( epsilonF, but does not require that fminNF ( epsilonF/rF. A requirement that expm1F(x) = x if x ( F and |x| ( fminNF, would thus be requireing results for some arguments of some (very rare) floating point type that are more than 0.5 ulp in error. For such arguments in such floating point types, underflow is still appropriate, and it is always appropriate to allow results that are at most 0.5 ulp in error. Note: expm1F(1) = nearestF(e1). Note: expm1F(x) will overflow approximately when x > ln(fmaxF). [I think one should not avoid underflow like this for any operation, especially not expm1F and ln1pF.] Operations for logarithms There are two maximum error parameters for approximate logarithms: max_error_lnF ( F max_error_logbaseF ( F The max_error_lnF parameter is required to be in the interval [0.5, 1.5*rnd_errorF]. The max_error_logbaseF parameter is required to be in the interval [max_error_lnF, 2*rnd_errorF]. [Any ranges of arguments for which the accuracy requirements maybe should be relaxed? Make the max_error_logbaseF parameter depend upon the arguments (cmp. Ada and exponentiation)? Notification?] Ada: max_error_powerF(x,y) ( [0.5, 4+|y*ln(x)/32|], but no such dependency mentioned for log op. What about max_error_logbaseF(x,y) ( [max_error_lnF, 2*rnd_errorF+...x...y...]????????] Argument base logarithmof The logbase*F approximating helper function: logbase*F : F ( F ( R logbase*F(x, y) returns a close approximation to logx(y) in R, with maximum error max_error_logbaseF. Further requirements on the logbase*F approximation helper function: logbase*F(x, x) = 1 if x ( F and x > 0 and x ( 1 The logbaseF operation: logbaseF : F ( F ( F ( {invalid, pole} logbaseF(x,y) = trans_resultF(logbase*F(x,y)) if x ( F and x > 0 and x ( 1 and y ( F and y > 0 = logbaseF(0,y) if x =0 and y ( F ( {(,0,+(} = logbaseF(x,0) if y =0 and x ( F ( {(, +(} = pole(+() if x ( F and 0 1 = invalid(qnan) if x = 1 and y = 1 = pole(() if x = 1 and y ( F and 0 ( y < 1 = invalid(qnan) if ((x ( F and x(0) or x=() and y ( F ( {+(,(} = invalid(qnan) if ((y ( F and y<0) or y=() and x ( F ( {+(,(} = qnan if x is a quiet nan and y is not a signalling nan = qnan if y is a quiet nan and x is not a signalling nan = invalid(qnan) if x is a signalling nan or y is a signalling nan Argument base logarithmof one plus second argument The logbase1p*F approximating helper function: logbase1p*F : F ( F ( R logbase1p*F(x,y) returns a close approximation to logx(1+y) in R, with maximum error max_error_logbaseF. Further requirements on logbase1p*F approximating helper function: logbase1p*F(x,x1) = 1 if x,x1 ( F and x > 0 and x ( 1 logbase1p*F(x,y) ( logbase*F(x,y) if x ( F and 0 < x < 1 and y ( F and y > 0 logbase1p*F(x,y) ( logbase*F(x,y) if x ( F and 1 < x and y ( F and y > 0 Note: logbase1p*F(x, y) ( y/ln(x) if x ( F and x > 0 and x ( 1 and y ( F and |y/ln(x)| < epsilonF/rF The logbase1pF operation: logbase1pF : F ( F ( F ( {invalid, underflow, pole} logbase1pF(x,y) = trans_resultF(logbase1p*F(x,y)) if x ( F and x > 0 and x ( 1 and y ( F and y > 1 and y ( 0 = logbase1pF(0,y) if x =0 and y ( F ( {(,0,+(} = 0 if y = 0 and x ( F and 0 < x < 1 = 0 if y = 0 and x ( F and 1 < x = 0 if y = 0 and x = +( = 0 if y = 0 and x ( F and 0 < x < 1 = 0 if y = 0 and x ( F and 1 < x = 0 if y = 0 and x = +( = invalid(qnan) if (y =0 or y = 0) and x = 1 = pole(+() if x ( F and 0 0 = invalid(qnan) if x = 1 and y = 0 = pole(() if x = 1 and y ( F and 1 ( y < 0 = invalid(qnan) if ((x ( F and x(0) or x=() and y ( F ( {+(,0,(} = invalid(qnan) if ((y ( F and y<1) or y=() and x ( F ( {+(,(} = qnan if x is a quiet nan and y is not a signalling nan = qnan if y is a quiet nan and x is not a signalling nan = invalid(qnan) if x is a signalling nan or y is a signalling nan 2Logarithmof The log2*F approximation helper function: log2*F : F ( R log2*F(x) returns a close approximation to log2(x) in R, with maximum error max_error_lnF. Further requirements on the log2*F approximation helper function: log2*F(x) = log2(x) if x ( F and log2(x) ( Z The log2F operation: log2F : F ( F ( {invalid, pole} log2F(x) = trans_resultF(log2*F(x)) if x ( F and x > 0 = pole(() if x = 0 = pole(() if x = 0 = +( if x = +( = invalid(qnan) if (x ( F and x < 0) or x = ( = qnan if x is a quiet nan = invalid(qnan) if x is a signalling nan 10Logarithmof The log10*F approximation helper function: log10*F : F ( R log10*F(x) returns a close approximation to log10(x) in R, with maximum error max_error_lnF. Further requirements on the log10*F approximation helper function: log10*F(x) = log10(x) if x ( F and log10(x) ( Z The log10F operation: log10F : F ( F ( {invalid, pole} log10F(x) = trans_resultF(log10*F(x)) if x ( F and x > 0 = pole(() if x = 0 = pole(() if x = 0 = +( if x = +( = invalid(qnan) if (x ( F and x < 0) or x = ( = qnan if x is a quiet nan = invalid(qnan) if x is a signalling nan Natural logarithmof The ln*F approximation helper function: ln*F : R ( R ln*F(x) returns a close approximation to ln(x) in R, with maximum error max_error_lnF. Further requirements on the ln*F approximation helper function: ln*F(e) = 1 The lnF operation: lnF : F ( F ( {invalid, pole} lnF(x) = trans_resultF(ln*F(x)) if x ( F and x > 0 = pole(() if x = 0 = pole(() if x = 0 = +( if x = +( = invalid(qnan) if (x ( F and x < 0) or x = ( = qnan if x is a quiet nan = invalid(qnan) if x is a signalling nan Natural logarithmof one plus the argument The ln1p*F approximation helper function: ln1p*F : R ( R ln1p*F(x) returns a close approximation to ln(1+x) in R, with maximum error max_error_lnF. Further requirements on the ln1p*F approximation helper function: ln1p*F(e1) = 1 ln1p*F(x) = x if x ( F and ln1p*F(x) ( ln(1+x) and 0.5*epsilonF/rF < x ( epsilonF/rF [0.5?] ln1p*F(x) ( ln*F(x) if x ( F and x > 0 The ln1pF operation: ln1pF : F ( F ( {invalid, pole, underflow} ln1pF(x) = trans_resultF(ln1p*F(x)) if x ( F and x > 1 and |x| ( 0.5*epsilonF/rF = x [don't have as spec. case!?] if x ( F and |x| < 0.5*epsilonF/rF = 0 if x = 0 = pole(() if x = 1 = +( if x = +( = invalid(qnan) if (x ( F and x < 1) or x = ( = qnan if x is a quiet nan = invalid(qnan) if x is a signalling nan Note: underflow is explicitly avoided, when possible. LIA-1 requires that fminNF ( epsilonF, but does not require that fminNF ( epsilonF/rF. A requirement that ln1pF(x) = x if x ( F and |x| ( fminNF would thus be requireing results for some arguments of some (very rare) floating point type that are more than 0.5 ulp in error. For such arguments in such floating point types, underflow is still appropriate, and it is always appropriate to allow results that are at most 0.5 ulp in error. Operations for hyperbolics There are three maximum error parameters for approximate hyperbolics: max_error_sinhF ( F max_error_tanhF ( F max_error_sechF ( F The max_error_sinhF parameter is required to be in the interval [0.5, 2*rnd_errorF]. The max_error_tanhF parameter is required to be in the interval [max_error_sinhF, 2*rnd_errorF]. The max_error_sechF parameter is required to be in the interval [max_error_sinhF, 2*rnd_errorF]. Sinus hyperbolicus The sinh*F approximation helper function: sinh*F : F ( R sinh*F(x) returns a close approximation to sinh(x) in R, with maximum error max_error_sinhF. Further requirements on the sinh*F approximation helper function: sinh*F(x) = x if x ( F and sinh*F(x) ( sinh(x) and |x| < ((2*epsilonF/rF) [2?] sinh*F(x) = sinh*F(x) if x ( F sinh*F(x) ( cosh*F(x) if x ( F The sinhF operation: sinhF : F ( F ( {floating_overflow} [underflow, ?] sinhF(x) = trans_resultF(sinh*F(x)) if x ( F and |x| > fminNF = x [don't have as spec. case?] if x ( F and |x| ( fminNF = 0 if x = 0 = ( if x = ( = +( if x = +( = qnan if x is a quiet nan = invalid(qnan) if x is a signalling nan Note: underflow is explicitly avoided. [I suggest removing this avoidance.] Note: sinhF(x) will overflow approximately when |x| > ln(2*fmaxF). Cosinus hyperbolicus The cosh*F approximation helper function: cosh*F : F ( R cosh*F(x) returns a close approximation to cosh(x) in R, with maximum error max_error_sinhF. Further requirements on the cosh*F approximation helper function: cosh*F(x) = 1 if x ( F and cosh*F(x) ( cosh(x) and |x| ( ((epsilonF) cosh*F(x) = cosh*F(x) if x ( F cosh*F(x) ( sinh*F(x) if x ( F The coshF operation: coshF : F ( F ( {floating_overflow} coshF(x) = trans_resultF(cosh*F(x)) if x ( F = 1 if x = 0 = +( if x = ( = +( if x = +( = qnan if x is a quiet nan = invalid(qnan) if x is a signalling nan Note: coshF(x) overflows approximately when |x| > ln(2*fmaxF). Tangent hyperbolicus The tanh*F approximation helper function: tanh*F : F ( R tanh*F(x) returns a close approximation to tanh(x) in R, with maximum error max_error_tanhF. Further requirements on the tanh*F approximation helper function: tanh*F(x) = x if x ( F and tanh*F(x) ( tanh(x) and |x| ( ((1.5*epsilonF/rF) tanh*F(x) = 1 if x ( F and tanh*F(x) ( tanh(x) and x > arctanh(1(epsilonF/(3*rF))) tanh*F(x) = tanh*F(x) if x ( F The tanhF operation: tanhF : F ( F [ ( {underflow}?] tanhF(x) = trans_resultF(tanh*F(x)) if x ( F and |x| > fminNF = x [don't have as spec. case?] if x ( F and |x| ( fminNF = 0 if x = 0 = 1 if x = ( = 1 if x = +( = qnan if x is a quiet nan = invalid(qnan) if x is a signalling nan Note: underflow is explicitly avoided. [I suggest removing this avoidance.] Cotangent hyperbolicus The coth*F approximation helper function: coth*F : F ( R coth*F(x) returns a close approximation to coth(x) in R, with maximum error max_error_tanhF. Further requirements on the coth*F approximation helper function: coth*F(x) = 1 if x ( F and coth*F(x) ( coth(x) and x > arccoth(1+(epsilonF/4)) coth*F(x) = coth*F(x) if x ( F The cothF operation: cothF : F ( F ( {pole, floating_overflow} cothF(x) = trans_resultF(coth*F(x)) if x ( F and x ( 0 = pole(+() if x = 0 = pole(() if x = 0 = 1 if x = ( = 1 if x = +( = qnan if x is a quiet nan = invalid(qnan) if x is a signalling nan Note: cothF(x) overflow approximately when |1/x| > fmaxF. Secant hyperbolicus The sech*F approximation helper function: sech*F : F ( R sech*F(x) returns a close approximation to sech(x) in R, with maximum error max_error_sechF. Further requirements on the sech*F approximation helper function: sech*F(x) = 1 if x ( F and sech*F(x) ( sech(x) and |x| ( ((epsilonF/rF) sech*F(x) = sech*F(x) if x ( F sech*F(x) ( csch*F(x) if x ( F and x > 0 sech*F(x) < fminDF/2 if x ( F and x > 2ln(fminDF/4) The sechF operation: sechF : F ( F ( {underflow} sechF(x) = trans_resultF(sech*F(x)) if x ( F = 1 if x = 0 = 0 if x = ( = 0 if x = +( = qnan if x is a quiet nan = invalid(qnan) if x is a signalling nan Cosecant hyperbolicus The csch*F approximation helper function: csch*F : F ( R csch*F(x) returns a close approximation to csch(x) in R, with maximum error max_error_sechF. Further requirements on the csch*F approximation helper function: csch*F(x) = csch*F(x) if x ( F csch*F(x) ( sech*F(x) if x ( F and x > 0 csch*F(x) < fminDF/2 if x ( F and x > 2ln(fminDF/4) The cschF operation: cschF : F ( F ( {underflow, floating_overflow, pole} cschF(x) = trans_resultF(csch*F(x)) if x ( F and x ( 0 = pole(+() if x = 0 = pole(() if x = 0 = 0 if x = ( = 0 if x = +( = qnan if x is a quiet nan = invalid(qnan) if x is a signalling nan Note: cschF(x) overflows approximately when |1/x| > fmaxF. Operations for inverse hyperbolics [In sect. 4: The principle values are chosen such that, when the function is defined: arccosh(x) ( [1, ([ arcsech(x) ( ]0, 1] (see [appropriate references]) ] Note: The approximation helper functions for the inverse hyperbolic operations need not be inverses of the approximation helper functions for the hyperbolic operations and the inverse hyperbolic operations cannot be inverses of the hyperbolic operations. There are three maximum error parameters for inverse hyperbolic operations: max_error_arcsinhF ( F max_error_arctanhF ( F max_error_arcsechF ( F The max_error_arcsinhF parameter is required to be in the interval [0.5, 2*rnd_errorF]. The max_error_arctanhF parameter is required to be in the interval [max_error_arcsinhF, 2*rnd_errorF]. The max_error_arcsechF parameter is required to be in the interval [max_error_arcsinhF, 2*rnd_errorF]. Arcus sinus hyperbolicus The arcsinh*F approximation helper function: arcsinh*F : F ( R arcsinh*F(x) returns a close approximation to arcsinh(x) in R, with maximum error max_error_arcsinhF. Further requirements on the arcsinh*F approximation helper function: arcsinh*F(x) = x if x ( F and arcsinh*F(x) ( arcsinh(x) and |x| ( ((3*epsilonF/rF) arcsinh*F(x) = arcsinh*F(x) if x ( F The arcsinhF operation: arcsinhF : F ( F [ ( {underflow} ?] arcsinhF(x) = trans_resultF(arcsinh*F(x)) if x ( F and |x| > fminNF = x [don't have as spec. case?] if x ( F and |x| ( fminNF = 0 if x = 0 = ( if x = ( = +( if x = +( = qnan if x is a quiet nan = invalid(qnan) if x is a signalling nan Note: underflow is explicitly avoided. [I suggest removing this avoidance.] Arcus cosinus hyperbolicus The arccosh*F approximation helper function: arccosh*F : F ( R arccosh*F(x) returns a close approximation to arccosh(x) in R, with maximum error max_error_arcsinhF. The arccoshF operation: arccoshF : F ( F ( {invalid} arccoshF(x) = trans_resultF(arccosh*F(x)) if x ( F and x ( 1 = +( if x = +( = invalid(qnan) if x ( F and x < 1 = invalid(qnan) if x = 0 = invalid(qnan) if x = ( = qnan if x is a quiet nan = invalid(qnan) if x is a signalling nan Arcus tangent hyperbolicus The arctanh*F approximation helper function: arctanh*F : F ( R arctanh*F(x) returns a close approximation to arctanh(x) in R, with maximum error max_error_arctanhF. Further requirements on the arctanh*F approximation helper function: arctanh*F(x) = x if x ( F and arctanh*F(x) ( arctanh(x) and |x| < ((1*epsilonF/rF) [1?] arctanh*F(x) = arctanh*F(x) if x ( F The arctanhF operation: arctanhF : F ( F ( {invalid, pole} [, underflow ?] arctanhF(x) = trans_resultF(arctanh*F(x)) if x ( F and fminNF < |x| < 1 = x [don't have as spec. case!?] if x ( F and |x| ( fminNF = pole(+() if x = 1 = pole(() if x = 1 = 0 if x = 0 = invalid(qnan) if x ( F and |x| > 1 = invalid(qnan) if x = ( or x = +( = qnan if x is a quiet nan = invalid(qnan) if x is a signalling nan Note: underflow is explicitly avoided. [I suggest removing this avoidance.] Arcus cotangent hyperbolicus The arccoth*F approximation helper function: arccoth*F : F ( R arccoth*F(x) returns a close approximation to arccoth(x) in R, with maximum error max_error_arctanhF. Further requirements on the arccoth*F approximation helper function: arccoth*F(x) = arccoth*F(x) if x ( F The arccothF operation: arccothF : F ( F ({invalid, underflow, pole} arccothF(x) = trans_resultF(arccoth*F(x)) if x ( F and |x| > 1 = pole(+() if x = 1 = pole(() if x = 1 = 0 if x = ( = 0 if x = +( = invalid(qnan) if x ( F and 1 < x < 1 = invalid(qnan) if x = 0 = qnan if x is a quiet nan = invalid(qnan) if x is a signalling nan Note: There is no underflow for this operation for most kinds of floating point types, e.g. IEC 559 ones. Arcus secant hyperbolicus The arcsech*F approximation helper function: arcsech*F : F ( R arcsech*F(x) returns a close approximation to arcsech(x) in R, with maximum error max_error_arcsechF. The arcsechF operation: arcsechF : F ( F ( {invalid, pole} arcsechF(x) = trans_resultF(arcsech*F(x)) if x ( F and 0 < x ( 1 = pole(+() if x = 0 = pole(+() if x = 0 = invalid(qnan) if x ( F and (x < 0 or x > 1) = invalid(qnan) if x = ( or x = +( = qnan if x is a quiet nan = invalid(qnan) if x is a signalling nan Arcus cosecant hyperbolicus The arccsch*F approximation helper function: arccsch*F : F ( R arccsch*F(x) returns a close approximation to arccsch(x) in R, with maximum error max_error_arcsechF. Further requirements on the arccsch*F approximation helper function: arccsch*F(1) = arcsinh*F(1) arccsch*F(x) = arccsch*F(x) if x ( F The arccschF operation: arccschF : F ( F ( {underflow, pole} arccschF(x) = trans_resultF(arccsch*F(x)) if x ( F and x ( 0 = pole(+() if x = 0 = pole(() if x = 0 = 0 if x = ( = 0 if x = +( = qnan if x is a quiet nan = invalid(qnan) if x is a signalling nan Note: There is no underflow for this operation for most kinds of floating point types, e.g. IEC 559 ones. Angular normalisations and angular unit conversions All of the unit argument trigonometric and unit argument inverse trigonometric approximation helper functions (including those for normalisation, anglular unit conversion, and arc) are exempted from the monotonicity requirement for the unit (first) argument. The radian trigonometric approximation helper functions (including those for normalisation and conversion to/from radians) need have the same zero points as the approximated mathematical function only if the absolute value of the argument is less than big_anglerF. Likewise, the radian trigonometric approximation helper functions need have the same sign as the approximated mathematical function only if the absolute value of the argument is less than or equal to big_anglerF. Let T = {1, 360, 400, 6400, 21600, 1296000}. T consists of angle values for exactly one revolution for some common nonradian angular units (revoultions, degrees, grades, mils, arc minutes, and arc seconds respectively). The mathematical trigonometric functions are perfectly cyclic. Their numerical counterparts are not that perfect, for two reasons: Firstly, the radian normalisation cannot be exact, even though it can be made very good given very many digits for the approximation(s) of ( used in the normalisation, returning an offset from the nearest axis, and including guard digits. As it happens, the unit argument normalisation can be made exact regardless of the (nonzero and, in case denormF=false, not too small) unit and the original angle, returning only a plain angle in F, and is so required below. Secondly, the lenght of one revolution is of course constant, but the density of floating point values gets sparser the larger the magnitude of the values are. This means that the number of floating point values gets sparser per revolution the larger the magnitude of the angle. For this reason the notification angle_too_big is introduced. This notification is given when the magnitude of the angle value is too big. Exactly when the representable angle values get too sparse may depend upon the application at hand, and it may be possible for the programmer to tighten (but perhaps not widen) the big angle parameters below. Note: angle_too_big notifications as well as underflow notifications should be handled via recording of indicators, unless there is an explicit request to do otherwise. There are two big angle parameters: big_angleuF ( F big_anglerF ( F They are required to have the following default values: big_angleuF = ((rF^(pF/2()/6( [Ada: not mentioned.] big_anglerF = 6*big_angleuF [Ada: something not less than rF^(pF/2(.] Note: The user may be allowed to narrow these values, but should not be allowed to widen them beyond the values given here. There is one derived parameter signifying the minumum allowed angular unit: min_angular_unitF = rF*fminNF/epsilonF = rF^(eminF1+pF) It is there for two reasons. Firstly, if the type F has no denormal values (denormF = false), some angle values in F are not representable after normalisation (this gives the firm limit above). Secondly, even if F has denormal values (denormF = true), very tiny angular units do not allow the representable angles to be particularly dense, not even if the angular value is within the first cycle. By fiat, no negative angular units are allowed. [but there is no technical reason for this last one] To make the requirements a bit easier to express, let GF = {x ( F | x ( min_angular_unitF}. In order to make the operation specifications easier to read, the continuation value upon an angle_too_big notification is as given by the cases in the operation specification given prior to the angle_too_big case. In addition, writing c.v. in front of an operation, e.g. c.v.unitF(u,x), is used to mean the continuation value. If there is no notification, it is the ordinary result, if there is a notification, like underflow or angle_too_big, the notification is ignored and only the continuation value is referred to. There is one maximum error parameter for trigonometric normalisation and conversion operations: max_error_radF (F The max_error_radF parameter is required to be in the interval [0.5, 1.5*rnd_errorF]. Argument angular-unit angle normalisation The unitF operation: unitF : F ( F ( F({0, angle_too_big, invalid} unitF(u,x) = iremrF(x,u) if u ( GF and x ( F({0} = angle_too_big if u ( GF and x ( F and |x/u| > big_angleuF = invalid(qnan) if u ( F and u < min_angular_unitF and x ( F({0} = invalid(qnan) if u ( F and x ( {(,+(} = invalid(qnan) if u ( {(,0,+(} and x ( F({(,0,+(} = qnan if x is a quiet NaN and u is not a signalling NaN = qnan if u is a quiet NaN and x is not a signalling NaN = invalid(qnan) if x is a signalling NaN or u is a signalling NaN The continuation value for angle_too_big shall be as specified in the first case. Note: unitF(u,x) has a result in the interval [downF(u/2),upF(u/2)]. A zero resulting angle is negative if the original angle is negative. Note: unitF is an exact operation. Note: The unitF operation is used also in the specifications of the unit argument trigonometric operations in sections 5.3.7.15.3.7.6. Radian angle normalisation Define the following mathematical functions: nearest_axis : R ( {1,2,3,4} offset_axis : R ( R rad : R ( R nearest_axis(x) = 1 if cos(x) ( 1/((2) = 2 if sin(x) > 1/((2) = 3 if cos(x) ( 1/((2) = 4 if sin(x) < 1/((2) offset_axis(x) = arcsin(sin(x)) if |cos(x)| ( 1/((2) = arcsin(cos(x)) if |cos(x)| < 1/((2) rad(x) = arccos(cos(x)) if sin(x) ( 0 = arccos(cos(x)) if sin(x) < 0 The rad_nearest_axis*F, rad_offset_axis*F , and rad*F approximation helper functions: rad_nearest_axis*F : R ( {1,2,3,4} rad_offset_axis*F : R ( R rad*F : R ( R rad_nearest_axis*F(x) returns a close approximation to nearest_axis(x) in Z, if x ( big_anglerF. Borderline cases may return the indication for the other axis. rad_offset_axis*F(x) returns a close approximation to offset_axis(x) in R if x ( big_anglerF, with maximum error max_error_radF. Borderline cases may return the offset from the other axis, but it is the offset from the axis indicated by rad_nearest_axis*F(x). The maximum error is relative the offset from the so indicated axis, even if that axis is not really the nearest axis. rad*F(x) returns a close approximation to rad(x) in R if |x| ( big_anglerF, with maximum error max_error_radF. Further requirements on the rad_offset_axis*F , and rad*F approximation helper functions: rad_offset_axis*F(x) = rad*F(x) if rad_nearest_axis*F(x) = 1 rad*F(x) = x if |x| < ( The rad_nearest_axisF, rad_offset_axisF, and radF operations: rad_nearest_axisF : F ( F({angle_too_big} rad_nearest_axisF(x) = rad_nearest_axis*F(x) if x ( F = 1 if x = 0 = angle_too_big if x ( F and |x| > big_anglerF = invalid(qnan) if x ( {(,+(} = qnan if x is a quiet NaN = invalid(qnan) if x is a signalling NaN rad_offset_axisF: F ( F({underflow, angle_too_big} rad_offset_axisF(x) = trans_resultF(rad_offset_axis*F(x)) if x ( F and |x| > fminNF = x if x ( F and |x| ( fminNF = 0 if x = 0 = angle_too_big if x ( F and |x| > big_anglerF = invalid(qnan) if x ( {(,+(} = qnan if x is a quiet NaN = invalid(qnan) if x is a signalling NaN radF: F ( F({underflow, angle_too_big} radF(x) = trans_resultF(rad*F(x)) if x ( F and |x| > fminNF = x if x ( F and |x| ( fminNF = 0 if x = 0 = angle_too_big if x ( F and |x| > big_anglerF = invalid(qnan) if x ( {(,+(} = qnan if x is a quiet NaN = invalid(qnan) if x is a signalling NaN Converting radian angle to argument angular-unit angle Define the mathematical function: rad_to_unit : R ( R ( R rad_to_unit(x,v) = arccos(cos(x))*v/(2*() if sin(x) ( 0 = arccos(cos(x))*v/(2*() if sin(x) < 0 The rad_to_unit*F approximation helper function: rad_to_unit*F : R ( F ( R rad_to_unit*F(x,v) returns a close approximation to rad_to_unit(x,v) in R, with maximum error max_error_radF, if |x| ( big_anglerF. Further requirements on the rad_to_unit*F approximation helper function: rad_to_unit*F(n*2*(+(/6, v) = v/12 if n ( Z and |n*2*(+(/6| ( big_anglerF rad_to_unit*F(n*2*(+(/4, v) = v/8 if n ( Z and |n*2*(+(/4| ( big_anglerF rad_to_unit*F(n*2*(+(/3, v) = v/6 if n ( Z and |n*2*(+(/3| ( big_anglerF rad_to_unit*F(n*2*(+(/2, v) = v/4 if n ( Z and |n*2*(+(/2| ( big_anglerF rad_to_unit*F(n*2*(+2*(/3, v) = v/3 if n ( Z and |n*2*(+2*(/3| ( big_anglerF rad_to_unit*F(n*2*(+3*(/4, v) = 3*v/8 if n ( Z and |n*2*(+3*(/4| ( big_anglerF rad_to_unit*F(n*2*(+5*(/6, v) = 5*v/12 if n ( Z and |n*2*(+5*(/6| ( big_anglerF rad_to_unit*F(n*2*(+(, v) = v/2 if n ( Z and |n*2*(+(| ( big_anglerF rad_to_unit*F(x, v) = rad_to_unit*F(x, v) if rad_to_unit(x, v) ( v/2 The rad_to_unitF operation: rad_to_unitF : F ( F ( F({underflow, angle_too_big, invalid} rad_to_unitF(x,v) = trans_resultF(rad_to_unit*F(x,v)) if v ( GF and x ( F = 0 if v ( GF and x = 0 = angle_too_big if v ( GF and x ( F and |x| > big_anglerF = invalid(qnan) if v ( GF and x ( {(,+(} = invalid(qnan) if v ( F and v < min_angular_unitF and x ( F ( {(,0,+(} = invalid(qnan) if v ( {(,0,+(} and x ( F ( {(,0,+(} = qnan if x is a quiet NaN and v is not a signalling NaN = qnan if v is a quiet NaN and x is not a signalling NaN = invalid(qnan) if x is a signalling NaN or v is a signalling NaN Note: Both the notifications underflow and angle_too_big can occur simultaneously for some arguments to radF and also for rad_to_unitF. Converting argument angular-unit angle to radian angle Define the mathematical function: unit_to_rad : R ( R ( R unit_to_rad(u,x) = arccos(cos(x*2*(/u)) if sin(x*2*(/u) ( 0 = arccos(cos(x*2*(/u)) if sin(x*2*(/u) < 0 The unit_to_rad*F approximation helper function: unit_to_rad*F : F ( R ( R unit_to_rad*F(u,x) returns a close approximation to unit_to_rad(u,x) in R, if u ( 0, with maximum error max_error_radF. Further requirements on the unit_to_rad*F approximation helper function: unit_to_rad*F(u,n*u+x) = unit_to_rad*F(u,x) if n ( Z unit_to_rad*F(u,u/12) = (/6 unit_to_rad*F(u,u/8) = (/4 unit_to_rad*F(u,u/6) = (/3 unit_to_rad*F(u,u/4) = (/2 unit_to_rad*F(u,u/3) = 2*(/3 unit_to_rad*F(u,3*u/8) = 3*(/4 unit_to_rad*F(u,5*u/12) = 5*(/6 unit_to_rad*F(u,u/2) = ( unit_to_rad*F(u, x) = unit_to_rad*F(u, x) if unit_to_rad(u, x) ( ( The unit_to_radF operation: unit_to_radF: F ( F ( F({0, underflow, angle_too_big, invalid} unit_to_radF(u,x) = trans_resultF(unit_to_rad*F(u,x)) if c.v.unitF(u,x) ( F = 0 if c.v.unitF(u,x) = 0 = angle_too_big if unitF(u,x) = angle_too_big = invalid(qnan) if unitF(u,x) = invalid = qnan if unitF(u,x) is a quiet NaN Converting argument angular-unit angle to (another) argument angular-unit angle Define the mathematical function: unit_to_unit : R ( R ( R ( R unit_to_unit(u,x,v) = arccos(cos(x*2*(/u))*v/(2*() if sin(x*2*(/u) ( 0 = arccos(cos(x*2*(/u))*v/(2*() if sin(x*2*(/u) < 0 The unit_to_unit*F approximation helper function: unit_to_unit*F : F ( R ( F ( R unit_to_unit*F(u,x,v) returns a close approximation to unit_to_unit(u,x,v) in R if u ( 0 and |x/u| ( big_angleuF, with maximum error max_error_radF. Further requirements on the unit_to_unit*F approximation helper function: unit_to_unit*F(u,n*u+x,v) = unit_to_unit*F(u,x,v) if n ( Z unit_to_unit*F(u,u/12,v) = v/12 unit_to_unit*F(u,u/8,v) = v/8 unit_to_unit*F(u,u/6,v) = v/6 unit_to_unit*F(u,u/4,v) = v/4 unit_to_unit*F(u,u/3,v) = v/3 unit_to_unit*F(u,3*u/8,v) = 3*v/8 unit_to_unit*F(u,5*u/12,v) = 5*v/12 unit_to_unit*F(u,u/2,v) = v/2 unit_to_unit*F(u, x,v) = unit_to_unit*F(u, x,v) if unit_to_unit(u, x, v) ( v/2 The unit_to_unitF operation: unit_to_unitF: F ( F ( F ( F({0, underflow, angle_too_big, invalid} unit_to_unitF(u,x,v) = trans_resultF(unit_to_unit*F(u,x,v)) if v ( GF and c.v.unitF(u,x) ( F = 0 if v ( GF and c.v.unitF(u,x) = 0 = angle_too_big if v ( GF and unitF(u,x) = angle_too_big = invalid(qnan) if v ( GF and unitF(u,x) = invalid = invalid(qnan) if v ( F and v < min_angular_unitF and u,x ( F ( {(,0,+(} = invalid(qnan) if v ( {(,0,+(} and u,x ( F ( {(,0,+(} = qnan if unitF(u,x) is a quiet NaN and v is not a signalling NaN = qnan if v is a quiet NaN and unitF(u,x) ( invalid = invalid(qnan) if v is a signalling NaN Degree normalisation and conversions degF : F ( F({0, angle_too_big} degF(x) = unitF(360,x) rad_to_degF : F ( F({underflow, angle_too_big} rad_to_degF(x) = rad_to_unitF(x,360) deg_to_radF : F ( F({0, underflow, angle_too_big} deg_to_radF(x) = unit_to_radF(360,x) unit_to_degF : F ( F ( F({0, underflow, angle_too_big, invalid} unit_to_degF(u,x) = unit_to_unitF(u,x,360) deg_to_unitF : F ( F ( F({0, underflow, angle_too_big, invalid} deg_to_unitF(x,v) = unit_to_unitF(360,x,v) The arcus (angle, phase) and hypotenuse operations Define the mathematical arc function: arc : R ( R ( R arc(x,y) = arccos(x/((x2+y2)) if y (0 = arccos(x/((x2+y2)) if y < 0 [This is the most elegant mathematical definition of this function I can think of. Formulations involving arctan or arccot are much less appealing, there are too many special cases.] [The "arc" operations are sometimes referred to as "arccot2" or "arctan2" (with the coordinate arguments swapped). Since the mathematical definition is in terms arccos, and they compute the angle, or phase, of a vector, names that refer to tangent or cotangent seems inappropriate and limited.] [Note also that a too naive implementation of, e.g., arcrF in terms of arctanrF may leak internal overflows (from the division), which the specification here does not allow.] There are three max error parameters for the arcus and hypotenuse operations: max_error_arcF ( F max_error_arcuF(u) ( F(F ( {invalid} max_error_hypotF ( F The max_error_arcF parameter is required to be in the interval [max_error_arctanF , 2*rnd_errorF]. [2??] For u ( GF, the max_error_arcuF(u) parameter is required to be in the interval [max_error_arcF, 4]. The max_error_arcuF(u) parameter is required to be equal to max_error_arcF if u ( T. The max_error_arcuF(u) parameter returns invalid if u ( F and u < min_angular_unitF or if u ( {(,0,+(} or if u is a NaN. The max_error_hypotF parameter is required to be in the interval [0.5, 1]. Unit argument arcus The arcu*F approximation helper function: arcu*F : F ( F ( F ( R arcu*F(u,x,y) returns a close approximation to arc(x,y)*u/(2*() in R, with maximum error max_error_arcuF(u). Further requirements on the arcu*F approximation helper function: arcu*F(u, x, x) = u/8 if x > 0 arcu*F(u, 0, y) = u/4 if y > 0 arcu*F(u, x, x) = 3*u/8 if x < 0 arcu*F(u, x, 0) = u/2 if x < 0 arcu*F(u, x, y) = arcu*F(u, x, y) if y ( 0 or x > 0 The arcuF operation: arcuF : F ( F ( F ( F ( {underflow, invalid} arcuF(u,x,y) = trans_resultF(arcu*F(u,x,y)) if u ( GF and x,y ( F and (x ( 0 or y ( 0) = invalid(0) if u ( GF and x = 0 and y = 0 = arcuF(u,0,y) if u ( GF and x=0 and y ( F({(,0,+(} = negF(arcuF(u,x,0)) if u ( GF and y=0 and x ( F({(,+(} = arcuF(u,1,0) if u ( GF and x = +( and y ( F and y ( 0 = arcuF(u,1,1) if u ( GF and x = +( and y = +( = arcuF(u,0,1) if u ( GF and x ( F and y = +( = arcuF(u,1,1) if u ( GF and x = ( and y = +( = arcuF(u,1,0) if u ( GF and x = ( and y ( F and y ( 0 = arcuF(u,1,0) if u ( GF and x = ( and y ( F and y < 0 = arcuF(u,1,1) if u ( GF and x = ( and y = ( = arcuF(u,0,1) if u ( GF and x ( F and y = ( = arcuF(u,1,1) if u ( GF and x = +( and y = ( = arcuF(u,1,0) if u ( GF and x = +( and y ( F and y < 0 = invalid(qnan) if u ( F and u < min_angular_unitF and x ( F({(,0,+(} = invalid(qnan) if u ( {(,0,+(} and x,y ( F ( {(,0,+(} = qnan if u is a quiet NaN and not x nor y is a signalling NaN = qnan if x is a quiet NaN and not u nor y is a signalling NaN = qnan if y is a quiet NaN and not u nor x is a signalling NaN = invalid(qnan) if u is a signalling NaN or x is a signalling NaN or y is a signalling NaN Degree arcus [should be left to bindings, need not be explicit in LIA2]: arc360F : F ( F ( F ( {underflow, invalid} arc360F(x,y) = arcuF(360,x,y) Radian arcus The arc*F approximation helper function: arc*F : F ( F ( R arc*F(x,y) returns a close approximation to arc(x,y) in R, with maximum error max_error_arcF. Further requirements on the arc*F approximation helper function: arc*F(x, 0) = 0 if x > 0 arc*F(x, x) = (/4 if x > 0 arc*F(0, y) = (/2 if y > 0 arc*F(x, x) = 3*(/4 if x < 0 arc*F(x, 0) = ( if x < 0 arc*F(x, y) = arc*F(x, y) if y ( 0 or x > 0 The arcrF operation: arcrF : F ( F ( F ( {underflow, invalid} arcrF(x,y) = trans_resultF(arc*F(x,y)) if x,y ( F and (x ( 0 or y ( 0) = invalid(0) if x = 0 and y = 0 = arcrF(0,y) if x = 0 and y ( F ( {(,0,+(} = negF(arcrF(x,0)) if y = 0 and x ( F ( {(,+(} = arcrF(1,0) if x = +( and y ( F and y ( 0 = arcrF(1,1) if x = +( and y = +( = arcrF(0,1) if x ( F and y = +( = arcrF(1,1) if x = ( and y = +( = arcrF(1,0) if x = ( and y ( F and y ( 0 = arcrF(1,0) if x = ( and y ( F and y < 0 = arcrF(1,1) if x = ( and y = ( = arcrF(0,1) if x ( F and y = ( = arcrF(1,1) if x = +( and y = ( = arcrF(1,0) if x = +( and y ( F and y < 0 = qnan if x is a quiet NaN and y is not a signalling NaN = qnan if y is a quiet NaN and x is not a signalling NaN = invalid(qnan) if x is a signalling NaN or y is a signalling NaN Hypotenuse The hypot*F approximation helper function: hypot*F : F ( F( R hypot*F(x,y) returns a close approximation to ((x2+y2) in R, with maximum error max_error_hypotF. Further requirements on the hypot*F approximation helper function: hypot*F(x,y) = hypot*F(y,x) hypot*F(x,y) = hypot*F(x,y) hypot*F(x,y) ( max{|x|,|y|} hypot*F(x,y) ( |x| + |y| hypot*F(x,y) ( 1 if ((x2+y2) ( 1 hypot*F(x,y) ( 1 if ((x2+y2) ( 1 The hypotF operation: hypotF : F ( F ( F({underflow, floating_overflow} hypotF(x,y) = trans_resultF(hypot*F(x,y)) if x,y ( F = hypotF(0,y) if x = 0 and y ( F ( {(,0,+(} = hypotF(x,0) if y = 0 and x ( F ( {(,+(} = +( if x ( {(,+(} and y ( F ( {(,+(} = +( if y ( {(,+(} and x ( F = qnan if x is a quiet NaN and y is not a signalling NaN = qnan if y is a quiet NaN and x is not a signalling NaN = invalid(qnan) if x is a signalling NaN or y is a signalling NaN Operations for trigonometrics There are six maximum error parameters for trigonometric operations, three of which are in turn parametrised: max_error_sinF (F max_error_tanF ( F max_error_secF ( F max_error_sinuF : F ( F ( {invalid} max_error_tanuF : F ( F ( {invalid} max_error_secuF : F ( F ( {invalid} The max_error_sinF parameter is required to be in the interval [0.5, 1.5*rnd_errorF]. The max_error_tanF parameter is required to be in the interval [max_error_sinF , 2*rnd_errorF]. The max_error_secF parameter is required to be in the interval [max_error_sinF , 2*rnd_errorF]. For u ( GF, the max_error_sinuF(u) parameter is required to be in the interval [max_error_sinF, 2]. For u ( GF, the max_error_tanuF(u) parameter is required to be in the interval [max_error_tanF, 4]. For u ( GF, the max_error_secuF(u) parameter is required to be in the interval [max_error_secF, 4]. The max_error_sinuF(u) parameter is required to be equal to max_error_sinF if u ( T. The max_error_tanuF(u) parameter is required to be equal to max_error_tanF if u ( T. The max_error_secuF(u) parameter is required to be equal to max_error_secF if u ( T. The max_error_sinuF(u), max_error_tanuF(u), and max_error_secuF(u) parameters return invalid if u ( F and u < min_angular_unitF. or if u ( {(,0,+(} or if u is a NaN. Unit argument sinus The sinu*F approximation helper function: sinu*F : F ( R ( R sinu*F(u,x) returns a close approximation to sin(x*2*(/u) in R if u ( 0, with maximum error max_error_sinuF(u). Further requirements on the sinu*F approximation helper function: sinu*F(u, n*u+x) = sinu*F(u, x) if n ( Z and u ( F and u ( 0 sinu*F(u, u/12) = 1/2 if u ( F and u ( 0 sinu*F(u, u/4) = 1 if u ( F and u ( 0 sinu*F(u, 5*u/12) = 1/2 if u ( F and u ( 0 sinu*F(u, x) = sinu*F(u, x) if u ( F and u ( 0 Note: sinu*F(u, x) ( x*2*(/u if |x*2*(/u| < fminNF The sinuF operation: sinuF : F ( F ( F ( {0, underflow, invalid, angle_too_big} sinuF(u,x) = trans_resultF(sinu*F(u, x)) if c.v.unitF(u,x) ( F = 0 if c.v.unitF(u,x) = 0 = angle_too_big if unitF(u,x) = angle_too_big = invalid(qnan) if unitF(u,x) = invalid = qnan if unitF(u,x) is a quiet NaN Unit argument cosinus The cosu*F approximation helper function: cosu*F : F ( R ( R cosu*F(u,x) returns a close approximation to cos(x*2*(/u) in R if u ( 0, with maximum error max_error_sinuF(u). Further requirements on the cosu*F approximation helper function: cosu*F(u, n*u+x) = cosu*F(u, x) if n ( Z and u ( F and u ( 0 cosu*F(u, 0) = 1 if u ( F and u ( 0 cosu*F(u, u/6) = 1/2 if u ( F and u ( 0 cosu*F(u, u/3) = 1/2 if u ( F and u ( 0 cosu*F(u, u/2) = 1 if u ( F and u ( 0 cosu*F(u, x) = cosu*F(u, x) if u ( F and u ( 0 Note: cosu*F(u, x) = 1 should hold if |x*2*(/u| < ((epsilonF/rF) [make normative?] The cosuF operation: cosuF : F ( F ( F ( {underflow, invalid, angle_too_big} cosuF(u,x) = trans_resultF(cosu*F(u, x)) if c.v.unitF(u,x) ( F = 1 if c.v.unitF(u,x) = 0 = angle_too_big if unitF(u,x) = angle_too_big = invalid(qnan) if unitF(u,x) = invalid = qnan if unitF(u,x) is a quiet NaN Unit argument tangent The tanu*F approximation helper function: tanu*F : F ( R ( R tanu*F(u,x) returns a close approximation to tan(x*2*(/u) in R if u ( 0, with maximum error max_error_tanuF(u). Further requirements on the tanu*F approximation helper function: tanu*F(u, n*u+x) = tanu*F(u, x) if n ( Z and u ( F and u ( 0 tanu*F(u, u/8) = 1 if u ( F and u ( 0 tanu*F(u, 3*u/8) = 1 if u ( F and u ( 0 tanu*F(u, x) = tanu*F(u, x) if u ( F and u ( 0 Note: tanu*F(u, x) ( x*2*(/u if |x*2*(/u| < fminNF The tanuF operation: tanuF : F(F (F({0,pole,floating_overflow,underflow,invalid,angle_too_big} tanuF(u,x) = trans_resultF(tanu*F(u, x)) if c.v.unitF(u,x) ( F and c.v.unitF(u,x) ( {u/4,u/4} = 0 if c.v.unitF(u,x) = 0 = pole(+() if c.v.unitF(u,x) = u/4 = pole(() if c.v.unitF(u,x) = u/4 = angle_too_big if unitF(u,x) = angle_too_big = invalid(qnan) if unitF(u,x) = invalid = qnan if unitF(u,x) is a quiet NaN Note: The pole notification can arise for tanuF(u,x) only when u/4 is in F. Unit argument cotangent The cotu*F approximation helper function: cotu*F : F ( R ( R cotu*F(u,x) returns a close approximation to cot(x*2*(/u) in R if u ( 0, with maximum error max_error_tanuF(u). Further requirements on the cotu*F approximation helper function: cotu*F(u, n*u+x) = cotu*F(u, x) if n ( Z and u ( F and u ( 0 cotu*F(u, u/8) = 1 if u ( F and u ( 0 cotu*F(u, 3*u/8) = 1 if u ( F and u ( 0 cotu*F(u, x) = cotu*F(u, x) if u ( F and u ( 0 The cotuF operation: cotuF : F(F ( F({pole, floating_overflow, underflow, invalid, angle_too_big} cotuF(u,x) = trans_resultF(cotu*F(u, x)) if c.v.unitF(u,x) ( F and c.v.unitF(u,x) ( {u/2,0,u/2} = pole(+() if c.v.unitF(u,x) = 0 = pole(() if c.v.unitF(u,x) = 0 = pole(+() if c.v.unitF(u,x) = u/2 = pole(() if c.v.unitF(u,x) = u/2 = angle_too_big if unitF(u,x) = angle_too_big = invalid(qnan) if unitF(u,x) = invalid = qnan if unitF(u,x) is a quiet NaN Unit argument secant The secu*F approximation helper function: secu*F : F ( R ( R secu*F(u,x) returns a close approximation to sec(x*2*(/u) in R if u ( 0, with maximum error max_error_secuF(u). Further requirements on the secu*F approximation helper function: secu*F(u, n*u+x) = secu*F(u, x) if n ( Z and u ( F and u ( 0 secu*F(u, 0) = 1 if u ( F and u ( 0 secu*F(u, u/6) = 2 if u ( F and u ( 0 secu*F(u, u/3) = 2 if u ( F and u ( 0 secu*F(u, u/2) = 1 if u ( F and u ( 0 secu*F(u, x) = secu*F(u, x) if u ( F and u ( 0 Note: secu*F(u, x) = 1 should hold if |x*2*(/u| < ((epsilonF) [make normative?] The secuF operation: secuF : F ( F ( F ( {pole, floating_overflow, invalid, angle_too_big} secuF(u,x) = trans_resultF(secu*F(u, x)) if c.v.unitF(u,x) ( F and c.v.unitF(u,x) ( {u/4,u/4} = 1 if c.v.unitF(u,x) = 0 = pole(+() if c.v.unitF(u,x) = u/4 = pole(+() if c.v.unitF(u,x) = u/4 = angle_too_big if unitF(u,x) = angle_too_big = invalid(qnan) if unitF(u,x) = invalid = qnan if unitF(u,x) is a quiet NaN Unit argument cosecant The cscu*F approximation helper function: cscu*F : F ( R ( R cscu*F(u,x) returns a close approximation to csc(x*2*(/u) in R if u ( 0, with maximum error max_error_secuF(u). Further requirements on the cscu*F approximation helper function: cscu*F(u, n*u+x) = cscu*F(u, x) if n ( Z and u ( F and u ( 0 cscu*F(u, u/12) = 2 if u ( F and u ( 0 cscu*F(u, u/4) = 1 if u ( F and u ( 0 cscu*F(u, 5*u/12) = 2 if u ( F and u ( 0 cscu*F(u, x) = cscu*F(u, x) if u ( F and u ( 0 The cscuF operation: cscuF : F ( F ( F ( {pole, floating_overflow, invalid, angle_too_big} cscuF(u,x) = trans_resultF(cscu*F(u, x)) if c.v.unitF(u,x) ( F and c.v.unitF(u,x) ( {u/2,0,u/2} = pole(+() if c.v.unitF(u,x) = 0 = pole(() if c.v.unitF(u,x) = 0 = pole(+() if c.v.unitF(u,x) = u/2 = pole(() if c.v.unitF(u,x) = u/2 = angle_too_big if unitF(u,x) = angle_too_big = invalid(qnan) if unitF(u,x) = invalid = qnan if unitF(u,x) is a quiet NaN Degree operations [I don't see why these need to be singled out in LIA2 at all. Leave it to the bindings.] sin360F : F ( F ( {0, underflow, angle_too_big} sin360F(x) = sinuF(360,x) cos360F : F ( F ( {underflow, angle_too_big} cos360F(x) = cosuF(360,x) tan360F : F ( F ( {0, pole, floating_overflow, underflow, angle_too_big} tan360F(x) = tanuF(360,x) cot360F : F ( F ( {pole, floating_overflow, underflow, angle_too_big} cot360F(x) = cotuF(360,x) sec360F : F ( F ( {pole, floating_overflow, angle_too_big} sec360F(x) = secuF(360,x) csc360F : F ( F ( {pole, floating_overflow, angle_too_big} csc360F(x) = cscuF(360,x) Radian sinus The sin*F approximation helper function: sin*F : R ( R sin*F(x) returns a close approximation to sin(x) in R if |x| ( big_anglerF, with maximum error max_error_sinF. Further requirements on the sin*F approximation helper function: sin*F(n*2*(+(/6) = 1/2 if n ( Z and |n*2*(+(/6| ( big_anglerF sin*F(n*2*(+(/4) = 1 if n ( Z and |n*2*(+(/4| ( big_anglerF sin*F(n*2*(+5*(/6) = 1/2 if n ( Z and |n*2*(+5*(/6| ( big_anglerF sin*F(x) = x if sin*F(x) ( sin(x) and |x| ( ((3*epsilonF/rF) sin*F(x) = sin*F(x) The sinrF operation: sinrF : F ( F ( {underflow, angle_too_big} sinrF(x) = trans_resultF(sin*F(x)) if x ( F and fminNF < |x| = x if x ( F and |x| ( fminNF = 0 if x = 0 = angle_too_big if |x| > big_anglerF = invalid(qnan) if x ( {(, +(} = qnan if x is a quiet NaN = invalid(qnan) if x is a signalling NaN Note: underflow is here explicitly avoided for denormal arguments, but the operation may underflow for other arguments. [I suggest removing this avoidance.] Radian cosinus The cos*F approximation helper function: cos*F : R ( R cos*F(x) returns a close approximation to cos(x) in R if |x| ( big_anglerF, with maximum error max_error_sinF. Further requirements on the cos*F approximation helper function: cos*F(n*2*() = 1 if n ( Z and |n*2*(| ( big_anglerF cos*F(n*2*(+(/3) = 1/2 if n ( Z and |n*2*(+(/3| ( big_anglerF cos*F(n*2*(+2*(/3) = 1/2 if n ( Z and |n*2*(+2*(/3| ( big_anglerF cos*F(n*2*(+() = 1 if n ( Z and |n*2*(+(| ( big_anglerF cos*F(x) = 1 if cos*F(x) ( cos(x) and |x| ( ((epsilonF/rF) cos*F(x) = cos*F(x) The cosrF operation: cosrF : F ( F ( {underflow, angle_too_big} cosrF(x) = trans_resultF(cos*F(x)) if x ( F = 1 if x = 0 = angle_too_big if |x| > big_anglerF = invalid(qnan) if x ( {(, +(} = qnan if x is a quiet NaN = invalid(qnan) if x is a signalling NaN Radian tangent The tan*F approximation helper function: tan*F : R ( R tan*F(x) returns a close approximation to tan(x) in R if |x| ( big_anglerF, with maximum error max_error_tanF. Further requirements on the tan*F approximation helper function: tan*F(n*2*(+(/4) = 1 if n ( Z and |n*2*(+(/4| ( big_anglerF tan*F(n*2*(+3*(/4) = 1 if n ( Z and |n*2*(+3*(/4| ( big_anglerF tan*F(x) = x if tan*F(x) ( tan(x) and |x| < ((epsilonF/rF) [1?] tan*F(x) = tan*F(x) The tanrF operation: tanrF : F ( F ( {underflow, floating_overflow, angle_too_big} tanrF(x) = trans_resultF(tan*F(x)) if x ( F and fminNF < |x| = x if x ( F and |x| ( fminNF = 0 if x = 0 = angle_too_big if |x| > big_anglerF = invalid(qnan) if x ( {(, +(} = qnan if x is a quiet NaN = invalid(qnan) if x is a signalling NaN Note: underflow is explicitly avoided for denormal arguments, but the operation may underflow for other arguments. [I suggest removing this avoidance.] Radian cotangent The cot*F approximation helper function: cot*F : R ( R cot*F(x) returns a close approximation to cot(x) in R if |x| ( big_anglerF, with maximum error max_error_tanF. Further requirements on the cot*F approximation helper function: cot*F(n*2*(+(/4) = 1 if n ( Z and |n*2*(+(/4| ( big_anglerF cot*F(n*2*(+3*(/4) = 1 if n ( Z and |n*2*(+3*(/4| ( big_anglerF cot*F(x) = cot*F(x) The cotrF operation: cotrF : F ( F ( {underflow, floating_overflow, pole, angle_too_big} cotrF(x) = trans_resultF(cot*F(x)) if x ( F and x ( 0 = pole(+() if x = 0 = pole(() if x = 0 = angle_too_big if |x| > big_anglerF = invalid(qnan) if x ( {(, +(} = qnan if x is a quiet NaN = invalid(qnan) if x is a signalling NaN Radian secant The sec*F approximation helper function: sec*F : R ( R sec*F(x) returns a close approximation to sec(x) in R if |x| ( big_anglerF, with maximum error max_error_secF. Further requirements on the sec*F approximation helper function: sec*F(n*2*() = 1 if n ( Z and |n*2*(| ( big_anglerF sec*F(n*2*(+(/3) = 2 if n ( Z and |n*2*(+(/3| ( big_anglerF sec*F(n*2*(+2*(/3) = 2 if n ( Z and |n*2*(+2*(/3| ( big_anglerF sec*F(n*2*(+() = 1 if n ( Z and |n*2*(+(| ( big_anglerF sec*F(x) = 1 if sec*F(x) ( sec(x) and |x| ( ((epsilonF) sec*F(x) = sec*F(x) The secrF operation: secrF : F ( F ( {floating_overflow, angle_too_big} secrF (x) = trans_resultF(sec*F(x)) if x ( F = 1 if x = 0 = angle_too_big if |x| > big_anglerF = invalid(qnan) if x ( {(, +(} = qnan if x is a quiet NaN = invalid(qnan) if x is a signalling NaN Radian cosecant The csc*F approximation helper function: csc*F : R ( R csc*F(x) returns a close approximation to csc(x) in R if |x| ( big_anglerF, with maximum error max_error_secF. Further requirements on the csc*F approximation helper function: csc*F(n*2*(+(/6) = 2 if n ( Z and |n*2*(+(/6| ( big_anglerF csc*F(n*2*(+(/2) = 1 if n ( Z and |n*2*(+(/2| ( big_anglerF csc*F(n*2*(+5*(/6) = 2 if n ( Z and |n*2*(+5*(/6| ( big_anglerF csc*F(x) = csc*F(x) The cscrF operation: cscrF : F ( F ( {floating_overflow, pole, angle_too_big} cscrF (x) = trans_resultF(csc*F(x)) if x ( F and x ( 0 = pole(+() if x = 0 = pole(() if x = 0 = angle_too_big if |x| > big_anglerF = invalid(qnan) if x ( {(, +(} = qnan if x is a quiet NaN = invalid(qnan) if x is a signalling NaN Operations for inverse trigonometrics [In sect. 4: The principle values are chosen such that, when the function is defined: arcsin(x) ( [(/2, (/2] arccos(x) ( [0, (] arctan(x) ( [(/2, (/2] arccot(x) ( [0, (] arcctg(x) ( [(/2, (/2] arcsec(x) ( [0, (] arccsc(x) ( [(/2, (/2] (see [appropriate references])] There are six maximum error parameters for inverse trigonometric operations, three of which are in turn parametrised: max_error_arcsinF ( F max_error_arctanF ( F max_error_arcsecF ( F max_error_arcsinuF : F ( F ( {invalid} max_error_arctanuF : F ( F ( {invalid} max_error_arcsecuF : F ( F ( {invalid} The max_error_arcsinF parameter is required to be in the interval [0.5, 2*rnd_errorF]. The max_error_arctanF parameter is required to be in the interval [max_error_arcsinF , 2*rnd_errorF]. The max_error_arcsecF parameter is required to be in the interval [max_error_arcsinF , 2*rnd_errorF]. For u ( GF, the max_error_arcsinuF(u) parameter is required to be in the interval [max_error_arcsinF, 4]. For u ( GF, the max_error_arctanuF(u) parameter is required to be in the interval [max_error_arctanF, 4]. For u ( GF, the max_error_arcsecuF(u) parameter is required to be in the interval [max_error_arcsecF, 4]. The max_error_arcsinuF(u) parameter is required to be equal to max_error_arcsinF if u ( T. The max_error_arctanuF(u) parameter is required to be equal to max_error_arctanF if u ( T. The max_error_arcsecuF(u) parameter is required to be equal to max_error_arcsecF if u ( T. The max_error_arcsinuF(u), max_error_arctanuF(u), and max_error_arcsecuF(u) parameters return invalid if u ( F and u < min_angular_unitF or if u ( {(,0,+(} or if u is a NaN. [nearestF(u/4), e.g., may be greater than u/4. So arcsinuF(u, 1), e.g., may be slightly greater than u/4. This is an intentional difference from the current LIA2 draft, but in accordance with Ada (which uses some handwaving here, not taking "(" seriously; LIA takes "(" etc. seriously, and so it must be done without handwaving here). Even when the final result is not exact, these requirements are still higher accuracy requirements and should not be removed (made conditional upon membership in F) even then.] Unit argument arcus sinus The arcsinu*F approximation helper function: arcsinu*F : F ( F ( R arcsinu*F(u, x) returns a close approximation to arcsin(x)*u/(2*() in R, with maximum error max_error_arcsinuF(u). Further requirements on the arcsinu*F approximation helper function: arcsinu*F(u, 1/2) = u/12 arcsinu*F(u, 1) = u/4 arcsinu*F(u, x) = arcsinu*F(u, x) Note: arcsinu*F(u, x) ( u/(2*() if |x| < fminNF The arcsinuF operation: arcsinuF : F ( F ( F ( {underflow, invalid} arcsinuF(u,x) = trans_resultF(arcsinu*F(u, x)) if u ( GF and x ( F and |x| ( 1 = 0 if u ( GF and x = 0 = invalid(qnan) if u ( GF and x ( F and |x| > 1 = invalid(qnan) if u ( GF and x ( {(,+(} = invalid(qnan) if u ( F and u < min_angular_unitF and x ( F ( {(,0,+(} = invalid(qnan) if u ( {(,0,+(} and x ( F ( {(,0,+(} = qnan if x is a quiet nan and u is not a signalling nan = qnan if u is a quiet nan and x is not a signalling nan = invalid(qnan) if x is a signalling nan or u is a signalling nan Unit argument arcus cosinus The arccosu*F approximation helper function: arccosu*F : F ( F ( R arccosu*F(u, x) returns a close approximation to arccos(x)*u/(2*() in R, with maximum error max_error_arcsinuF(u). Further requirements on the arccosu*F approximation helper function: arccosu*F(u, 1/2) = u/6 arccosu*F(u, 0) = u/4 arccosu*F(u, 1/2) = u/3 arccosu*F(u, 1) = u/2 The arccosuF operation: arccosuF : F ( F ( F ( {underflow, invalid} arccosuF(u,x) = trans_resultF(arccosu*F(u, x)) if u ( GF and x ( F and |x| ( 1 = trans_resultF(u/4) if u ( GF and x = 0 [arccosuF(u,0)] = invalid(qnan) if u ( GF and x ( F and |x| > 1 = invalid(qnan) if u ( GF and x ( {(,+(} = invalid(qnan) if u ( F and u < min_angular_unitF and x ( F ( {(,0,+(} = invalid(qnan) if u ( {(,0,+(} and x ( F ( {(,0,+(} = qnan if x is a quiet nan and u is not a signalling nan = qnan if u is a quiet nan and x is not a signalling nan = invalid(qnan) if x is a signalling nan or u is a signalling nan Unit argument arcus tangent The arctanu*F approximation helper function: arctanu*F : F ( F ( R arctanu*F(u, x) returns a close approximation to arctan(x)*u/(2*() in R, with maximum error max_error_arctanuF(u). Further requirements on the arctanu*F approximation helper function: arctanu*F(u, 1) = u/8 arctanu*F(u, x) = u/4 if arctanu*F(u,x)(arctan(x)*u/(2*() and x > ... [?] arctanu*F(u, x) = arctanu*F(u, x) Note: arctanu*F(u, x) ( u/(2*() if |x| < fminNF The arctanuF operation: arctanuF : F ( F ( F ( {invalid, underflow} arctanuF(u,x) = trans_resultF(arctanu*F(u, x)) if u ( GF and x ( F = 0 if u ( GF and x = 0 = trans_resultF(u/4) if u ( GF and x = ( = trans_resultF(u/4) if u ( GF and x = +( = invalid(qnan) if u ( F and u < min_angular_unitF and x ( F ( {(,0,+(} = invalid(qnan) if u ( {(,0,+(} and x ( F ( {(,0,+(} = qnan if x is a quiet nan and u is not a signalling nan = qnan if u is a quiet nan and x is not a signalling nan = invalid(qnan) if x is a signalling nan or u is a signalling nan Note: arctanuF(u,x) ( arcuF(u,1,x) Unit argument arcus cotangent The arccotu*F and arcctgu*F approximation helper functions: arccotu*F : F ( F ( R arcctgu*F : F ( F ( R arccotu*F(u, x) returns a close approximation to arccot(x)*u/(2*() in R, with maximum error max_error_arctanuF(u). arcctgu*F(u, x) returns a close approximation to arcctg(x)*u/(2*() in R, with maximum error max_error_arctanuF(u). [There are two reasonable ways of selecting the principle value for the inverse of the cot oper. I think it is best to leave it to the user/programmer to decide which one is the most appropriate in a particular application. I suggest that LIA2 specifies both of them. Selecting just one is probably premature at the LIA level.] Further requirements on the arccotu*F and arccotu*F approximation helper functions: arccotu*F(u, 1) = u/8 arccotu*F(u, 0) = u/4 arccotu*F(u, 1) = 3*u/8 arccotu*F(u,x) ( u/2 arccotu*F(u,x) = u/2 if arccotu*F(u,x) ( arccot(x)*u/(2*() and x < ... [??] arcctgu*F(u, x) = arccotu*F(u, x) if x ( 0 arcctgu*F(u, x) = arcctgu*F(u, x) The arccotuF operation: arccotuF : F ( F ( F ( {invalid, underflow} arccotuF(u,x) = trans_resultF(arccotu*F(u, x)) if u ( GF and x ( F = trans_resultF(u/4) if u ( GF and x = 0 [arccotuF(u,0)] = trans_resultF(u/2) if u ( GF and x = ( = 0 if u ( GF and x = +( = invalid(qnan) if u ( F and u < min_angular_unitF and x ( F ( {(,0,+(} = invalid(qnan) if u ( {(,0,+(} and x ( F ( {(,0,+(} = qnan if x is a quiet nan and u is not a signalling nan = qnan if u is a quiet nan and x is not a signalling nan = invalid(qnan) if x is a signalling nan or u is a signalling nan Note: arccotuF(u,x) ( arcuF(u,x,1) The arcctguF operation: arcctguF : F ( F ( F ( {invalid, underflow} arcctguF(u,x) = trans_resultF(arcctgu*F(u, x)) if u ( GF and x ( F = trans_resultF(u/4) if u ( GF and x = 0 [arcctguF(u,0)] = 0 if u ( GF and x = ( = 0 if u ( GF and x = +( = invalid(qnan) if u ( F and u < min_angular_unitF and x ( F ( {(,0,+(} = invalid(qnan) if u ( {(,0,+(} and x ( F ( {(,0,+(} = qnan if x is a quiet nan and u is not a signalling nan = qnan if u is a quiet nan and x is not a signalling nan = invalid(qnan) if x is a signalling nan or u is a signalling nan Unit argument arcus secant The arcsecu*F approximation helper function: arcsecu*F : F ( F ( R arcsecu*F(u, x) returns a close approximation to arcsec(x)*u/(2*() in R, with maximum error max_error_arcsecuF(u). Further requirements on the arcsecu*F approximation helper function: arcsecu*F(u, 2) = u/6 arcsecu*F(u, 2) = u/3 arcsecu*F(u, 1) = u/2 arcsecu*F(u, x) ( u/4 if x > 0 arcsecu*F(u, x) ( u/4 if x < 0 arcsecu*F(u, x) = u/4 if arcsecu*F(u,x) ( arcsec(x)*u/(2*() and (x < ... or x > [...?]) The arcsecuF operation: arcsecuF : F ( F ( F ( {underflow, invalid} arcsecuF(u,x) = trans_resultF(arcsecu*F(u, x)) if u ( GF and x ( F and (x ( 1 or x ( 1) = invalid(qnan) if u ( GF and x ( F and 1 < x < 1 = invalid(qnan) if u ( GF and x = 0 = trans_resultF(u/4) if u ( GF and x = ( = trans_resultF(u/4) if u ( GF and x = +( = invalid(qnan) if u ( F and u < min_angular_unitF and x ( F ( {(,0,+(} = invalid(qnan) if u ( {(,0,+(} and x ( F ( {(,0,+(} = qnan if x is a quiet nan and u is not a signalling nan = qnan if u is a quiet nan and x is not a signalling nan = invalid(qnan) if x is a signalling nan or u is a signalling nan Unit argument arcus cosecant The arccscu*F approximation helper function: arccscu*F : F ( F ( R arccscu*F(u, x) returns a close approximation to arccsc(x)*u/(2*() in R, with maximum error max_error_arccscuF(u). Further requirements on the arccscu*F approximation helper function: arccscu*F(u, 2) = u/12 arccscu*F(u, 1) = u/4 arccscu*F(u, x) = arccscu*F(u, x) The arccscuF operation: arccscuF : F ( F ( F ( {underflow, invalid} arccscuF(u,x) = trans_resultF(arccscu*F(u, x)) if u ( GF and x ( F and (x ( 1 or x ( 1) = invalid(qnan) if u ( GF and x ( F and 1 < x < 1 = invalid(qnan) if u ( GF and x = 0 = 0 if u ( GF and x = ( = 0 if u ( GF and x = +( = invalid(qnan) if u ( F and u < min_angular_unitF and x ( F ( {(,0,+(} = invalid(qnan) if u ( {(,0,+(} and x ( F ( {(,0,+(} = qnan if x is a quiet nan and u is not a signalling nan = qnan if u is a quiet nan and x is not a signalling nan = invalid(qnan) if x is a signalling nan or u is a signalling nan Degree operations [Should be left to bindings, need not be explicit in LIA2] arcsin360F : F ( F ( {underflow, invalid} arcsin360F(x) = arcsinuF(360,x) arccos360F : F ( F ( {invalid} arccos360F(x) = arccosuF(360,x) arctan360F : F ( F ( {underflow} arctan360F(x) = arctanuF(360,x) arccot360F : F ( F ( {underflow} arccot360F(x) = arccotuF(360,x) arcctg360F : F ( F ( {underflow} arcctg360F(x) = arcctguF(360,x) arcsec360F : F ( F ( {invalid} arcsec360F(x) = arcsecuF(360,x) arccsc360F : F ( F ( {underflow, invalid} arccsc360F(x) = arccscuF(360,x) Radian arcus sinus The arcsin*F approximation helper function: arcsin*F : F ( R arcsin*F(x) returns a close approximation to arcsin(x) in R, with maximum error max_error_arcsinF. Further requirements on the arcsin*F approximation helper function: arcsin*F(1/2) = (/6 arcsin*F(1) = (/2 arcsin*(x) = x if arcsin*F(x) ( arcsin(x) and |x| < ((2*epsilonF/rF) [2?] arcsin*F(x) = arcsin*F(x) The arcsinrF operation: arcsinrF : F ( F ( {invalid} [underflow?] arcsinrF(x) = trans_resultF(arcsin*F(x)) if x ( F and fminNF < |x| ( 1 = x if x ( F and |x| ( fminNF = 0 if x = 0 = invalid(qnan) if x ( F and (x < 1 or x > 1) = invalid(qnan) if x ( {(,+(} = qnan if x is a quiet NaN = invalid(qnan) if x is a signalling NaN Note: underflow is explicitly avoided. [I suggest removing this avoidance.] Radian arcus cosinus The arccos*F approximation helper function: arccos*F : F ( R arccos*F(x) returns a close approximation to arccos(x) in R, with maximum error max_error_arcsinF. Further requirements on the arccos*F approximation helper function: arccos*F(1/2) = (/3 arccos*F(0) = (/2 arccos*F(1/2) = 2*(/3 arccos*F(1) = ( The arccosrF operation: arccosrF : F ( F ( {invalid} arccosrF(x) = trans_resultF(arccos*F(x)) if x ( F and 1 ( x ( 1 = trans_resultF((/2) if x = 0 [arccosrF(0)] = invalid(qnan) if x ( F and (x < 1 or x > 1) = invalid(qnan) if x ( {(,+(} = qnan if x is a quiet NaN = invalid(qnan) if x is a signalling NaN Radian arcus tangent The arctan*F approximation helper function: arctan*F : F ( R arctan*F(x) returns a close approximation to arctan(x) in R, with maximum error max_error_arctanF. Further requirements on the arctan*F approximation helper function: arctan*F(1) = (/4 arctan*F(x) = x if arctan*F(x)(arctan(x) and |x| ( ((1.5*epsilonF/rF) arctan*F(x) = (/2 if arctan*F(x)(arctan(x) and x > ... [?] arctan*F(x) = arctan*F(x) The arctanrF operation: arctanrF : F ( F [ ( {underflow}?] arctanrF(x) = trans_resultF(arctan*F(x)) if x ( F and fminNF < |x| = x if x ( F and |x| ( fminNF = 0 if x = 0 = trans_resultF((/2) if x = ( = trans_resultF((/2) if x = +( = qnan if x is a quiet NaN = invalid(qnan) if x is a signalling NaN Note: arctanrF(x) ( arcrF(1,x) Note: underflow is explicitly avoided. [I suggest removing this avoidance.] Radian arcus cotangent The arccot*F and arcctg*F approximation helper functions: arccot*F : F ( R arcctg*F : F ( R arccot*F(x) returns a close approximation to arccot(x) in R, with maximum error max_error_arctanF. arcctg*F(x) returns a close approximation to arcctg(x) in R, with maximum error max_error_arctanF. Further requirements on the arccot*F and arcctg*F approximation helper functions: arccot*F(1) = (/4 arccot*F(0) = (/2 arccot*F(1) = 3*(/4 arccot*F(x) = ( if arccot*F(x) ( arccot(x) and x < ... [?] arcctg*F(x) = arccot*F(x) if x ( 0 arcctg*F(x) = arcctg*F(x) The arccotrF operation: arccotrF : F ( F ( {underflow} arccotrF(x) = trans_resultF(arccot*F(x)) if x ( F = trans_resultF((/2) if x = 0 = trans_resultF(() if x = ( = 0 if x = +( = qnan if x is a quiet NaN = invalid(qnan) if x is a signalling NaN Note: arccotrF(x) ( arcrF(x,1) Note: There is no jump at zero for arccotrF. The arcctgrF operation: arcctgrF : F ( F ( {underflow} arcctgrF(x) = trans_resultF(arcctg*F( x)) if x ( F = trans_resultF((/2) if x = 0 = 0 if x = ( = 0 if x = +( = qnan if x is a quiet NaN = invalid(qnan) if x is a signalling NaN Note: arcctgrF(negF(x)) = negF(arcctgrF(x)) Radian arcus secant The arcsec*F approximation helper function: arcsec*F : F ( R arcsec*F(x) returns a close approximation to arcsec(x) in R, with maximum error max_error_arcsecF. Further requirements on the arcsec*F approximation helper function: arcsec*F(2) = (/3 arcsec*F(2) = 2*(/3 arcsec*F(1) = ( arcsec*F(x) ( (/2 if x > 0 arcsec*F(x) ( (/2 if x < 0 The arcsecrF operation: arcsecrF : F ( F ( {invalid} arcsecrF(x) = trans_resultF(arcsec*F(x)) if x ( F and (x ( 1 or x ( 1) = invalid(qnan) if x ( F and 1 < x < 1 = invalid(qnan) if x = 0 = trans_resultF((/2) if x = ( = trans_resultF((/2) if x = +( = qnan if x is a quiet NaN = invalid(qnan) if x is a signalling NaN Radian arcus cosecant The arccsc*F approximation helper function: arccsc*F : F ( R arccsc*F(x) returns a close approximation to arccsc(x) in R, with maximum error max_error_arcsecF. Further requirements on the arccsc*F approximation helper function: arccsc*F(2) = (/6 arccsc*F(1) = (/2 arccsc*F(x) = arccsc*F(x) The arccscrF operation: arccscrF : F ( F ( {underflow, invalid} arccscrF(x) = trans_resultF(arccsc*F(x)) if x ( F and |x| ( 1 = invalid(qnan) if x ( F and 1 < x < 1 = invalid(qnan) if x = 0 = 0 if x = ( = 0 if x = +( = qnan if x is a quiet NaN = invalid(qnan) if x is a signalling NaN SIDA  SIDA 44  h.A@ copy@dest@feed@vfpan@nmap@$pmap@8qual@rang@|smap@*sort@tmap@0BestNormalDraft##: US Letter@RsyptPtT  W  A4 Letter' =' =ߙ4z'`@base@crea@ flag@unit@sypt@@dirm@ layo@scal@ dd A4 Letter' =' =ߙ4z'`@base@crea@ flag@unit@sypt@@dirm@layo@scal@  ddunivnonerastSWIIStyleWriter GXStyleWriter GXࡱ; vasz/?)*/01267@A3 : < @ B O ] i j F L M N R        " # & ' JZJJVh^VUUVc [' ) * + , - 5 6    <HI\hizQVW,0<=@ABCDEFGHQSdjvwxy}JJV]hV]]JpUVhUVUVhJVhVhU    ()*+/@CDJQRSTY]^copqrvJUJhJVhV^ <CDEFPQYefghlu| !%*+/;<=>BKU[\]b`JhVhUV`   y rwx~EJK_h^klqrstv&JJUJhVhV^&348ABEL[\]^_`bcnost" ' ( ) . / 0 1 2 3 5 6 7 8 9 E J K L M N O P Q R W ] ^ ` a b c d e f h m r s J]J]JJJ]V]hV]]VhVWs t u v w x !!!!!!)!*!+!,!-!.!2!7!8!9!:!;!H!I!J!K!L!M!R!S![!`!a!b!c!d!k!l!q!r!s!t!u!v!{!|!}!~!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!JJVhVVh`!!!!!!!!!!!!!!!!""""#"%")"/"4"5"6"7"8"9"@"L"M"N"S"T"U"V"W"X"Y"d"e"f"g"h"i"n"o"v"w"x"y"z"{"""""""""""""""""""""""""""""""""""""""JJUJJJVhV\"########"###1#8#@#A#J#K#O#o#{########################################## $$$$$$%$($)$.$/$2$3$5$H$V$W$^$_$`$a$b$c$h$i$p$q$t$u$$$$$$$$$JJUJV`$$$$$$$$$$$$$$$$$$$$$$$$$$$$$%% %)%<%=%@%A%I%J%K%L%M%N%S%T%[%\%_%`%o%v%x%y%z%{%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%Z`V``JZUJJV\%%%% & & &&&&&&!&"&#&(&)&=&?&@&A&M&T&V&W&X&Y&[&^&_&o&q&r&s&w&x&&&&&&&&&&&&&&&&&&&&&&&&&&'''(')'/'0'1'5'6'q'r'''''''''''''''''''JJVhVhVUV`Z`Z`Z'''''''''''''''''''( ( ((((((((#($(%(&('(((-(.(5(6(7(8(9(:(F(R(S(T(Y(Z([(](^(_(`(k(l(m(n(o(p(u(v(}(~((((((((((((((((((((((((((((((((((JVhVUJ`(((((((()))))%)&)/)0)4)S)_)c)f)g)n)o)x)y)z){)|)})))))))))))))))))))))))))))****$*%*H*L*O*P*W*X*d*e*f*g*h*i*n*o*z*{********************JUJVa*************+ + ++++++:+M+N+S+T+Z+[+\+]+^+_+d+e+w+x+++++++++++++++++++++++++++++++++++,, , ,,+,>,?,D,E,K,L,M,N,O,P,U,V,a,b,x,y,~,,,,,,UJJVa,,,,,,,,,,,,,,,,,,,,,,,,,,,,,- - -c-d-g-l-m------.$.%.*.0.2................///////-/./G/H/N/O/P/T/U/r/s////////////////JVhVhUZV_/////////00000(0)0*00010H0W0X0w0~000000000000000000000000000000000000001 1111111111111&1'1(1+12131718191?1F1G1H1I1J1R1S1Y1Z1[1JJVhVhJV^[1\1]1^1c1d1e1f1m1t1u1v1w1x1z1{1}1~1111111111111111111111111111111111111111111111111111111122222 222$2+2,2/20212223242526272JJJJVhJVJ\728292:2<2C2E2N2P2a2c2g2m2t2u2v2w2x2y2}222222222222222222222222222222222222222222222233!3"3+3,3-3.3/30393:3S3T3]3^3_3`3a3b3i3j3k3l33333JJJJVhUJV\3333333333333333333333333444 4%4&4=4>4G4H4I4J4K4L4Q4R4b4i4s4t4}4~444444444444455 5 555555555758595:5;5<5B5C5D5K5L5O5P5a5b5h5i5j5k5l5m5s5t5u5|5}5UJJVJ`}555555555555555555555555555555566666666#6$6'6(6:6;6A6B6E6F6N6O6P6Q6R6S6X6Y6`6a6d6e6u6|66666666666666666666666666777777777ZJVUJ`77777!7"7%7&75767778797:7;7<7@7A7J7K7]7^7_7`7b7e7f7q7s7t7u7z7{77777777777777777777777777777778 8 8 888!8#8$8%8/868788898:8;8^8_8`8c8g8h8s8t888VhVhUZ`V``ZJJJVZ88888888888888888889999?9C9D9E9K9L9M9N9O9P9U9Y9Z9[9\9]999999999999999999:: : : : :::::::::: :/:0:4:;:<:@:A:B:H:I:O:P:T:[:\:d:h:i:j:k:l:q:r:hJJVhJVVh^r:w:x:y:z:|:}:~:::::::::::::::::::::::::::::::::::::::::::::::::;;;;;;%;1;2;3;7;8;9;:;;;B;C;D;E;F;G;Y;Z;m;n;v;w;|;};;;;;;;ZJUJJhVhVhJJVZ;;;;;;;;;;;;;;;;;;;;;;;;;;"<#<)<*<+</<0<E<J<K<L<p<u<v<w<|<}<~<<<<<<<<<<<<<<<<<<===)=.=/=0=1=2=<===>=?=@=A=G=L=M=N=O=P=R=S=V=W=f=h=l=s=t=x=y=JJVhJhVhUVZ\y=z===================================================>> >>>!>&>'>*>+>,>->.>/>0>1>3><>>>O>U>Z>[>\>]>e>q>r>s>x>y>z>{>|>>>>>>>>UJJJJVhhVVh\>>>>>>>>>>>>>>>>>>>>>>????????+?-?.?/?9?>???@?A?d?e?k?m?n?r?s??????????????????????? @ @@@)@6@7@V@Y@Z@[@@@@@@@@@@@@@@VhJUVhVhUZJV[@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@AA AAAAAAAAAA%A*A+A4A7A8AHAKALAOAPAQARASATAUAVAXAaAcAtAzA}A~AAAAAAAAAAAAAAAAAAAAAAAAAAAJUJJVhJVhVJ[AAAA B B B BBBB B!B"B,B3B5B6B7B8B?B@BPBRBSBTB^BaBbBhBoBpB|BBBBBBBBBBBBBBBBC$C%C&C+C,C-C.C/C0C5C:C;CCcCdCjCkCCCCCCCCCCCCCCCCCCCCDDDDDDJVhJUVVhUZJV\D DDDDDDDDDD+D2D3D5D6D7D8D9D:DADHDIDKDLDXD]D^D_D`DaDlDmDnDoDpDqDwD|D}D~DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDEEUJJJJVhJVhV[EEE$E%E&E'E.E:E;EMJJJVhVV]hJ]V]]X>M?MGMNMOM_MfMgMjMkMlMmMnMoMpMqMrMsMtMuMwM~MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMN NNNNNN$N%N&N'N(N)N*N+N/N0N9N:NJNQNRNSNTN\N]NhNiNjNkNJJUJJJVhVJ[kNlNmNnNoNsNtNyNzNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNOOOOO O OOOOO+O,O2O3O4O5O6O7O>O?OFOGOLOMO\OcOkOlOqOrOxOyO|O}O~OOOOOOOOOOOOOOOOOOOOOJJUJJV_OOOOOOOO PPPP"P#P)P*P,PLP\P]PcPdPmPnPsPtPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPQQQQQQ Q QQQ!Q(Q*Q+Q,Q-Q4Q5Q6Q7Q8Q9Q>Q?Q@QFQGQJQKQZQ[Q\Q]Q^Q_Q`QaQeQfQJJZJUJV^fQjQkQ{QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ R R RRRRR R"R%R&R1R3R4R5R:R;RORQRRRSRaRhRjRkRlRmRoRrRsRRRRRRRRRRRRRRR SVhZ`V``JJVZUJZ SSSSSSSSSS S!S"S#S(S1S2S3S4S5S6S7S]S^SaSbSgShSSSSSSSSSSSSSSSSSSSSSSSSTT TTTTT T!T"T#T$T%T&T(T)T+T2T3T4T5T6T7T8T=T>T?T@TATBTKTLTUTVTWTXTYTZT_T`ThTqTrTJJJJJVhV]rTsTtTuTvTwTyTzT|TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTUUU UUUUUUUU(U)U9UBUCUFUGUHUIUJUKULUMUNUOUPUQUJJJJJJJVVh[QUSUZU\UeUgUkUqUzU{U|U}U~UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUVVV VVVVVVVVV V!V%V&V/V0VJVKVTVUVVVWVXVYVbVcV}V~VVVVVVVVVVVVVVVVJJJJVhVU^VVVVVVVVVV W WWWWWWW'W(W@WAWMWNWSWTWdWkWmWnWoWpWvWwWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWXXXXXXXX&X'X.X/X4X5XGXHXNXOXPXQXRXSXZX[XbXcXhXiXzXXXZUJJV`XXXXXXXXXXXXXXXXXXXXXXXXYYYYYYYYYYYY-Y4Y=Y>YCYDYJYKYPYkY}Y~YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY ZZZZZZ$Z%Z&Z'Z(Z)Z1Z2Z3Z4ZHZJZUJJJV^HZOZQZRZSZTZ[Z\Z]Z^Z_Z`ZeZfZgZmZnZqZrZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ[[[ [ [[[[[[[#[$[8[:[;[<[L[M[N[O[Q[T[U[`[b[c[d[i[j[~[Z`V``JJJJVZU[~[[[[[[[[[[[[[[[[[[[[[[[[[[[[\\\\\ \!\"\#\$\)\-\.\/\0\1\W\X\Y\Z\_\`\w\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\]]]]]]]]] ]!]JhJVhVV`ZU`Z`[      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~!]"]#]$]&]-]/]3]9]=]>]?]@]K]W]X]Y]]]^]_]`]a]h]i]j]k]l]m]r]s]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]^^ ^^^^^^#^$^/^1^2^3^=^D^F^G^H^I^P^Q^a^c^d^e^}^^^^^^^ZJJVhUJV^^^^^^^^^^^^^^^^^^^^^___<_A_B_C_g_l_m_n_o_p_x_z_{_|______________________________________________``` ` ` ` ``` `$`'`UJJhJVVh]'`(`0`1`?`C`F`G`O`P`c`d`l`m`r`s`~````````````````````````````````````aaaa!a#a$a%aIaKaLaMaWaXaYaZa[a\aaacadaeafagaaaaaaaaaaaaabbbbbb$bJVhJZUVJ^$b&b'b*b+b,b-b.b/b0b1b3b:bc?cIcPcRcScTcUc\c]cmcocpcZJJUJJVhV]pcqcccccccccccccccccccccdddd4d@dAd`dddedfddddddddddddddddddddddddddddddddddddddddddde e eeeeeeeeeeee e!e"e#eJJJJJVhVZ\#e$e%e*e+e5e9e:eJeNeOeReSeTeUeVeWeXeYe[ebedehejeseye}e~eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeffff ffffff0f1fBfFfIfJfQfRfcfdfkflfqfrf}ffffffffZJJJUJJVhV\fffffffffffffffffffffffffffffffgg ggPgUgVgWgXgYg`gaglgog}gggggggggggggggggggggggggggggggg\ijikiminioipiriiiiiiiiiiiJVhUZJVJ^iiiiiiiiiiijj5jCjDjHjQjRjYjgjhjjjjjjjjjjjjjjkkkkkkk kkkkkk>k?kDkEk\kjkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkklllllllJJJVhVJ^lllll#l$l%l&l'l,l-l.l/l0l1l6l:l;ll@lAlBlFlGlHlIlJlSlTlUlVlWlXl^lblclslwlxl{l|l}l~llllllllllllllllllllllllllllllllllllmmmmmm!m"m$m%m&m+m,m?mUJJJJVVh^?m@mQmRmZm[m`mamlmmmumvm{m|mmmmmmmmmmmmmmmmmmmmmmmmmm!n)n-n.n/n0nTnUn^nbncnnnnnnnnnnnnnnnnnnnnnnnnn ooo:o>o?o@odohoiojokolowoxoyozo{o|ooJJVh]UZJV]oooooooooooooooooooooooooooooooooooooooooooooooooooooooooopppppppppppp p"p3p9p=p>p?p@pIpUpVpWp[p\p]p^p_pfpgphpipUJJJJJJ<JVhVZipjpkp|p}ppppppppppppppppppppppppppppppp qqqqqqq q!qAqBqKqOqPqnqrqsqtqqqqqqqqqqqqqqqqqqqqqqrr(r,r-r.rRrVrWrXrYrZr^r_rdrerfrgrhrirnrJJVhUZJV^nrrrsrtrurvrxryrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrss s sssssssssss$s%s&s's(s)s/s3s4sDsHsIsLsMsNsOsPsQsUsVsXsasismsnsospsxsUJJJJJJVhV[xsssssssssssssssssssssssssssssssssssstttt t3t4t9t:tEtFtGtHtOtPt[t]t^t_thtotqtrtsttt{t|tttttttttuuuu*u.u/u0u3u4u5u6u7u8u=uAuBuCuDuEumunuJ]UZJJJVhV\nusutuuuuuuuuuuuuuuuuuuuuuvvvvv v vvvvv-v4v5v>vBvCvDvFvGvLvPvQvRvSvTvYvZv[v\v]v^vdvhvivyv}v~vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvUJJJJVhV^vvvvvvvvvw wwwww1w2w7w8wJwKwPwQw[w\w]w^wewfwqwswtwuw}wwwwwwwwwwwwwwwwwwwwwwwxxx&x*x+x,x/x0x1x2x3x4x9x=x>x?x@xAxixjxoxpxxxxxxxxxxxxxxxxxJVhZVJUJ^xxxxxxyyyyyy y yyyyyyyy"y#y$y%y&y+y/y0y1y3y4y9y=y>y?y@yAyFyGyHyIyJyKyPyTyUyVyWyXyZy[y\y`yaybycydyjykylymynyoytyuy}yyyyyyyyyyyyyyyyyyyyyyyyyyyyJJJ<JVhVJ]yyyyyyyyyyyyyyy z z zzzzzzzzzzz z1z2zJzKzPzQzczdzizjzuzvzwzxzzzzzzzzzzzzzzzzzzzzzzz{ { {{{{{{{{{{ {!{"{#{K{L{Q{R{i{w{x{{{{{{ZJJVhUJVJ\{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{|||||| | ||||||||$|%|+|,|-|.|/|0|5|6|>|C|D|M|Q|R|b|f|g|j|k|l|m|n|o|p|q|s|||~|||||||||||||||||||UJJJJVhV^|||||||||||||||||}}}}}+},}1}2}D}E}J}K}V}W}X}Y}`}a}l}n}o}p}y}}}}}}}}}}}}}}}}}}}}}}~f~g~i~j~o~p~|~}~~~~ &'()*+-J]J]V]]VhZJUJJVX->?BCDEK\] O`aenoƁǁȁˁ́́΁ρЁՁ܁݁ށ߁ ):;Zabĉ͂ςЂт҂Ղ܂JJJJJVhV]܂݂ނ߂ *1256789:>?AJSZ[\]dpqryz{|}ŃƃǃȃɃʃЃуӃԃՃڃۃ$%-.34JJUJJJVVh\4ABCDJKVXYZelnopqwx݄,34589:;<=BIJKLMxy~ʅх҅Յօׅ؅مڅۅ܅ޅ  !&'(JJJVh]UVZ\()9:BCHIV]_`abhijklmrs†Іц҆ӆنچ?FGHlstuxyz{|}ևJVhJZUVJJ\4;<=>?DEJKLMNOT[\]^_abklz{LjΈψ߈ '345<=>?@FGHIUJJJJJVhV\IJKPUVZ[lmщՉ؉ى$%&'()/0AHJKLMSTYZ_`eftuvw}~ɊҊ5<=]ZJUJJVhV]=>bijknopqrsx̋݋ދ*12356;BCDEFLMNOPQW^_ovwz{|}~njȌɌʌˌьҌӌԌՌ֌܌݌JUJJJVVh^ <=BCXY^_lsuvwx~ōƍǍȍ΍ύڍ܍ݍލ &/ˎҎӎԎ׎؎َڎێ܎5FGNUVfmnqJVhJZVJU^qrstuvwxzÏ̏͏ΏϏݏ")+,-.456789?@HIZacdeflmrsxy~ZJJJVhUJJV\ĐŐՐאِؐ*1236789:;@GHIJKvw|}ő̑͑Α $+,-./56789:@GHX_`cdefghijluw{UJJJVhVZ^͒ђԒՒݒޒ#$9:?@NOPQWXcefgsz|}~