diff --git a/src/app/app.component.ts b/src/app/app.component.ts
index f99d49adc5c600a890a1d883d2124ac2ec70a367..4f605afb85ab6124ef69fa46f496786499ca563f 100644
--- a/src/app/app.component.ts
+++ b/src/app/app.component.ts
@@ -177,6 +177,7 @@ export class AppComponent implements OnInit, OnDestroy, Observer {
   // cf. src/environments/*, ng build --env=<mode> (par ex : ng build --env=prod)
   private get ruler(): boolean {
     return !environment.production;
+    // return false;
   }
 
   // sidenav
@@ -194,5 +195,10 @@ export class AppComponent implements OnInit, OnDestroy, Observer {
     this.toList();
   }
 
+  private params() {
+    this.closeNav();
+    this.router.navigate(['/setup']);
+  }
+
   // sidenav
 }
diff --git a/src/app/app.module.ts b/src/app/app.module.ts
index 5acde2f69539b72daa318bb1f6554bdaadaec0cd..f435bcba1827aa0fdc3b40723bb1c661aa46d697 100644
--- a/src/app/app.module.ts
+++ b/src/app/app.module.ts
@@ -30,10 +30,13 @@ import { SectionCanvasComponent } from './components/section-canvas/section-canv
 import { RemousResultsComponent } from './components/remous-results/remous-results.component';
 import { LogComponent } from './components/log/log.component';
 import { CalculatorListComponent } from './components/calculator-list/calculator-list.component';
+import { ApplicationSetupComponent } from './components/app-setup/app-setup.component';
+import { BaseParamInputComponent } from './components/base-param-input/base-param-input.component';
 
 const appRoutes: Routes = [
   { path: 'list', component: CalculatorListComponent },
   { path: 'calculator/:uid', component: GenericCalculatorComponent },
+  { path: 'setup', component: ApplicationSetupComponent },
   { path: '**', component: CalculatorListComponent }
 ];
 
@@ -60,6 +63,8 @@ const appRoutes: Routes = [
     ParamFieldLineComponent, SelectFieldLineComponent, CheckFieldLineComponent,
     LogComponent,
     CalculatorListComponent,
+    ApplicationSetupComponent,
+    BaseParamInputComponent,
     GenericCalculatorComponent,
     // AlertDialog,
     CalculatorResultsComponent, FixedVarResultsComponent, SectionResultsComponent, RemousResultsComponent,
diff --git a/src/app/calculators/cond_distri/cond_distri.config.json b/src/app/calculators/cond_distri/cond_distri.config.json
index 52397b384f66d83719a4fd2bc6efbe1fba09fbaf..7001c739e621acc1fcff03831a498b02dc10cbef 100644
--- a/src/app/calculators/cond_distri/cond_distri.config.json
+++ b/src/app/calculators/cond_distri/cond_distri.config.json
@@ -42,8 +42,7 @@
             {
                 "type": "input",
                 "id": "Pr",
-                "unit": "m",
-                "value": 0.001
+                "unit": "m"
             }
         ]
     },
diff --git a/src/app/calculators/lechapt-calmon/lechapt-calmon.config.json b/src/app/calculators/lechapt-calmon/lechapt-calmon.config.json
index 77ce3598fb6a629352bca369f4490fb3481d7ea0..93498287d1e17dfe44c156229421046b76de07f0 100644
--- a/src/app/calculators/lechapt-calmon/lechapt-calmon.config.json
+++ b/src/app/calculators/lechapt-calmon/lechapt-calmon.config.json
@@ -231,8 +231,7 @@
             {
                 "type": "input",
                 "id": "Pr",
-                "unit": "m",
-                "value": 0.001
+                "unit": "m"
             }
         ]
     },
diff --git a/src/app/calculators/ouvrages/ouvrages.config.json b/src/app/calculators/ouvrages/ouvrages.config.json
index 1dcdb14cbca965dbda6a1aca1650dd59291691a0..fbb8930e7350651bd252ee9387e8c45bc869ad4e 100644
--- a/src/app/calculators/ouvrages/ouvrages.config.json
+++ b/src/app/calculators/ouvrages/ouvrages.config.json
@@ -227,8 +227,7 @@
             {
                 "type": "input",
                 "id": "Pr",
-                "unit": "m",
-                "value": 0.001
+                "unit": "m"
             }
         ]
     },
diff --git a/src/app/calculators/regime-uniforme/regime-uniforme.config.json b/src/app/calculators/regime-uniforme/regime-uniforme.config.json
index d8ff1194517e3c2f19d493423f962afd07348b8b..5434719eefd2976c3c293b37ed2de429a39da936 100644
--- a/src/app/calculators/regime-uniforme/regime-uniforme.config.json
+++ b/src/app/calculators/regime-uniforme/regime-uniforme.config.json
@@ -159,8 +159,7 @@
             {
                 "type": "input",
                 "id": "Pr",
-                "unit": "m",
-                "value": 0.001
+                "unit": "m"
             }
         ]
     },
diff --git a/src/app/calculators/remous/remous.config.json b/src/app/calculators/remous/remous.config.json
index 4399886be3622f0c1788f621805acbfeed054f84..4952eee19fbb6783b72013dd43d2cbf76956b355 100644
--- a/src/app/calculators/remous/remous.config.json
+++ b/src/app/calculators/remous/remous.config.json
@@ -177,8 +177,7 @@
             {
                 "type": "input",
                 "id": "Pr",
-                "unit": "m",
-                "value": 0.0001
+                "unit": "m"
             },
             {
                 "id": "select_resolution",
diff --git a/src/app/calculators/section-param/section-param.config.json b/src/app/calculators/section-param/section-param.config.json
index fa20969c327d9c6d5e477a32d8810f9359f3c8f3..53cb4e654c560f53e6dc71a43787d98bab0980f2 100644
--- a/src/app/calculators/section-param/section-param.config.json
+++ b/src/app/calculators/section-param/section-param.config.json
@@ -159,8 +159,7 @@
             {
                 "type": "input",
                 "id": "Pr",
-                "unit": "m",
-                "value": 0.001
+                "unit": "m"
             }
         ]
     },
diff --git a/src/app/components/app-setup/app-setup.component.html b/src/app/components/app-setup/app-setup.component.html
new file mode 100644
index 0000000000000000000000000000000000000000..e274b1f639830bd7e256fa89350c2f15ee38fd4d
--- /dev/null
+++ b/src/app/components/app-setup/app-setup.component.html
@@ -0,0 +1,22 @@
+<div class="container-fluid">
+    <div class="row">
+        <div class="col-4 mx-auto">
+            <h1>Paramètres de l'application</h1>
+            <br/>
+        </div>
+    </div>
+
+    <!-- précision d'affichage -->
+    <div class="row">
+        <div class="col-4 mx-auto">
+            <base-param-input title="Précision d'affichage" [param]="_displayPrec"></base-param-input>
+        </div>
+    </div>
+
+    <!-- précision de calcul -->
+    <div class="row">
+        <div class="col-4 mx-auto">
+            <base-param-input title="Précision de calcul" [param]="_computePrec"></base-param-input>
+        </div>
+    </div>
+</div>
\ No newline at end of file
diff --git a/src/app/components/app-setup/app-setup.component.ts b/src/app/components/app-setup/app-setup.component.ts
new file mode 100644
index 0000000000000000000000000000000000000000..9fc5f5784351ed2f1cbb5d6fdfa0f7eb58e4e2a5
--- /dev/null
+++ b/src/app/components/app-setup/app-setup.component.ts
@@ -0,0 +1,46 @@
+import { Component } from "@angular/core";
+
+import { BaseParam, ParamDomainValue } from "jalhyd";
+
+import { ApplicationSetupService } from '../../services/app-setup/app-setup.service';
+import { NgBaseParam } from "../base-param-input/base-param-input.component";
+import { Observer } from "../../services/observer";
+
+@Component({
+    selector: "setup",
+    templateUrl: "./app-setup.component.html",
+})
+export class ApplicationSetupComponent implements Observer {
+    /**
+     * précision d'affichage
+     */
+    private _displayPrec: NgBaseParam;
+
+    /**
+     * précision de calcul
+     */
+    private _computePrec: NgBaseParam;
+
+    constructor(private appSetupService: ApplicationSetupService) {
+        this._displayPrec = new NgBaseParam("dp", ParamDomainValue.NOT_NULL, this.appSetupService.displayPrecision);
+        this._displayPrec.addObserver(this);
+
+        this._computePrec = new NgBaseParam("cp", ParamDomainValue.NOT_NULL, this.appSetupService.computePrecision);
+        this._computePrec.addObserver(this);
+    }
+
+    // interface Observer
+
+    public update(sender: any, data: any): void {
+        const p: NgBaseParam = sender;
+        switch (p.symbol) {
+            case "dp":
+                this.appSetupService.displayPrecision = +data;
+                break;
+
+            case "cp":
+                this.appSetupService.computePrecision = +data;
+                break;
+        }
+    }
+}
diff --git a/src/app/components/base-param-input/base-param-input.component.html b/src/app/components/base-param-input/base-param-input.component.html
new file mode 100644
index 0000000000000000000000000000000000000000..2e1af91be2ee365ae2d2697b4adf14c634696f9a
--- /dev/null
+++ b/src/app/components/base-param-input/base-param-input.component.html
@@ -0,0 +1,5 @@
+<div class="md-form form-sm">
+    <input mdbActive type="text" id="form1" class="form-control" [ngModel]="_uiValue.uncheckedValueString" (ngModelChange)="setValue($event)">
+    <label for="form1">{{_title}}</label>
+    <small class="text-danger">{{_message}}</small>
+</div>
\ No newline at end of file
diff --git a/src/app/components/base-param-input/base-param-input.component.ts b/src/app/components/base-param-input/base-param-input.component.ts
new file mode 100644
index 0000000000000000000000000000000000000000..1006d13f3cd9462212e16af9712a7f0d241efa79
--- /dev/null
+++ b/src/app/components/base-param-input/base-param-input.component.ts
@@ -0,0 +1,218 @@
+// cf. https://blog.thoughtram.io/angular/2016/07/27/custom-form-controls-in-angular-2.html
+
+import { Component, Input, forwardRef, OnInit, DoCheck, ChangeDetectorRef } from "@angular/core";
+import { ControlValueAccessor, NG_VALUE_ACCESSOR, NG_VALIDATORS, FormControl } from "@angular/forms";
+
+import { BaseParam, NumericalString, Message, ParamDomain, ParamDomainValue } from "jalhyd";
+
+import { InternationalisationService, LanguageCode } from "../../services/internationalisation/internationalisation.service";
+import { Observable } from "../../services/observer";
+
+export class NgBaseParam extends Observable {
+    private _param: BaseParam;
+
+    constructor(symb: string, d: ParamDomain | ParamDomainValue, val: number) {
+        super();
+        this._param = new BaseParam(symb, d, val);
+    }
+
+    public get symbol() {
+        return this._param.symbol;
+    }
+
+    public get isDefined() {
+        return this._param.isDefined;
+    }
+
+    public getValue() {
+        return this._param.getValue();
+    }
+
+    public checkValue(val: number) {
+        return this._param.checkValue(val);
+    }
+
+    public setValue(val: number) {
+        this._param.setValue(val);
+        this.notifyObservers(val);
+    }
+}
+
+@Component({
+    selector: "base-param-input",
+    templateUrl: "./base-param-input.component.html",
+    providers: [
+        {
+            provide: NG_VALUE_ACCESSOR,
+            useExisting: forwardRef(() => BaseParamInputComponent),
+            multi: true
+        },
+        {
+            provide: NG_VALIDATORS,
+            useExisting: forwardRef(() => BaseParamInputComponent),
+            multi: true
+        }
+    ]
+})
+export class BaseParamInputComponent implements ControlValueAccessor, DoCheck {
+    /**
+     * enable/disable input field
+     */
+    @Input('inputDisabled')
+    private _inputDisabled: boolean;
+
+    /**
+     * managed parameter
+     */
+    @Input('param')
+    private _paramDef: NgBaseParam;
+
+    @Input('title')
+    private _title: string;
+
+    private _message: string;
+
+    /**
+     * flag d'affichage du titre
+     */
+    public displayTitle: boolean = false;
+
+    /**
+     * true si la modification du paramètre géré vient de l'interface utilisateur
+     * false si la modification du paramètre géré vient d'un appel du code
+     */
+    private _fromUI: boolean;
+
+    /**
+     * valeur dans le contrôle (saisie par l'utilisateur)
+     */
+    private _uiValue: NumericalString;
+
+    constructor(private changeDetector: ChangeDetectorRef, private intlService: InternationalisationService) {
+        this._uiValue = new NumericalString();
+    }
+
+    /**
+     * fonction appelée lorsque l'utilisateur fait une saisie
+     * @param event valeur du contrôle
+     */
+    private setValue(event: any) {
+        this._fromUI = true;
+        this._uiValue.value = event;
+        // this.log(this._uiValue.toString());
+        return this.validateUIValue();
+    }
+
+    /**
+     * fonction appelée lors d'un rafraîchissement de l'UI
+     */
+    ngDoCheck(): void {
+        // this.log("ngDoCheck start : " + this.getSParam() + this.getSUIvalue() + this.getSfromUI());
+
+        if (this._fromUI)
+            this.updateMessage(this._uiValue);
+        else {
+            if (this._paramDef.isDefined) {
+                this.updateMessage(new NumericalString(this._paramDef.getValue()));
+                this._uiValue.value = String(this._paramDef.getValue());
+            }
+            else
+                this.updateMessage(this._uiValue);
+        }
+
+        // this.log("ngDoCheck end : " + this.getSParam() + this.getSUIvalue());
+
+        this._fromUI = false;
+    }
+
+    private updateMessage(v: NumericalString) {
+        // this.log("updateMessage start :" + this.getSParam() + this.getSfromUI() + this.getSUIvalue(v) + "  message=" + this._message);
+
+        if (v.isNumerical) {
+            this._message = undefined;
+
+            try {
+                this._paramDef.checkValue(v.numericalValue);
+            }
+            catch (e) {
+                if (e instanceof Message)
+                    this._message = this.intlService.localizeMessage(e);
+                else
+                    this._message = "invalid value";
+            }
+        }
+        else {
+            switch (this.intlService.currentLanguage.code) {
+                case LanguageCode.FRENCH:
+                    this._message = "Veuillez entrer une valeur numérique";
+                    break;
+
+                default:
+                    this._message = "Please enter a numerical value";
+            }
+        }
+
+        // this.log("updateMessage end :" + this.getSParam() + this.getSfromUI() + this.getSUIvalue(v) + "  message=" + this._message);
+    }
+
+    private validateUIValue() {
+        // this.log("");
+        // this.log("validateValue start : val '" + this._uiValue.toString() + "'" + this.getSParam() + this.getSfromUI());
+
+        let ok: boolean = this._uiValue.isNumerical;
+        if (ok) {
+            try {
+                if (!this._paramDef.isDefined || this._paramDef.getValue() != this._uiValue.numericalValue) {
+                    this._paramDef.setValue(this._uiValue.numericalValue);
+                    this.changeDetector.detectChanges();  // provoque une détection des changements dans les contrôles
+                }
+            }
+            catch (e) {
+                ok = false;
+            }
+        }
+
+        if (!ok) {
+            // this.log("validateValue end : " + this.getSParam());
+
+            let err = {
+                rangeError: {
+                    // given: val,
+                    given: this._uiValue.toString(),
+                    max: 4,
+                    min: 0
+                }
+            };
+            return err;
+        }
+
+        // this.log("validateValue end : " + this.getSParam());
+        return null;
+    }
+
+    // private log(m: string) {
+    //     console.log("ParamInputComponent(" + this._id + ") : " + m);
+    // }
+
+    // ControlValueAccessor interface
+
+    propagateChange = (_: any) => { };
+
+    /*
+    //From ControlValueAccessor interface
+    writeValue(value: any) {
+        if (value !== this.innerValue) {
+            this.innerValue = value;
+        }
+    }
+    */
+    writeValue(value: any) {
+        // this.log("writeValue " + value);
+    }
+
+    registerOnChange(fn: any) {
+        this.propagateChange = fn;
+    }
+
+    registerOnTouched() { }
+}
diff --git a/src/app/formulaire/formulaire-definition.ts b/src/app/formulaire/formulaire-definition.ts
index 82771cde8dd5a788e7a4823fd796cc74587af03e..62d38b6d5b43d0a8a001b9a851378af990b32b11 100644
--- a/src/app/formulaire/formulaire-definition.ts
+++ b/src/app/formulaire/formulaire-definition.ts
@@ -5,6 +5,7 @@ import { ConduiteDistrib, ConduiteDistribParams, LechaptCalmon, LechaptCalmonPar
 
 import { ParamService } from "../services/param/param.service";
 import { InternationalisationService } from "../services/internationalisation/internationalisation.service";
+import { ApplicationSetupService } from "../services/app-setup/app-setup.service";
 import { Field } from "./field";
 import { NgParameter, ParamRadioConfig } from "./ngparam";
 import { InputField } from "./input-field";
@@ -76,7 +77,8 @@ export class FormulaireDefinition {
     constructor(
         private _calcType: CalculatorType,
         private paramService: ParamService,
-        private intlService: InternationalisationService
+        private intlService: InternationalisationService,
+        private appSetupService: ApplicationSetupService
     ) {
         this._uid = FormulaireDefinition.uidGenerator();
         this._fixVarResults = new FixedVarResults();
@@ -497,7 +499,10 @@ export class FormulaireDefinition {
             throw "pas de paramètre '" + input_id + "' trouvé dans le noeud " + ComputeNodeType[node_type] + "(" + node_type + ") ou " + ComputeNodeType[this._defaultNodeType] + "(" + this._defaultNodeType + ")";
 
         res.unit = field["unit"];
-        let val = field["value"];
+        if (input_id == "Pr")
+            var val = this.appSetupService.computePrecision;
+        else
+            val = field["value"];
         if (val != undefined)
             res.setValue(+val);
         res.radioConfig = NgParameter.getRadioConfig(fieldset["option"]);
diff --git a/src/app/services/app-setup/app-setup.service.ts b/src/app/services/app-setup/app-setup.service.ts
index 25a9f8d70bf706161f9e0d45bdc293695841c0b8..caa5df91346f31d8a16d4d52d7f9416622ad8bd8 100644
--- a/src/app/services/app-setup/app-setup.service.ts
+++ b/src/app/services/app-setup/app-setup.service.ts
@@ -16,6 +16,10 @@ export class ApplicationSetupService {
         return this._displayPrecision;
     }
 
+    public set displayPrecision(p: number) {
+        this._displayPrecision = p;
+    }
+
     public get displayDigits() {
         return -Math.log10(this._displayPrecision);
     }
@@ -23,4 +27,8 @@ export class ApplicationSetupService {
     public get computePrecision() {
         return this._computePrecision;
     }
+
+    public set computePrecision(p: number) {
+        this._computePrecision = p;
+    }
 }
diff --git a/src/app/services/formulaire/formulaire.service.ts b/src/app/services/formulaire/formulaire.service.ts
index 1b833bc14e79d4960f03fa567103a79d792b4e15..5451adbefdb7c577dd5335fd9c698f30b514bab7 100644
--- a/src/app/services/formulaire/formulaire.service.ts
+++ b/src/app/services/formulaire/formulaire.service.ts
@@ -6,6 +6,7 @@ import "rxjs/add/operator/toPromise";
 import { ParamService } from "../param/param.service";
 import { HttpService } from "../../services/http/http.service";
 import { InternationalisationService } from "../../services/internationalisation/internationalisation.service";
+import { ApplicationSetupService } from "../../services/app-setup/app-setup.service";
 import { FormulaireDefinition, CalculatorType } from "../../formulaire/formulaire-definition";
 import { FormulaireElement } from "../../formulaire/formulaire-element";
 import { InputField } from "../../formulaire/input-field";
@@ -23,7 +24,8 @@ export class FormulaireService extends Observable {
 
     constructor(private paramService: ParamService,
         private httpService: HttpService,
-        private intlService: InternationalisationService
+        private intlService: InternationalisationService,
+        private appSetupService: ApplicationSetupService
     ) {
         super();
         this._formulaires = [];
@@ -92,7 +94,7 @@ export class FormulaireService extends Observable {
         if (ct == undefined)
             throw "FormulaireService.createFormulaire() : invalid undefined CalculatorType"
 
-        let f = new FormulaireDefinition(ct, this.paramService, this.intlService);
+        let f = new FormulaireDefinition(ct, this.paramService, this.intlService, this.appSetupService);
         this._formulaires.push(f);
         let prom: Promise<Response> = this.loadConfig(f, ct);
         return prom.then(_ => {