# Fehler in Fact

**URL:** <https://oscat.discourse.group/t/fehler-in-fact/1023>\
**Category:** Bestehende Module / Existing Modules\
**Created:** [15. März 2011 um 19:56 UTC](https://oscat.discourse.group/t/fehler-in-fact/1023 "2011-03-15T19:56:18Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![system](https://global.discourse-cdn.com/free1/uploads/oscat/original/1X/2efdfb9c592ff9a666c94dff124ee84fa863dae5.jpeg) [@system](https://oscat.discourse.group/u/system)\
**Post date:** [15. März 2011 um 19:56 UTC](https://oscat.discourse.group/t/fehler-in-fact/1023/1 "2011-03-15T19:56:18Z")

</div>

Hallo,

der Baustein FACT liefert für 13 einen falschen Wert zurück.  
Richtig wäre 6227020800, das ist aber mit DINT nicht darstellbar, deswegen wird 1932053504 zurückgeliefert.  
Außerdem liefert FACT für negative Werte nicht -1 zurück, sondern die Fakultät des positiven Wertes.

Wäre es nicht effektiver, die Werte vorzuberechnen und mittels CASE auszuwählen?

CASE x OF  
0: fact := 1;  
1: fact := 1;  
2: fact := 2;  
3: fact := 6;  
4: fact := 24;  
5: fact := 120;  
6: fact := 720;  
7: fact := 5040;  
8: fact := 40320;  
9: fact := 362880;  
10: fact := 3628800;  
11: fact := 39916800;  
12: fact := 479001600;  
(\* für 64Bit-Werte  
13: fact := 6227020800;  
14: fact := 87178291200;  
15: fact := 1307674368000;  
16: fact := 20922789888000;  
17: fact := 355687428096000;  
18: fact := 6402373705728000;  
19: fact := 121645100408832000;  
20: fact := 2432902008176640000;  
\*)  
ELSE  
fact\_ad := -1;  
END\_CASE

---

<div class="post-metadata">

**Author:** ![hugo](https://yyz2.discourse-cdn.com/free1/user_avatar/oscat.discourse.group/hugo/32/133_2.png) [@hugo](https://oscat.discourse.group/u/hugo)\
**Post date:** [15. März 2011 um 20:54 UTC](https://oscat.discourse.group/t/fehler-in-fact/1023/2 "2011-03-15T20:54:00Z")

</div>

den ferhler mit 13 werden wir prüfen,  
allerdings -1 für negative werte ist schlichtweg falsch, fakultät für negative werte ist nicht definiert und deshalb ist auch die antwort -1 falsch.  
das wäre geleichbedeutend als für 34/0 eione -1 zurückzuliefern.

wie bei jeder mathematischen funktion muss der programmierer den wertebereich einhalten.

---

<div class="post-metadata">

**Author:** ![system](https://global.discourse-cdn.com/free1/uploads/oscat/original/1X/2efdfb9c592ff9a666c94dff124ee84fa863dae5.jpeg) [@system](https://oscat.discourse.group/u/system)\
**Post date:** [16. März 2011 um 19:01 UTC](https://oscat.discourse.group/t/fehler-in-fact/1023/3 "2011-03-16T19:01:42Z")

</div>

Hmmm, wenn man die Werte in ein Array packt, dann hat man das Problem mit den negativen Werten nicht.  
Vorberechnen kann man di dann auch:

Deklaration:  
werte : ARRAY[0..12] OF DINT :=1,1,2,6,24,120,720,5040,40320,362880,3628800,39916800,479001600;

Implementation:  
IF X \> 12 THEN  
Fact := -1;  
ELSE  
Fact := werte;  
END\_IF

---

<div class="post-metadata">

**Author:** ![hugo](https://yyz2.discourse-cdn.com/free1/user_avatar/oscat.discourse.group/hugo/32/133_2.png) [@hugo](https://oscat.discourse.group/u/hugo)\
**Post date:** [18. März 2011 um 11:16 UTC](https://oscat.discourse.group/t/fehler-in-fact/1023/4 "2011-03-18T11:16:38Z")

</div>

die fact von 13 haben wir ausgeschlossen, den sie übersteigt den wertebereich von dint.  
die lösung mittels array sieht zwar super aus, ist aber bedeutend langsamer weil bei jedem asufruf das ganze array auf den stack kopiert werden muss  
in release 332 wird der fehler korrigiert

---

<div class="post-metadata">

**Author:** ![system](https://global.discourse-cdn.com/free1/uploads/oscat/original/1X/2efdfb9c592ff9a666c94dff124ee84fa863dae5.jpeg) [@system](https://oscat.discourse.group/u/system)\
**Post date:** [24. März 2011 um 19:48 UTC](https://oscat.discourse.group/t/fehler-in-fact/1023/5 "2011-03-24T19:48:04Z")

</div>

Hallo,

wenn man das Array in die Struktur CONSTANTS\_MATH aufnimmt, dann wird es einmal global angelegt und nicht jedesmal in den Stack kopiert werden.

---

<div class="post-metadata">

**Author:** ![hugo](https://yyz2.discourse-cdn.com/free1/user_avatar/oscat.discourse.group/hugo/32/133_2.png) [@hugo](https://oscat.discourse.group/u/hugo)\
**Post date:** [25. März 2011 um 05:49 UTC](https://oscat.discourse.group/t/fehler-in-fact/1023/6 "2011-03-25T05:49:54Z")

</div>

richtig das werde ich mir nochmal ansehen

---

<div class="post-metadata">

**Author:** ![hugo](https://yyz2.discourse-cdn.com/free1/user_avatar/oscat.discourse.group/hugo/32/133_2.png) [@hugo](https://oscat.discourse.group/u/hugo)\
**Post date:** [26. März 2011 um 06:05 UTC](https://oscat.discourse.group/t/fehler-in-fact/1023/7 "2011-03-26T06:05:41Z")

</div>

fact mittels array ist ca doppelt so schnell, habe ich entsprechend realisiert
