json-processing-spec
  1. json-processing-spec
  2. JSON_PROCESSING_SPEC-41

Remove NumberType.LONG and rename NumberType.BigDecimal

    Details

    • Type: Improvement Improvement
    • Status: Resolved
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 1.0-pr
    • Fix Version/s: 1.0-pr
    • Labels:
      None

      Description

      NumberType would be less confusing if it just stated the distinction whether a number has a fractional part.

      A NumberType of INTEGER would guarantee that calling getBigIntegerValue does not throw an ArithmeticException. The NumberType would be independent of the actual magnitude of the number, thus calling getIntValueExact might still throw an Exception if the number is smaller than Integer.MIN_VALUE of larger than Integer.MAX_VALUE.

      The current NumberType BIG_DECIMAL should be renamed to just DECIMAL or REAL (see http://en.wikipedia.org/wiki/Real_number) and would indicate that the number has a fractional part and calling get(Int|Long|BigInteger)ValueExact might throw an ArithmeticException.

      The algorithm for distinguishing these two types should be based on whether BigDecimal#scale() is 0.

      Discussion at http://java.net/projects/json-processing-spec/lists/users/archive/2012-12/message/43

        Activity

        Hide
        jitu added a comment -

        Resolving with the proposal in this issue

        Show
        jitu added a comment - Resolving with the proposal in this issue
        Hide
        jitu added a comment -

        Let me commit the proposal in this issue. I don't think we need to define what ME is going to do here now. Anyway, ME needs to define semantics for other methods like equals(), hashCode() etc.

        Show
        jitu added a comment - Let me commit the proposal in this issue. I don't think we need to define what ME is going to do here now. Anyway, ME needs to define semantics for other methods like equals(), hashCode() etc.
        Hide
        jhorstmann added a comment -

        A ME profile would probably store the number in a double, which has no concept similar to BigDecimal#scale(). It could return type INTEGER if getDoubleValue() == Math.floor(getDoubleValue());, but this would return different results than an implementation based on BigDecimal for numbers like "1.0".

        The equivalent code with BigDecimal would be:

        try {
            bd.setScale(0, RoundingMode.UNNECESSARY);
            return NumberType.INTEGER;
        } catch (ArithmeticException ex) {
            return NumberType.DECIMAL;
        }
        

        If we can not decide on the correct semantics, then it would probably be better to remove the NumberType distinction completely or defer it to a future version.

        Show
        jhorstmann added a comment - A ME profile would probably store the number in a double, which has no concept similar to BigDecimal#scale() . It could return type INTEGER if getDoubleValue() == Math.floor(getDoubleValue()); , but this would return different results than an implementation based on BigDecimal for numbers like "1.0". The equivalent code with BigDecimal would be: try { bd.setScale(0, RoundingMode.UNNECESSARY); return NumberType.INTEGER; } catch (ArithmeticException ex) { return NumberType.DECIMAL; } If we can not decide on the correct semantics, then it would probably be better to remove the NumberType distinction completely or defer it to a future version.
        Hide
        jitu added a comment -

        ME could use a similar algo what scale() is doing to determine if the number has a fractional part or not.

        I am thinking of rolling the following:

            /**
             * JSON number type that is used to find out if a number is numerically
             * integer or a decimal.
             */
            enum NumberType {
                /**
                 * Represents a number that is numerically integer.
                 * The value can be accessed as int, long, or BigInteger using
                 * different JsonNumber accessor methods.
                 */
                INTEGER,
        
                /**
                 * Represents a number that is numerically decimal. The value can
                 * be accessed as double, or BigDecimal using different JsonNumber
                 * accessor methods.
                 */
                DECIMAL
            }
        
            /**
             * Returns a JSON number type for this number.
             * A {@link BigDecimal} may be used to store the numeric value internally
             * and the semantics of this method is defined using
             * {@link BigDecimal#scale()}.
             * If the scale of a value is zero, then its number type is
             * {@link NumberType#INTEGER INTEGER} else {@link NumberType#DECIMAL DECIMAL}.
             *
             * <p>
             * The number type can be used to invoke appropriate accessor methods to get
             * numeric value for the number.
             * <p>
             * <b>For example:</b>
             * <code>
             * <pre>
             * switch(getNumberType()) {
             *     case INTEGER :
             *         long l = getLongValue(); break;
             *     case DECIMAL :
             *         BigDecimal bd = getBigDecimalValue(); break;
             * }
             * </pre>
             * </code>
             *
             * @return a number type
             */
            NumberType getNumberType();
        
        Show
        jitu added a comment - ME could use a similar algo what scale() is doing to determine if the number has a fractional part or not. I am thinking of rolling the following: /** * JSON number type that is used to find out if a number is numerically * integer or a decimal. */ enum NumberType { /** * Represents a number that is numerically integer. * The value can be accessed as int , long , or BigInteger using * different JsonNumber accessor methods. */ INTEGER, /** * Represents a number that is numerically decimal. The value can * be accessed as double , or BigDecimal using different JsonNumber * accessor methods. */ DECIMAL } /** * Returns a JSON number type for this number. * A {@link BigDecimal} may be used to store the numeric value internally * and the semantics of this method is defined using * {@link BigDecimal#scale()}. * If the scale of a value is zero, then its number type is * {@link NumberType#INTEGER INTEGER} else {@link NumberType#DECIMAL DECIMAL}. * * <p> * The number type can be used to invoke appropriate accessor methods to get * numeric value for the number. * <p> * <b>For example:</b> * <code> * <pre> * switch (getNumberType()) { * case INTEGER : * long l = getLongValue(); break ; * case DECIMAL : * BigDecimal bd = getBigDecimalValue(); break ; * } * </pre> * </code> * * @ return a number type */ NumberType getNumberType();
        Hide
        keilw added a comment - - edited

        >The algorithm for distinguishing these two types should be based on whether >BigDecimal#scale() is 0.

        What would it be on ME, as BigDecimal and BigInteger would not be there?

        Aside from that, I fully agree with renaming BIG_DECIMAL to something like DECIMAL, REAL or FLOATING, which covers all numbers with decimal value.

        And keep INTEGER or rename INT, ideally dropping the LONG.

        An alternative could again be the JSON spec which knows
        int

        • digit
        • digit1-9 digits
          • digit
          • digit1-9 digits

        frac

        • . digits

        exp

        • e digits

        see http://json.org/

        If there are sufficient algorithms to tell FRAC (which is quite similar to FLOATING or DECIMAL) from EXP, this may be closest to JSON design.

        Werner

        Show
        keilw added a comment - - edited >The algorithm for distinguishing these two types should be based on whether >BigDecimal#scale() is 0. What would it be on ME, as BigDecimal and BigInteger would not be there? Aside from that, I fully agree with renaming BIG_DECIMAL to something like DECIMAL, REAL or FLOATING, which covers all numbers with decimal value. And keep INTEGER or rename INT, ideally dropping the LONG. An alternative could again be the JSON spec which knows int digit digit1-9 digits digit digit1-9 digits frac . digits exp e digits see http://json.org/ If there are sufficient algorithms to tell FRAC (which is quite similar to FLOATING or DECIMAL) from EXP, this may be closest to JSON design. Werner
        Hide
        jitu added a comment - - edited

        The current number type is the minimum holding number type. For 1.23e2, it gives INT.

        This proposal is primarily removing "minimum holding" number type. So API doesn't provide a way if the integral number fits into int, long, BigInteger, and it becomes an application responsibility.

        If applications don't require to know about this minimum holding number type, then I am fine with the proposal. I will see if there any comments internally.

        Show
        jitu added a comment - - edited The current number type is the minimum holding number type. For 1.23e2, it gives INT. This proposal is primarily removing "minimum holding" number type. So API doesn't provide a way if the integral number fits into int, long, BigInteger, and it becomes an application responsibility. If applications don't require to know about this minimum holding number type, then I am fine with the proposal. I will see if there any comments internally.
        Hide
        jhorstmann added a comment -

        On a Jave ME profile of this JSON API, the methods getBigIntegerValue(Exact) and getBigDecimalValue would be excluded, NumberType should be INTEGER if the number can be exactly represented as a long, which is the largest integral type on such platforms.

        Show
        jhorstmann added a comment - On a Jave ME profile of this JSON API, the methods getBigIntegerValue(Exact) and getBigDecimalValue would be excluded, NumberType should be INTEGER if the number can be exactly represented as a long, which is the largest integral type on such platforms.

          People

          • Assignee:
            jitu
            Reporter:
            jhorstmann
          • Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: