UNPKG

@abaplint/runtime

Version:
103 lines 3.31 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Float = void 0; const hex_1 = require("./hex"); const xstring_1 = require("./xstring"); const integer8_1 = require("./integer8"); const decfloat34_1 = require("./decfloat34"); /* function getNumberParts(x: number) { if(isNaN(x)) { throw new Error("Float NaN"; } const sig = x > 0 ? 1 : -1; if (!isFinite(x)) { throw new Error("Float not finite"; } x = Math.abs(x); const exp = Math.floor(Math.log(x) * Math.LOG2E) - 52; const man = x / Math.pow(2, exp); return {mantissa: sig * man, exponent: exp}; } */ class Float { value; integerCalculationType = false; qualifiedName; constructor(input) { this.value = 0; this.qualifiedName = input?.qualifiedName; } clone() { const n = new Float({ qualifiedName: this.qualifiedName }); n.value = this.value; return n; } /** ABAP calculates in type i if all operands are integers, ie. "3 / 2" is 2. The exact value is * kept here, so assigning to a float or packed target, which raises the calculation type, still * gives the exact result. Consumers without a target type must use getCalculationValue() */ setIntegerCalculationType() { this.integerCalculationType = true; return this; } /** value as seen by the calculation type, ie. rounded if the calculation type is integer */ getCalculationValue() { if (this.integerCalculationType === true) { // ABAP rounds half away from zero return this.value < 0 ? -Math.round(-this.value) : Math.round(this.value); } return this.value; } getQualifiedName() { return this.qualifiedName; } set(value) { if (typeof value === "number") { this.value = value; } else if (typeof value === "string" && value.trim().length === 0) { this.value = 0; } else if (typeof value === "string") { this.value = parseFloat(value); } else if (value instanceof integer8_1.Integer8) { this.value = Number(value.get()); } else if (value instanceof Float || value instanceof decfloat34_1.DecFloat34) { this.value = value.getRaw(); } else if (value instanceof hex_1.Hex || value instanceof xstring_1.XString) { // todo, how/if should this work? this.set(parseInt(value.get(), 16)); } else { this.set(value.get()); } return this; } clear() { this.value = 0; } getRaw() { return this.value; } get() { let text = new Number(this.value).toExponential(16); text = text.replace(".", ","); if (text.includes("e+")) { const split = text.split("e+"); const mantissa = split[0]; const exponent = split[1].padStart(2, "0"); return mantissa + "E+" + exponent; } else { const split = text.split("e-"); const mantissa = split[0]; const exponent = split[1].padStart(2, "0"); return mantissa + "E-" + exponent; } } } exports.Float = Float; //# sourceMappingURL=float.js.map