/**
* @copyright 2015 Tridium, Inc. All Rights Reserved.
* @author Gareth Johnson
*/
/**
* Defines {@link baja.Float}.
* @module baja/obj/Float
*/
define([ 'bajaScript/sys',
'bajaScript/baja/obj/numberUtil',
'bajaScript/baja/obj/objUtil',
'bajaScript/baja/obj/Simple' ], function (
baja,
numberUtil,
objUtil,
Simple) {
'use strict';
var subclass = baja.subclass,
callSuper = baja.callSuper,
strictArg = baja.strictArg,
floatingPointToString = numberUtil.floatingPointToString,
cacheDecode = objUtil.cacheDecode,
cacheEncode = objUtil.cacheEncode,
uncacheConstantEncodeDecode = objUtil.uncacheConstantEncodeDecode;
/**
* Represents a `baja:Float` in BajaScript.
*
* Boxes JavaScript `Number` to represent a `baja:Float`.
*
* When creating a `Simple`, always use the `make()` method instead of
* creating a new Object.
*
* @class
* @alias baja.Float
* @extends baja.Simple
*/
var Float = function Float(val) {
callSuper(Float, this, arguments);
this.$val = strictArg(val, Number);
};
subclass(Float, Simple);
/**
* Make a `Float`.
*
* @param {Number} val - the number value.
*
* @returns {baja.Float}
*/
Float.make = function (val) {
if (val === 0) {
return Float.DEFAULT;
}
if (isNaN(val)) {
return Float.NaN;
}
if (val === Float.POSITIVE_INFINITY.valueOf()) {
return Float.POSITIVE_INFINITY;
}
if (val === Float.NEGATIVE_INFINITY.valueOf()) {
return Float.NEGATIVE_INFINITY;
}
if (val >= Float.MAX_VALUE.valueOf()) {
return Float.MAX_VALUE;
}
if (val > 0 && val <= Float.MIN_VALUE.valueOf()) {
return Float.MIN_VALUE;
}
return new Float(val);
};
/**
* Make a `Float`.
*
* @param {Number} val - the number value.
*
* @returns {baja.Float}
*/
Float.prototype.make = function (val) {
return Float.make(val);
};
/**
* Decode a `Float` from a `String`.
*
* @param {String} str - an encoded `Float`.
*
* @returns {baja.Float}
*/
Float.prototype.decodeFromString = function (str) {
switch (str) {
case "0": return Float.DEFAULT;
// Infinity and NaN
case "+inf": return Float.POSITIVE_INFINITY;
case "-inf": return Float.NEGATIVE_INFINITY;
case "nan": return Float.NaN;
default: return Float.make(parseFloat(str));
}
};
/**
* Encode the `Float` (itself) to a `String`.
*
* @returns {String}
*/
Float.prototype.encodeToString = function () {
// Infinity and NaN
if (this.$val === Number.POSITIVE_INFINITY) {
return "+inf";
}
if (this.$val === Number.NEGATIVE_INFINITY) {
return "-inf";
}
if (isNaN(this.$val)) {
return "nan";
}
// Check range limits
if (this.$val >= Float.MAX_VALUE.valueOf()) {
return Float.MAX_VALUE.valueOf().toString();
}
if (this.$val > 0 && this.$val <= Float.MIN_VALUE.valueOf()) {
return Float.MIN_VALUE.valueOf().toString();
}
return this.$val.toString();
};
/**
* Default `Float` instance.
* @type {baja.Float}
*/
Float.DEFAULT = uncacheConstantEncodeDecode(new Float(0));
/**
* `Float` Max Value.
* @type {baja.Float}
*/
Float.MAX_VALUE = uncacheConstantEncodeDecode(new Float(3.4028235E38));
/**
* `Float` Min Value.
* @type {baja.Float}
*/
Float.MIN_VALUE = uncacheConstantEncodeDecode(new Float(1.4E-45));
/**
* `Float` Positive Infinity.
* @type {baja.Float}
*/
Float.POSITIVE_INFINITY = uncacheConstantEncodeDecode(new Float(Number.POSITIVE_INFINITY));
/**
* `Float` Negative Infinity.
* @type {baja.Float}
*/
Float.NEGATIVE_INFINITY = uncacheConstantEncodeDecode(new Float(Number.NEGATIVE_INFINITY));
/**
* `Float` Not A Number.
* @type {baja.Float}
*/
Float.NaN = uncacheConstantEncodeDecode(new Float(Number.NaN));
Float.NAN = Float.NaN; // Here for customers that may be using 'NAN'
Float.prototype.decodeFromString = cacheDecode(Float.prototype.decodeFromString);
Float.prototype.encodeToString = cacheEncode(Float.prototype.encodeToString);
/**
* Return the data type symbol.
*
* Used for encoding this data type (primarily for facets).
*
* @returns {String}
*/
Float.prototype.getDataTypeSymbol = function () {
return "f";
};
/**
* Equality test.
*
* @param obj
*
* @returns {Boolean}
*/
Float.prototype.equals = function (obj) {
return objUtil.valueOfEquals(this, obj);
};
/**
* Return the `Number` encapsulated in the `Float` (itself).
*
* @returns {Number}
*/
Float.prototype.valueOf = function () {
return this.$val;
};
/**
* Return the `String` representation of the `Float` (itself).
*
* @param {baja.Facets|Object} [cx] - used to specify formatting facets. The
* argument can also be an Object Literal.
*
* @param {Boolean} [cx.forceSign] - specifying 'true' will concatenate a '+'
* to the beginning of the number if positive.
*
* @param {Number} [cx.precision] - the number of decimal places to show in
* the return string. Specifying '0' will also remove the decimal. If a context
* is provided without precision, this value will default to 2. If no context
* is provided, there will be no precision applied.
*
* @param {Boolean} [cx.showSeparators] - include separators.
*
* @param {baja.Unit} [cx.units] - the baja Unit to apply to the return
* string.
*
* @param {baja.Enum|Number|String} [cx.unitConversion] - the
* `baja:UnitConversion` enum, an ordinal, or tag.
*
* @param {Number} [cx.zeroPad] - the minimum number of the whole-number
* digits to be displayed, filling in zeroes when necessary.
*
* @param {boolean} [cx.trimTrailingZeros] - set to true if trailing zeros
* should not be included in the string. If the only digits after the decimal
* point are zeros, the decimal point will be removed as well.
*
* @returns {String|Promise.<String>} returns a Promise if a cx is passed in.
*/
Float.prototype.toString = function (cx) {
if (cx) {
if (cx instanceof baja.Facets) {
cx = cx.toObject();
}
return floatingPointToString(this, cx);
}
return this.encodeToString();
};
return Float;
});