From f88c704d69928c2a33473e6abae30e5973cc11b5 Mon Sep 17 00:00:00 2001 From: Beka Westberg Date: Mon, 15 Apr 2019 13:26:20 -0700 Subject: [PATCH] Fixed visible floating point errors in number fields. (#2384) --- core/field_number.js | 11 +++++++--- tests/blocks/test_blocks.js | 40 ++++++++++++++++++++++++++++++++----- tests/playground.html | 10 ++++++++-- 3 files changed, 51 insertions(+), 10 deletions(-) diff --git a/core/field_number.js b/core/field_number.js index 7d4cf2759..c9f75215a 100644 --- a/core/field_number.js +++ b/core/field_number.js @@ -79,6 +79,10 @@ Blockly.FieldNumber.fromJson = function(options) { Blockly.FieldNumber.prototype.setConstraints = function(min, max, precision) { precision = parseFloat(precision); this.precision_ = isNaN(precision) ? 0 : precision; + var precisionString = this.precision_.toString(); + var decimalIndex = precisionString.indexOf('.'); + this.fractionalDigits_ = (decimalIndex == -1) ? -1 : + precisionString.length - (decimalIndex + 1); min = parseFloat(min); this.min_ = isNaN(min) ? -Infinity : min; max = parseFloat(max); @@ -106,13 +110,14 @@ Blockly.FieldNumber.prototype.classValidator = function(text) { // Invalid number. return null; } + // Get the value in range. + n = Math.min(Math.max(n, this.min_), this.max_); // Round to nearest multiple of precision. if (this.precision_ && isFinite(n)) { n = Math.round(n / this.precision_) * this.precision_; } - // Get the value in range. - n = Math.min(Math.max(n, this.min_), this.max_); - return String(n); + return (this.fractionalDigits_ == -1) ? String(n) : + n.toFixed(this.fractionalDigits_); }; Blockly.Field.register('field_number', Blockly.FieldNumber); diff --git a/tests/blocks/test_blocks.js b/tests/blocks/test_blocks.js index 5b3da54fe..e3e473415 100644 --- a/tests/blocks/test_blocks.js +++ b/tests/blocks/test_blocks.js @@ -207,8 +207,8 @@ Blockly.defineBlocksWithJsonArray([ // BEGIN JSON EXTRACT "tooltip": "A number." }, { - "type": "test_fields_integer", - "message0": "integer %1", + "type": "test_fields_number_whole", + "message0": "precision 1 %1", "args0": [ { "type": "field_number", @@ -219,11 +219,11 @@ Blockly.defineBlocksWithJsonArray([ // BEGIN JSON EXTRACT ], "style": "math_blocks", "output": "Number", - "tooltip": "An integer." + "tooltip": "The number should be rounded to multiples of 1" }, { "type": "test_fields_number_hundredths", - "message0": "$ %1", + "message0": "precision 0.01 %1", "args0": [ { "type": "field_number", @@ -234,7 +234,37 @@ Blockly.defineBlocksWithJsonArray([ // BEGIN JSON EXTRACT ], "style": "math_blocks", "output": "Number", - "tooltip": "A dollar amount." + "tooltip": "The number should be rounded to multiples of 0.01" + }, + { + "type": "test_fields_number_halves", + "message0": "precision 0.5 %1", + "args0": [ + { + "type": "field_number", + "name": "NUM", + "precision": 0.5, + "text": "0" + } + ], + "style": "math_blocks", + "output": "Number", + "tooltip": "The number should be rounded to multiples of 0.5" + }, + { + "type": "test_fields_number_three_halves", + "message0": "precision 1.5 %1", + "args0": [ + { + "type": "field_number", + "name": "NUM", + "precision": 1.5, + "text": "0" + } + ], + "style": "math_blocks", + "output": "Number", + "tooltip": "The number should be rounded to multiples of 1.5" }, { "type": "test_fields_integer_bounded", diff --git a/tests/playground.html b/tests/playground.html index e961c49e5..680b9fb2d 100644 --- a/tests/playground.html +++ b/tests/playground.html @@ -1197,10 +1197,16 @@ h1 { 123.456 - + 123.456 - + + 123.456 + + + 123.456 + + 123.456