Float vs Double

Does Connect IQ actually support Double values? as far as I can see, the accuracy of all values seems to be limited to float, no matter how you declare them

Take the following code for example:

    var myval1 = 1.123456789123456789 as Double;
    var myval2 = 1.123456789123456789 as Float;
    var valString1 = myval1.toString();
    var valString2 = myval2.toString();
    System.println("Double = " + valString1 + "  Float = " + valString2);
The resulting output from this is:
Double = 1.123457 Float = 1.123457
Which would indicate to me that 'Double' is really just a Float...
  • - 1.123456789123456789 is a float literal, as is any numerical literal in the form x.y. You need to add the d suffix to make it a double: 1.123456789123456789d

    It would be nice if there were a compiler warning to tell you that your literal will lose precision because it's not specified as a double (or that the literal has too much precision even for a double), but there is none.

    - The casts "as Double" and "as Float" do nothing to affect the value / type of the casted values at runtime. The only serve to override the compile-time type checker's determination of casted values' types (just like TypeScript). I would avoid casts as much as possible, as they defeat the purpose of type checking and arguably give the dev a false sense of security. (e.g. it's possible to "cast away" a type error a compile-time, which could lead to a crash at runtime)

    - If you use Float/Double.toString() (or just concatenate a string with float or double, which has the same effect), you will get a default conversion with limited precision (6 decimal places). For additional precision, you need to use Float/Double.format()

    Test code:

    var doubleVal = 1.123456789123456789d;
    var floatVal = 1.123456789123456789;

    // doubleVal.toString() is implicitly called due to concatenation with a string
    System.println("doubleVal (toString) = " + doubleVal);
    // floatVal.toString() is implicitly called due to concatenation with a string

    System.println("floatVal (toString) = " + floatVal);

    System.println("doubleVal.format(\"%.20f\") = " + doubleVal.format("%.20f"));
    System.println("floatVal.format(\"%.20f\") = " + floatVal.format("%.20f"));

    // determine runtime types:
    System.println("doubleVal instanceof Double: " + (doubleVal instanceof Double));
    System.println("doubleVal instanceof Float: " + (doubleVal instanceof Float));
    System.println("floatVal instanceof Double: " + (floatVal instanceof Double));
    System.println("floatVal instanceof Float: " + (floatVal instanceof Float));

    Output:

    doubleVal (toString) = 1.123457
    floatVal (toString) = 1.123457
    doubleVal.format(\"%.20f\") = 1.12345678912345681155
    floatVal.format(\"%.20f\") = 1.12345683574676513672
    doubleVal instanceof Double: true

    doubleVal instanceof Float: false
    floatVal instanceof Double: false
    floatVal instanceof Float: true

  • Ah! Excellent, so there is a trick I missed then... thanks for that!

  • See https://developer.garmin.com/connect-iq/monkey-c/functions/

    "Declaring Variables"

    the "as Double" and "as Float" is only for the Type Checker.