From 939b365c708218f620814f316a696544da447c7e Mon Sep 17 00:00:00 2001 From: "mathias.chouet" <mathias.chouet@irstea.fr> Date: Thu, 16 May 2019 11:48:53 +0200 Subject: [PATCH] Fix #90 - PAB : nombre add function isEqual to compare real numbers fix integer division / modulo update jasmine test --- spec/pab/pab_nombre.spec.ts | 29 ++++++++++++++++++++++++++++- src/base.ts | 35 +++++++++++++++++++++++++++++++++++ src/pab/pab_nombre.ts | 14 +++++++++++--- src/util/message.ts | 5 +++++ 4 files changed, 79 insertions(+), 4 deletions(-) diff --git a/spec/pab/pab_nombre.spec.ts b/spec/pab/pab_nombre.spec.ts index fb5d9619..322fb2f7 100644 --- a/spec/pab/pab_nombre.spec.ts +++ b/spec/pab/pab_nombre.spec.ts @@ -28,13 +28,40 @@ describe("Class PabNombre: ", () => { it ("DHR should be 0.3", () => { const prms = new PabNombreParams( 7.5, // Chute totale DHT - 9, // Nombre de bassins N + 666, // Nombre de bassins N 0.8, // Chute entre bassins DH ); const nub = new PabNombre(prms); nub.Calc("N", 0); + expect(nub.result.vCalc).toBe(9); expect(nub.result.getExtraResult("DHR")).toBeCloseTo(0.3); }); + + it ("DHR should be 0", () => { + const prms = new PabNombreParams( + 3, // Chute totale DHT + 666, // Nombre de bassins N + 0.2, // Chute entre bassins DH + ); + + const nub = new PabNombre(prms); + + nub.Calc("N", 0); + expect(nub.result.vCalc).toBe(15); + expect(nub.result.getExtraResult("DHR")).toBe(0); + }); + + it ("non-integer number of basins should throw an error", () => { + const prms = new PabNombreParams( + 3, // Chute totale DHT + 4.5, // Nombre de bassins N + 0.2, // Chute entre bassins DH + ); + + const nub = new PabNombre(prms); + + expect(nub.Calc("DH", 0).log.messages.length).toBeGreaterThan(0); + }); }); diff --git a/src/base.ts b/src/base.ts index be98cf9a..40c54156 100644 --- a/src/base.ts +++ b/src/base.ts @@ -63,3 +63,38 @@ export function isNumeric(s: string): boolean { } return false; } + +/** + * Retourne true si a et b sont égaux à e près (en gros) + */ +export function isEqual(a: number, b: number, e: number = 1E-7): boolean { + if (a === 0 && b === 0) { + return true; + } + if (b === 0) { // ne pas diviser par 0 + [ a, b ] = [ b, a ]; + } + if (a === 0) { // éviter d'avoir un quotient toujours nul + return (Math.abs(b) < e); + } + // cas général + return (Math.abs((a / b) - 1) < e); +} + +/** + * Division entière de a par b, plus modulo, avec une tolérance e + * pour gérer le cas des nombres réels + */ +export function floatDivAndMod(a: number, b: number, e: number = 1E-7): { q: number, r: number } { + let q = Math.floor(a / b); + let r = a % b; + // si le modulo est bon à un pouïème, pas de reste + if (isEqual(r, b)) { + r = 0; + // si la division entière n'est pas tombée juste, +1 au quotient + if (q !== (a / b)) { + q++; + } + } + return { q, r }; +} diff --git a/src/pab/pab_nombre.ts b/src/pab/pab_nombre.ts index a853df31..d0fa32b5 100644 --- a/src/pab/pab_nombre.ts +++ b/src/pab/pab_nombre.ts @@ -1,8 +1,10 @@ +import { floatDivAndMod } from "../base"; import { CalculatorType } from "../compute-node"; import { Nub } from "../nub"; import { ParamCalculability, ParamDefinition, ParamFamily } from "../param/param-definition"; import { ParamDomainValue } from "../param/param-domain"; import { ParamsEquation } from "../param/params-equation"; +import { Message, MessageCode } from "../util/message"; import { Result } from "../util/result"; export class PabNombreParams extends ParamsEquation { @@ -58,6 +60,12 @@ export class PabNombre extends Nub { } public Equation(sVarCalc: string): Result { + if (sVarCalc !== "N" && ! Number.isInteger(this.prms.N.singleValue)) { + const m = new Message(MessageCode.ERROR_PARAMDEF_VALUE_INTEGER); + m.extraVar.N = this.prms.N.singleValue; + return new Result(m); + } + let v: number; let DHR = 0; @@ -67,8 +75,9 @@ export class PabNombre extends Nub { break; case "N": - v = Math.floor(this.prms.DHT.v / this.prms.DH.v); - DHR = this.prms.DHT.v % this.prms.DH.v; + const divAndMod = floatDivAndMod(this.prms.DHT.v, this.prms.DH.v); + v = divAndMod.q; + DHR = divAndMod.r; break; case "DH": @@ -99,5 +108,4 @@ export class PabNombre extends Nub { DHR: ParamFamily.HEIGHTS }; } - } diff --git a/src/util/message.ts b/src/util/message.ts index cd5b6e39..d5f4cacb 100644 --- a/src/util/message.ts +++ b/src/util/message.ts @@ -73,6 +73,11 @@ export enum MessageCode { */ ERROR_PARAMDEF_VALUE_FIXED, + /** + * la valeur d'un ParamDefinition doit être entière + */ + ERROR_PARAMDEF_VALUE_INTEGER, + /** * la valeur d'un ParamDefinition doit être > 0 */ -- GitLab