Cannot transform JSON number value to ABL decimal value, JSO

Posted by Valeriy Bashkatov on 20-Nov-2017 03:15

Hi,

Our client encountered the problem of getting a Json array in which one element has a value in exponential form.

@Call to Progress.Json.ObjectModel.JsonObject:GetDecimal( ) failed. Cannot transform JSON number value to ABL decimal value, JSON value has an exponent. (16061)

We get this value in the code like this:

disk_share.face_value = (IF oTmpIt:Has("face_value") THEN oTmpIt:GetDecimal("face_value") ELSE 0)

Example of value:

"face_value": 6.25e-6,

We haven't found other than this:

IF oTmpIt:Has("face_value")
THEN DO:
      ASSIGN cStr = oTmpIt:GetJsonText("face_value").
      IF INDEX(cStr, "e") > 0
      THEN DO: 
            ASSIGN base = DECIMAL(SUBSTRING(cStr, 1, INDEX(cStr, "e") - 1))
            power = INTEGER(SUBSTRING(cStr, INDEX(cStr, "e") + 1 ))
            disk_bond.face_value = base * EXP(10, power). 
       END.
       ELSE ASSIGN disk_bond.face_value = oTmpIt:GetDecimal("face_value"). 
END.

This seems to work, but maybe in ABL (4GL) there is another more efficient way to do this with the built-in ABL functions?

Regards,
Valeriy

Posted by Valeriy Bashkatov on 21-Nov-2017 03:46
Posted by Valeriy Bashkatov on 20-Nov-2017 07:51

In PTS says that there no built-in functionality available in ABL  to convert exponential notation to decimal value, and offered to submit an idea for a Progress product enhancement.

All Replies

Posted by Mike Fechner on 20-Nov-2017 03:54

Sounds like an expected functional limitation (as Progress added a specific error message for this).
 
Which Progress Version have you tried this on?
Von: Valeriy Bashkatov [mailto:bounce-Arelav2@community.progress.com]
Gesendet: Montag, 20. November 2017 10:17
An: TU.OE.Development@community.progress.com
Betreff: [Technical Users - OE Development] Cannot transform JSON number value to ABL decimal value, JSON value has an exponent.
 
Update from Progress Community
 

Hi,

Our client encountered the problem of getting a Json array in which one element has a value in exponential form.

@Call to Progress.Json.ObjectModel.JsonObject:GetDecimal( ) failed. Cannot transform JSON number value to ABL decimal value, JSON value has an exponent. (16061)

We get this value in the code like this:

disk_share.face_value = (IF oTmpIt:Has("face_value") THEN oTmpIt:GetDecimal("face_value") ELSE 0)

Example of value:

"face_value": 6.25e-6,

We haven't found other than this:

IF oTmpIt:Has("face_value")
THEN DO:
      ASSIGN cStr = oTmpIt:GetJsonText("face_value").
      IF INDEX(cStr, "e") > 0
      THEN DO: 
            ASSIGN base = DECIMAL(SUBSTRING(cStr, 1, INDEX(cStr, "e") - 1))
            power = INTEGER(SUBSTRING(cStr, INDEX(cStr, "e") + 1 ))
            disk_bond.face_value = base * EXP(10, power). 
       END.
       ELSE ASSIGN disk_bond.face_value = oTmpIt:GetDecimal("face_value"). 
END.

This seems to work, but maybe in ABL (4GL) there is another more efficient way to do this with the built-in ABL functions?

Regards,
Valeriy

View online

 

You received this notification because you subscribed to the forum.  To stop receiving updates from only this thread, go here.

Flag this post as spam/abuse.

 

Posted by Valeriy Bashkatov on 20-Nov-2017 03:58

It is OE 11.7.2 on Windows.

update: 11.7.1

Posted by Mike Fechner on 20-Nov-2017 04:08

IMHO a documented bug as exponential number values are part of JSON.
 
 
I’d log it with tech support and see what they say.
Von: Valeriy Bashkatov [mailto:bounce-Arelav2@community.progress.com]
Gesendet: Montag, 20. November 2017 10:59
An: TU.OE.Development@community.progress.com
Betreff: RE: [Technical Users - OE Development] Cannot transform JSON number value to ABL decimal value, JSON value has an exponent.
 
Update from Progress Community
 

It is OE 11.7.2 on Windows.

View online

 

You received this notification because you subscribed to the forum.  To unsubscribe from only this thread, go here.

Flag this post as spam/abuse.

 

Posted by Valeriy Bashkatov on 20-Nov-2017 04:14

Thank you, Mike,

I'll do that.

Posted by Valeriy Bashkatov on 20-Nov-2017 07:51

In PTS says that there no built-in functionality available in ABL  to convert exponential notation to decimal value, and offered to submit an idea for a Progress product enhancement.

Posted by Peter Judge on 21-Nov-2017 04:55

I think that this should be a bug regardless.

We should handle exponent-numbers but if we won't then we should at lest let you figure out it's an exponential number and be able to deal with it cleanly, without explicitly trapping for the 16061 error.

Posted by WinningJr on 06-Jan-2018 10:06

I'm adding an "obvious manual workaround", just in case someone finds this thread and is hoping for a temp solution - get the value from the JSON as a character and parse it with .Net.

vDecimalValue = System.Decimal:Parse (<character value>, System.Globalization.NumberStyles:Any).

Posted by Peter Judge on 12-Jan-2018 09:59

Sadly that will only work on Windows.

I've added a version of Valeriy's code into the OpenEdge.Core.Util.MathUtil class that will be in the next releases. The code is below FYI.

    /* Keep the default in a readonly property - it is 10 */
    define static private property DEFAULT_BASE as integer initial 10 no-undo get.

    /** Converts an exponent (123e4) value into a decimal using a exponent
        base of 10.
        
        @param character The exponent value
        @param decimal The converted value  */
    method static public decimal ExponentialToDec(input pExpVal as character):
        return MathUtil:ExponentialToDec(pExpVal, DEFAULT_BASE).
    end method.
    
    /** Converts an exponent (123e4) value into a decimal.
        The format is
             nnn[.nnn]e[-]nnn
             <base>e<exponent>
        The <exponent> is raised as a power of the exponent-base.
        
        @param character The exponent value
        @param integer The exponent base. Must be a positive value (>0)
        @param decimal The converted value  */
    method static public decimal ExponentialToDec(input pExpVal as character,
                                                  input pBase as integer):
        define variable idx as integer no-undo.
        define variable decVal as decimal no-undo initial 0.00.
        define variable coefficient as decimal no-undo.
        define variable exponent as integer no-undo.
        
        if String:IsNullOrEmpty(pExpVal) then
            return decVal.
        Assert:IsPositive(pBase, 'Exponent base').
        
        assign idx = index(pExpVal, 'e':u).
        if idx eq 0 then
            assign decVal = decimal(pExpVal).
        else
            assign coefficient = decimal(substring(pExpVal, 1, idx - 1))
                   exponent    = integer(substring(pExpVal, idx + 1))
                   decVal      = coefficient * exp(pBase, exponent)
                   .
        return decVal.
    end method.

This thread is closed