[Info-vax] openvms and xterm

Arne Vajhøj arne at vajhoej.dk
Wed Apr 24 20:36:39 EDT 2024


On 4/24/2024 8:27 PM, Arne Vajhøj wrote:
> Let us see some code.
> 
> I picked Groovy as demo language, because I am a J guy
> and Groovy allows to demo a lot.
> 
> As a JVM language there are several possible data types to
> pick from:
>    int
>    long
>    double
>    String
>    BigInteger
>    BigDecimal
> 
> And obviously int and double has problem with 100000000000000001
> while the rest can store it OK.
> 
> To illustrate the option of different JSON libraries I will
> test with both GSON (Google JSON library) and Jackson (probably
> the most widely used JSON library in the Java wold).
> 
> Let us first look at the model where the JSON is parsed to
> a tree.

> We see:
> * the expected slightly off value for double
> * the crazy value for int (no exception)
> * other data types are fine
> 
> Now mapping/binding to class.

> Very similar behavior except that now I do get the exception for
> int that I so much prefer.

All that is of course if one bother to pick the data type.

Otherwise the result become a bit more implementation
specific.

GSON:

$ type Data3.groovy
import com.google.gson.*

class C1 {
     def v = 0
}

class C2 {
     def v = 0.0d
}

class C3 {
     def v = 0.0
}

class C4 {
     def v
}

def wrap(block) {
     try {
         block()
     } catch(ex) {
         printf("%s: %s\n", ex.class.name, ex.message)
     }
}

json = '{ "v": 100000000000000001 }'
println(json)
gson = new Gson()
wrap {
     C1 v1 = gson.fromJson(json, C1.class)
     printf("def = 0: %f (%s)\n", v1.v, v1.v.class.name)
}
wrap {
     C2 v2 = gson.fromJson(json, C2.class)
     printf("def = 0.0d: %f (%s)\n", v2.v, v2.v.class.name)
}
wrap {
     C3 v3 = gson.fromJson(json, C3.class)
     printf("def = 0.0: %f (%s)\n", v3.v, v3.v.class.name)
}
wrap {
     C4 v4 = gson.fromJson(json, C4.class)
     printf("def: %f (%s)\n", v4.v, v4.v.class.name)
}
$ groovy Data3.groovy
{ "v": 100000000000000001 }
def = 0: 100000000000000000.000000 (java.lang.Double)
def = 0.0d: 100000000000000000.000000 (java.lang.Double)
def = 0.0: 100000000000000000.000000 (java.lang.Double)
def: 100000000000000000.000000 (java.lang.Double)

Jackson:

$ type Data3X.groovy
import com.fasterxml.jackson.databind.*

class C1 {
     def v = 0
}

class C2 {
     def v = 0.0d
}

class C3 {
     def v = 0.0
}

class C4 {
     def v
}

def wrap(block) {
     try {
         block()
     } catch(ex) {
         printf("%s: %s\n", ex.class.name, ex.message)
     }
}

json = '{ "v": 100000000000000001 }'
println(json)
om = new ObjectMapper()
wrap {
     C1 v1 = om.readValue(json, C1.class)
     printf("def = 0: %d (%s)\n", v1.v, v1.v.class.name)
}
wrap {
     C2 v2 = om.readValue(json, C2.class)
     printf("def = 0.0d: %d (%s)\n", v2.v, v2.v.class.name)
}
wrap {
     C3 v3 = om.readValue(json, C3.class)
     printf("def = 0.0: %d (%s)\n", v3.v, v3.v.class.name)
}
wrap {
     C4 v4 = om.readValue(json, C4.class)
     printf("def: %d (%s)\n", v4.v, v4.v.class.name)
}
$ groovy Data3X.groovy
{ "v": 100000000000000001 }
def = 0: 100000000000000001 (java.lang.Long)
def = 0.0d: 100000000000000001 (java.lang.Long)
def = 0.0: 100000000000000001 (java.lang.Long)
def: 100000000000000001 (java.lang.Long)

GSON picked a "bad" data type (Double) while
Jackson picked a "good" data type (Long).

Groovy is in no way a typical dynamic typed
language, but I still think it sort of show that
JSON parsing may be a case where one really should
prefer static typing.

Arne






More information about the Info-vax mailing list