oscat.lib > oscat.lib fuer Step 7
Arithmetik doppelter Genauigkeit
Langnese:
Hallo,
das habe ich gemacht:
CALL "R2_ADD"
X :="Test".Ergebnis
Y :=MD54
RET_VAL:="Test".Ergebnis
und Test.Ergebnis mit der Funktion R2_SET einmalig auf 3.6 E07 gesetzt.
Jetzt ist das Verhalten anders, in Test.Ergebnis.R1 wird pro Zyklus die in MD54 stehenden 1.0E-05 dazuaddiert. Das sieht schon gut aus, aber wenn die Zahl bei ca 1.8 E00 ankommt, wird das Ergebnis plötzlich negativ und es wird von -1,8 wieder auf 1,8 hochgezählt.
Gruß
Peter
e3:
Hi,
ich möchte das Thema noch mal aufgreifen.
Den die Funktionen zur doppelten Genauigkeit erfüllen meiner Meinung nach nicht ihren Zweck, bzw. die Erwartungen an Korrektheit.
Aus der Funktion R2_ADD2:
--- Code: ---tR2_ADD2.R1 := X.R1 + Y.R1;
tR2_ADD2.RX := X.RX + Y.RX;
--- Ende Code ---
Da wird ja nur jeweils der Grob- und Feinanteil für sich alleinstehend aufsummiert. Ein Übertrag von Feinanteil zum Grobanteil findet nicht statt. Soll das so gewollt sein?
Ohne einen Übertrag zu den übergeordneten Stellen ergibt das mathematisch für mich keinen Sinn.
Für Aufklärung wäre ich durchaus dankbar,
mfG
e3
Wisse:
I'm sorry for resurrecting an old topic, but I figured it's worth posting since I couldn't find any similar solution on the forum. I hope someone finds this useful while S7-1500 with native double float is gaining traction.
If I understood e3's post correctly, he saw similar problem in R2_ADD2 function as we did. My colleague "mme" came up with this solution based on R2_ADD:
--- Code: ---tR2_ADD2.RX = Y.R1 + Y.RX + X.RX + X.R1;
tR2_ADD2.R1 = X.RX + Y.RX - tR2_ADD2.RX + Y.R1 + X.R1
--- Ende Code ---
I did a quick and dirty test in C# using floats in place of S7 Real and with double as a reference. The code above appears to be working as expected.
Test code:
--- Code: ---using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Real2Test
{
class Program
{
static void Main(string[] args)
{
float a = 10000000F;
float b = 0.00123F;
double c = a;
Real2 d = new Real2();
d.RX = a;
d.R1 = 0F;
Real2 e = new Real2();
e.RX = b;
e.R1 = 0F;
for (int i = 0; i < 3333333; i++)
{
c -= (double)b;
d = R2AddNew(d, R2Mul(e, -1F));
}
Console.WriteLine("Double: {0:F8}\tR2: {1:F8}\t{2:F8}", c, d.RX, d.R1);
for (int i = 0; i < 3333333; i++)
{
c += (double)b;
d = R2AddNew(d, R2Mul(e, 1F));
}
Console.WriteLine("Double: {0:F8}\tR2: {1:F8}\t{2:F8}", c, d.RX, d.R1);
for (int i = 0; i < 3333333; i++)
{
c += (double)b;
d = R2AddNew(d, R2Mul(e, 1F));
}
Console.WriteLine("Double: {0:F8}\tR2: {1:F8}\t{2:F8}", c, d.RX, d.R1);
Console.ReadKey();
}
static Real2 R2Mul(Real2 x, float y)
{
Real2 tmp = new Real2();
tmp.RX = x.RX * y;
tmp.R1 = x.R1 * y;
return tmp;
}
static Real2 R2AddNew(Real2 x, Real2 y)
{
Real2 z = new Real2();
z.RX = y.R1 + y.RX + x.RX + x.R1;
z.R1 = x.RX + y.RX - z.RX + y.R1 + x.R1;
return z;
}
}
class Real2
{
public float R1 { get; set; }
public float RX { get; set; }
}
}
--- Ende Code ---
Thank you for this great library!
W
Navigation
[0] Themen-Index
[*] Vorherige Sete
Zur normalen Ansicht wechseln