Repository: common-workflow-language/cwltool

Issue:
very small numbers get turned into scientific notation on the command line
From: https://github.com/nfdi4plants/nf-core-pipeline-to-arc/issues/9

---

## Expected Behavior
`type: float` of `0.00001` or smaller are still represented as normal numbers (`0.00001`) on the command line

## Actual Behavior
It is serialized using scientific notation `1e-05`

## Workflow Code
``` yaml
cwlVersion: v1.0
class: CommandLineTool
baseCommand: echo
inputs:
 annotation_prokka_evalue:
   type: float?
   default: 0.00001
   inputBinding: {}

outputs: []
```

## Full Traceback
```
INFO /home/michael/cwltool/env3.11/bin/cwltool 3.1
INFO Resolved 'too-small-test.cwl' to 'file:///home/michael/cwltool/too-small-test.cwl'
DEBUG Parsed job order from command line: {
    "id": "too-small-test.cwl",
    "annotation_prokka_evalue": 1e-05
}
DEBUG [job too-small-test.cwl] initializing from file:///home/michael/cwltool/too-small-test.cwl
DEBUG [job too-small-test.cwl] {
    "annotation_prokka_evalue": 1e-05
}
DEBUG [job too-small-test.cwl] path mappings is {}
DEBUG [job too-small-test.cwl] command line bindings is [
    {
        "position": [
            -1000000,
            0
        ],
        "datum": "echo"
    },
    {
        "position": [
            0,
            "annotation_prokka_evalue"
        ],
        "datum": 1e-05
    }
]
DEBUG [job too-small-test.cwl] initial work dir {}
INFO [job too-small-test.cwl] /tmp/uq2p3kdl$ echo \
    1e-05
1e-05
DEBUG Could not collect memory usage, job ended before monitoring began.
INFO [job too-small-test.cwl] completed success
DEBUG [job too-small-test.cwl] outputs {}
DEBUG [job too-small-test.cwl] Removing input staging directory /tmp/e11ug6hl
DEBUG [job too-small-test.cwl] Removing temporary directory /tmp/yk8r4ib_
DEBUG Removing intermediate output directory /tmp/uq2p3kdl
{}INFO Final process status is success

```




Discussion:

Resolving patch:
diff --git a/cwltool/builder.py b/cwltool/builder.py
--- a/cwltool/builder.py
+++ b/cwltool/builder.py
@@ -2,7 +2,8 @@
 import copy
 import logging
 import math
-from typing import (  # pylint: disable=unused-import
+from decimal import Decimal
+from typing import (
     IO,
     TYPE_CHECKING,
     Any,
@@ -28,6 +29,8 @@
 from schema_salad.validate import validate
 
 from ruamel.yaml.comments import CommentedMap
+from ruamel.yaml.representer import RoundTripRepresenter
+from ruamel.yaml.scalarfloat import ScalarFloat
 
 from .errors import WorkflowException
 from .loghandler import _logger
@@ -604,6 +607,12 @@ def tostr(self, value: Union[MutableMapping[str, str], Any]) -> str:
                     '{} object missing "path": {}'.format(value["class"], value)
                 )
             return value["path"]
+        elif isinstance(value, ScalarFloat):
+            rep = RoundTripRepresenter()
+            dec_value = Decimal(rep.represent_scalar_float(value).value)
+            if "E" in str(dec_value):
+                return str(dec_value.quantize(1))
+            return str(dec_value)
         else:
             return str(value)
 


Test patch:
diff --git a/tests/test_examples.py b/tests/test_examples.py
--- a/tests/test_examples.py
+++ b/tests/test_examples.py
@@ -1829,3 +1829,14 @@ def test_res_req_expr_float_1_2() -> None:
     assert exit_code == 0, stderr
     assert json.loads(stdout)["result"]["outdirSize"] >= 708
     assert json.loads(stdout)["result"]["tmpdirSize"] >= 708
+
+
+def test_very_small_and_large_floats() -> None:
+    """Confirm that very small or large numbers are not transformed into scientific notation."""
+    exit_code, stdout, stderr = get_main_output(
+        [
+            get_data("tests/wf/floats_small_and_large.cwl"),
+        ]
+    )
+    assert exit_code == 0, stderr
+    assert json.loads(stdout)["result"] == "0.00001 0.0000123 123000 1230000"
diff --git a/tests/wf/floats_small_and_large.cwl b/tests/wf/floats_small_and_large.cwl
new file mode 100644
--- /dev/null
+++ b/tests/wf/floats_small_and_large.cwl
@@ -0,0 +1,39 @@
+cwlVersion: v1.0
+class: CommandLineTool
+baseCommand: echo
+requirements:
+  InlineJavascriptRequirement: {}
+
+inputs:
+ annotation_prokka_evalue:
+   type: float
+   default: 0.00001
+   inputBinding: {}
+
+ annotation_prokka_evalue2:
+   type: float
+   default: 1.23e-05
+   inputBinding: {}
+
+ annotation_prokka_evalue3:
+   type: float
+   default: 1.23e5
+   inputBinding: {}
+
+ annotation_prokka_evalue4:
+   type: float
+   default: 1230000
+   inputBinding: {}
+
+
+arguments: [ -n ]
+
+stdout: dump
+
+outputs:
+  result:
+    type: string
+    outputBinding:
+      glob: dump
+      loadContents: true
+      outputEval: $(self[0].contents)