[Date Prev] | [Thread Prev] | [Thread Next] | [Date Next] -- [Date Index] | [Thread Index] | [List Home]

*Subject*: **[OASIS Issue Tracker] (ODATA-785) Numeric promotion (on overflow) across "number type families" is undesirable.**

*From*:**OASIS Issues Tracker <workgroup_mailer@lists.oasis-open.org>***To*: odata@lists.oasis-open.org*Date*: Wed, 2 Mar 2016 14:21:48 +0000 (UTC)

[ https://issues.oasis-open.org/browse/ODATA-785?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=61961#comment-61961 ] Michael Pizzo edited comment on ODATA-785 at 3/2/16 2:21 PM: ------------------------------------------------------------- Discussion from 2016-3-1: Within comparison expressions, services should promote as necessary to perform comparison operation – should not be unnecessarily restricted by types of operands. (expressions may be calculated and compared using more precision than the operands). The type becomes meaningful for reporting @odata.type in result of compute. This should be static (not data dependent). If a value doesn't fit into static type, return NaaN/-inf/+inf (need to add for int) We could: a) Statically define the types of each type to each operator i) Pick the smallest type that is guaranteed to fit ii) Aggressively promote to largest type (i.e., Edm.Decimal) b) Say that such values are "untyped" Minimal types for each operation: Int16 add/mult/sub Int16 => Int32 Int32 add/mult/sub Int16/32 => Int64 Int64 add/mult/sub Int16/32/64 => Int64 (may be +/-inf) or Decimal? (which is assumed if not written) >> for int, one greater than the size of the greatest operand, up to Int64 >> do we promote to decimal? Propose: >>>int* add/mult/sub int* => int64 (may be +/-inf) Int* div Int* => loperand (or larger) Int* div decimal/single/double => roperand Decimal/single/double div number => loperand Number div decimal/single/double =>decimal >>adding divideby operator that does mathematical division (number divideby number => decimal) >>int* div int* => loperand (or larger) -> service can always promote to int64 Int16 mod int* => int16 Int32 mod int* => int32 Int64 mod int* => int64 >> Int* mod Int* the type of the loperand (or larger) Int* mod decimal/single/double => roperand (could always say decimal) Decimal/single/double mod number => loperand (could always say decimal) >>simple rule would be if either result is non-integer, the result is decimal Single add/mult/sub single => double >> What should we do? IEE doesn’t support promoting single to double. This is C++/Java behavior. Double add/mult/sub single/double => double may have over/underflow Single add/mult/sub double => double >> what do we do for overflow/underflow of int? add +inf/-inf/nan for int datatypes. >> in JSON Schema 5, can we say that a number can contain "inf", "-inf", "nan"? better would have been define these values (unquoted, like null) for number. Working Proposal: 1) Add divideby that always results in a decimal (as if both operands were promoted to decimal) 2) add +inf/-inf/nan to int 3) specify that, within comparison expressions, services should promote as necessary to perform comparison operations – should not be unnecessarily restricted by types of operands. (expressions may be calculated and compared using more precision than the operands) 4) specify the result type for each operation based on operator types (refine and put in matrix) a) int* add/mult/sub int* => int64 (may be +/-inf) b) Int* add/mult/sub decimal/single/double => promotion rules will promote, then type c) int* div int* => loperand (or larger) -> service can always promote to int64 d) Int* div decimal/single/double => roperand e) decimal/single/double div number => operation promotes smaller operand; result is that type e) number divideby number =>decimal f) Int* mod Int* the type of the loperand (or larger) g) Int* mod decimal/single/double => roperand (service can promote to decimal) h) Decimal/single/double mod number => loperand (service can promote to decimal) f) Single add/mult/sub single -> single g) Double add/mult/sub Double -> double (note, if either operand is single, gets promoted to double) 5) Don't promote outside of type families 6) Do not promote Single->Double 7) Push for, in JSON Schema 5, that the strings "-inf", "+inf", "nan" are valid for numbers was (Author: mikep): Discussion from 2016-3-1: Within comparison expressions, services should promote as necessary to perform comparison operation – should not be unnecessarily restricted by types of operands. (expressions may be calculated and compared using more precision than the operands). The type becomes meaningful for reporting @odata.type in result of compute. This should be static (not data dependent). If a value doesn't fit into static type, return NaaN/-inf/+inf (need to add for int) We could: a) Statically define the types of each type to each operator i) Pick the smallest type that is guaranteed to fit ii) Aggressively promote to largest type (i.e., Edm.Decimal) b) Say that such values are "untyped" Minimal types for each operation: Int16 add/mult Int16 => Int32 Int32 add/mult Int16/32 => Int64 Int64 add/mult Int16/32/64 => Int64 (may be +/-inf) or Decimal? (which is assumed if not written) >>for int, one greater than the size of the greatest operand, up to Int64 >>do we promote to decimal? Int div int => int adding divideby operator that does mathematical division (number divideby number => decimal) Int16 mod int* => int16 Int32 mod int* => int32 Int64 mod int* => int64 >>the type of the loperand (could always say int64) Int* mod decimal/single/double => roperand (could always say decimal) Decimal/single/double mod number => loperand (could always say decimal) Single add/mult/sub single => double Double add/mult/sub single/double => double Single add/mult/sub double => double =>don't promote to decimal, do promote single=>double? >>what do we do for overflow/underflow of int? add +inf/-inf/nan for int datatypes. >>in JSON Schema 5, can we say that a number can contain "inf", "-inf", "nan"? better would have been define these values (unquoted, like null) for number. Working Proposal: 1) Add divideby that always results in a decimal (as if both operands were promoted to decimal) 2) add +inf/-inf/nan to int 3) specify that, within comparison expressions, services should promote as necessary to perform comparison operations – should not be unnecessarily restricted by types of operands. (expressions may be calculated and compared using more precision than the operands) 4) specify the result type for each operation based on operator types 5) Don't promote outside of type families 6) Do promote Single->Double 7) Promote, in JSON Schema 5, that the strings "-inf", "+inf", "nan" are valid for numbers > Numeric promotion (on overflow) across "number type families" is undesirable. > ----------------------------------------------------------------------------- > > Key: ODATA-785 > URL: https://issues.oasis-open.org/browse/ODATA-785 > Project: OASIS Open Data Protocol (OData) TC > Issue Type: Improvement > Components: OData URL Conventions > Affects Versions: V4.0_OS > Environment: Proposed > Reporter: Evan Ireland > Priority: Minor > Fix For: V4.01_WD01, V4.0_ERRATA03 > > > URL Conventions spec section 5.1.1.10 "Numeric Promotion" states: > "If the result of an arithmetic operation does not fit into the type determined by the above rules, the next-wider type is used in the above order, with Edm.Double considered widest." > We may group OData numeric types into three families: > integer types: Byte, SByte, Int16, Int32, Int64 > decimal types: Decimal > floating types: Single, Double > Numeric promotion as a result of overflow is undesirable when it results in promotion between number type families. The semantics of arithmetic operators can therefore not be determined by static analysis. For example: > First issue: > ---------------- > If A, B and C integer values, then "(A add B) div C" is an integer unless "A add B" overflows Int64, in which case "(A add B) div C" will be decimal. > Now consider "((A add B) div C) mod D". If "(A add B) div C" is decimal due to overflow, then "((A add B) div C) mod D" is an invalid expression since the "mod" operator is only defined for integral types. > Second issue: > ---------------- > Now consider that X and Y are decimal values. If (X add Y) overflows the range for decimal values, then according to the spec, (X add Y) is promoted to type Single. Two issues then arise: > (1) Type Single has much less precision than either Decimal or Double. The implicit promotion on overflow should (if we permit promotion across number type familes) arguably be to type Double, to avoid unnecessary loss of precision. > (2) "(X add Y)" div 0 is an error if "X add Y" does not overflow, but is positive or negative infinity if "X add Y" overflows and is promoted to a floating type. So the semantics of division are not statically determinable. > Third issue: > ---------------- > Consider (E add F) where E and F are type Single. > Promotion of the result from Single to Double (on overflow, say if the result exponent is outside the range of type Single) is not in accordance with IEEE floating point rules, which specify positive or negative infinity in this case. -- This message was sent by Atlassian JIRA (v6.2.2#6258)

[Date Prev] | [Thread Prev] | [Thread Next] | [Date Next] -- [Date Index] | [Thread Index] | [List Home]