Zur Übersicht - INFO - Neueste 50 Beiträge - Neuer Beitrag - Suchen - FAQ - Zum CC1-Forum - Zum CC-Pro-Forum

Re: Grundsätzliches :-) Kategorie: Verschiedenes (von André H. - 30.04.2007 11:23)
Als Antwort auf Grundsätzliches :-) von m8_nix - 29.04.2007 0:58
Ich nutze:
C-Control II Unit, C164CI-ControllerBoard, CC2-Application-Board, CC2-StarterBoard, CC2-ReglerBoard, OSOPT V3.0, OSOPT V3.1
Hallo m8_nix,

> Zum ersten möchte ich eine Frage an die User stellen.
> Ausgehend von meinen Projekten benötige ich
> fast immer eine Funktion die einen "String-Wert" in eine Fliesskommazahl umwandelt.
> (>> INPUT "Testkommawert"). Ich kann mir nicht vorstellen das Ihr alle nur mit "runden Zahlen" hantiert?!
> Was mich dann wundert ist, das ich hierfür keine entsprechende Funktion finde (getNumfloat)??

Naja, das liegt evtl. daran, daÃ? viele eher mit Festkommaintegern als mit Float arbeiten.
Ich sehe hier auch keine dringende Notwendigkeit.
Auch ist die Eingabe über ein Terminal-Programm bei feritgen nwendungen eher die Ausnahme,
da, zumindest im gewerblichen Bereich, meist ein Eigenes Windowsprogramm erstellt wird,
sofern erforderlich.
Aber Parametereingaben erfolgen dann doch mehr an einer Bedienheinheit.
Und hier ist das Arbeiten mit Festkommainteger leichter, da man bei solchen Eingaben
meist eine feste Anzahl an Vor-und Nachkommastellen definiert, um mit dem Platz
auf dem Display vernünftig umgehen zu können.
Und da jede Anwendung unterschiedlich ist, würde hier jeder eine an seine Bedürfnisse
angepasste Funktion benötigen.



> Natürlich würde sich eine Routine schreiben lassen die entsprechendes bereits während des Eintippens
> erledigt und Fehleingaben wie Beispielsweise zwei Kommas nacheinander unterbindet.
> Nur denke ich sollte es auch möglich sein, über Schnittstellen empfangene Werte, auf Richtigkeit hin
> überprüfen zu können.

Wenn man Daten über RS232 von z.B. einem Windowsprogramm empfängt,
gestaltet man die Datenübertragung normalerweise nicht im Klartext.
Hier würde man unnötige viele Daten übertragen.


> Ausgehend davon denke ich, das Ihr alle schon mal so eine Funktion geschrieben habt, die einen String
> in eine Fliesskommazahl wandelt?! (Oder seh ich den Wald im Moment vor lauter Bäumen nicht??)

Nö. Ich verwende für soetwas keine Flie�kommazahlen, da bisher die meisten Anwendungen
dies nicht erforderten.
Lediglich bei Berechnungen, bei denen es auf Genauigkeit ankommt, sind teilw. in Float.
Die Quelldaten sind aber meist in Festkommainteger (Int oder long).
Das Ergebnis wird dann meist auch wegen des leichteren Handlings auf
ein Festkommainteger gerundet.

z.B. bei Heizungs-/Solarregelungen kenne ich keine Anwendung, bei
der ein Float notwendig wäre.

Temperaturen lä�t man sich mit einer, oder für ganz Genaue ;-), mit zwei Nachkommastellen anzeigen.
Für Sollwertvorgaben reicht auch eine Nachkommastelle oder max. zwei.
Hier ist ein Float viel zu aufwendig, wenn man sowieso bei einer bestimmten Anzahl
an Nachkommastellen bleibt.
Wie gesagt, nur bei Berechnungen, bei denen sich das Komma stark verschieben kann,
und es u.U auf die 10. Nachkommastelle ankommt, ist float wichtig.
Aber hier geht es dann nicht um eingegebene Werte, sondern um die Berechnung selbst.

> Also daher hier mein erster Wunsch (auch wenn Anrdé mir jetzt nen Vogel zeigt)
> Wäre es denn nicht möglich hier eine Rubrik "UserModule" "UserProgramme" "UserProjekte"
> zu veröffentlichen (ohne Gewähr auf Funktionali- und Orginali -tät)? In der einfach jeder seine Projekte vorstellen
> darf?

�hh. Schau mal links ins Menü.
Der Bereich "Programme C2" ist prinzipiell genau dafür gedacht.
Nur stellen nur sehr wenige ihre Programme bereit.

Nützliche Module veröffentlich ich auch unter Module & Funktionen.
Dann meist als "Gemeinsames Modul". Es sind dann aber Richtlinien
einzuhalten, was den Modulheader angeht. Es gibt zwei mögliche Varianten.
Als Vorlage dienen die bisherigen System- und gemeinsamen Module.

Das Veröffentlichen von Quellcode als Dateidownload, welcher nicht unbedingt
funktioniert (da nicht getestet), lehne ich jedoch ab.

Wer etwas veröffentlichen will, braucht mir das nur mailen.
Bei Modulen ist bei nicht-Betaversionen eine Hilfe-HTML pflicht.
(Diese darf aber nicht mit Word erstellt werden. Das kann man kein Html nennen,
was da rauskommt ;-) )
Bei Projekten kann die Dokumentation Wahlweise als txt, Html oder PDF erfolgen.
Bei kleinen Programmen natürlich auch direkt im Quellcode-Header als Kommentar.


> Das würde natürlich auch bedeuten das man "hier" auch Bilder hochladen kann. Vielleicht wäre
> eine PDF-Implematation der einfachste Weg, da es hierfür inzwischen viele entsprechend freie Converter gibt
> die sich bei der Ausgabe wie ein "stink-normaler" Drucker verhalten.

Den Dateiupload habe ich absichtlich noch nicht implementiert.
Denn dafür mü�te ich ein User-Accounting einführen, was ich eigentlich nicht machen wollte.
Denn ein anonymes Hochladen wäre ein Sicherheitsrisiko, und ich habe
auch die Zeit nicht, alles zu überwachen. (Viren, Trojaner etc.)


> Mein nächstes Anliegen ist schon fast unverschämt *grins
> Wie schön es doch war, zu Turbo-Pascals-Zeiten, mit Zeigern zu arbeiten *schwäm
> Ein Zeiger selbst ist eine Variable die nicht etwa einen Wert beinhaltet , nein - sie beinhaltet den
> Speicherort einer Variablen dessen Wert mich Interessiert, deren Datentyp aber erst bei "Gebrauch"
> festgelegt wird. Also quasi eine undeffinierte Variable in der Variable.
> Dabei ist der Speicherort selbst für den Programmierer unerheblich. Wichtig ist nur das sich mit Hilfe
> einer solchen Funktion wiederkehrende, verschachtelte Strukturen
> (wie sie Beispielsweise in Menüs zu  finden sind)  oft benötigte, wiederkehrende Programmteile sparen kann.
> Zur Verdeutlichung: Eine "gemeine" Tastaureingabefunktion "function (getinteger) returns int"
> könnte mit Hilfe von Zeigern jede Art Datenstruktur zurückgeben "function(get) returns int^z"
> "z" Repräsentiert hierbei nicht etwa das Funktionsergebnins sondern nur den den "Aufenthaltsort" von "z"
> Dabei kann "z" sowohl byte, int, long als auch string sein. (Je nach dem wie sie vor dem Aufruf
> deklariert wurde "int^ z;"..... "byte^ z;" "string^ z".
> Kompliziert ... ich weiss. Aber jeder der schon mal  ein aufwendiges Menü programmiert hat wird sich
> hier gerne an Turbo Pascal zurückerinnern - da bin ich mir sicher:-)...
> Das ganze schimpft sich dann "neudeutsch" auch noch dynamische Variable. Phüüü!!!

Ã?hh, ich sehe hier das Problem nicht.
In C2 gibt es zwar nicht die explizite Möglichkeit, Variablen als Referenz zu übergeben,
jedoch wird bei Funktionen alles, auÃ?er den "Einzelwert"-Variablen (also Nichtarrays)
immer als Referenz "übergeben". Dabei sind z.B. Strings und eigene Datentypen
immer als Array zu sehen.
Also:
Byte, Integer, Long und Float werden immer als Wert übergeben.
Strings, Arrays und eigene Datentypen immer als Referenz.
Wobei es bei Strings einen Sonderfall gibt, wenn hier ein Konstanter
Ausdruck übergeben wird. Nur in dieser Fall wird eine lokale Variable angelegt.

Wenn Du also z.B. drei Vriablen x, y, z einer Funktion als Referenz übergeben willst,
ist eine Möglichkeit, dies in Form eines eigenen Datentyps zu machen:
type menue
{
 int x;
 int y;
 int z;
}

menue Daten;

function abc(menue werte)
{
 werte.x= werte.x+5;
 werte.y= werte.y-10;
 werte.z= werte.z*4;
}
...

Daten.x=2;
Daten.y=57;
Daten.z=5;
abc(Daten);
hwcom.num(Daten.x);hwcom.ret();
hwcom.num(Daten.y);hwcom.ret();
hwcom.num(Daten.z);hwcom.ret();
...


Nach ausführen in von "abc()" sind die in dieser Funktion berechneten
Werte auch in "Daten" enthalten.
Besser gesagt, es wurde direkt mit "Daten" gearbeitet, da "werte" nur
als Referenz auf "Daten" zeigt.

Wenn mann keinen eigenen Datentyp erstellen will, kann man das auch mit einfachen
Arrays machen, und für die Indizies Konstanten vorgeben:
int Daten[4];
const w=0;
const x=1;
const y=2;
const z=3;

function abc(int werte[])
{
 werte[w]= werte[w]/2;
 werte[x]= werte[x]+5;
 werte[y]= werte[y]-10;
 werte[z]= werte[z]*4;
}
...
Daten[w]=30;
Daten[x]=2;
Daten[y]=57;
Daten[z]=5;
abc(Daten);
hwcom.num(Daten[w]);hwcom.ret();
hwcom.num(Daten[x]);hwcom.ret();
hwcom.num(Daten[y]);hwcom.ret();
hwcom.num(Daten[z]);hwcom.ret();
...


Siehe auch Handbuch (Unit) Kapitel 5.8.2 Parameter und lokale Variablen.


> Eine vielleicht letzte saudoofe frage hab ich noch... Laut Handbuch hat ein "float" hier 8 byte... und einen
> Wertebereich von 1.7*10(308) .... Wie definiere ich jedoch hier einen Exponenten? 5.2e-100? oder
> wieso führt x (float)... also x=0x8000000000000000 zu x=0.000?

Ein Float ist ganz anders aufgebaut, als Byte, Integer und Long.
Bei Float sind keinerlei Bitmanipulationen möglich.
Auch das Verwenden der HEX-Schreibweise ist nicht anzuraten.
Es sollte hier immer die Dezimalschreibweise angewendet werden, da nur
hier Kommastellen dargestellt werden können.
Wenn Du die HEX-Schreibweise nutzt, werden die Daten nicht 1:1 in die Float
variable gespeichert, sondern als ganze Zahl gesehen, welche max. 32Bit haben kann (long)
Es gelten die Grenzbereiche, wie im Handbuch angegeben.
Wenn Du eine konstante Zahl explizit als Float angeben möchtest, diese aber keine
Kommastelle besitzt, muÃ? Du diese vorher in ein Float speichern.
Ein Anfügen von Komma.Null, also z.B. "25.0" hilft nicht.
Das muÃ? man innerhalb von Berechnungen beahten, wenn die Quelldaten kein Float sind,
aber das Ergebnis Float sein muÃ?. (Prinzipiell nur bei Divisionen)
int x;
float f;int x;
...
f=x/3.0;

Hier wird trotz Kommaangabe als integer gerechnet.
Nur, wenn es sich um eine echte Kommazahl handelt, also z.B. "3.1", wird
hier eine Floatberechnung durchgeführt.
Daher muÃ? man in diesem Fall so schreiben:
int x;
float f;int x;
...
f=3
f=x/f;


Der einzige Trick, direkt auf die Daten des Float zuzugreifen, ohne daÃ? dieser
Bestandteil eines Arrays oder eigenen Datentyps ist, ist das "Vorschalten"
eines Arrays:
byte raw[2];float x;
Wenn Du nun mit den Indizies 2 bis 9 auf raw[] zugreifst, befindest Du Dich
im Speicherbereich von x.
Wenn es aber nur um den Inhalt geht, und nicht um die Manipulation der
Floatvariable selbst, ist das Verwenden von mem.getfloat() und mem.putfloat()
sicher einfacher.
Du kannst die Daten somit einfach in ein Bytearray mit 8 Elementen speichern
bzw. davon auslesen, was z.B. für die Datenübertragung, aber auch für
das Abspeichern gedacht ist.


> Wie auch immer... hier stell ich mal meine Routine von "getNumfloat"  rein...
> (Da ich nicht in der Lage war einen kleinstmöglichen negativen Wert für einen "falschen" String zu deffinieren
> hab ich den von "long" hergenommen?! >>  -2147483647

Ich werde mir Deine Lösung mal genauer ansehen.
Als Fehlerwert sollte immer eine Zahl genommen werden, die "unwahrscheinlich" ist.
Bei Float wäre das z.B. -1,7*10^-308. Aber das kann man schlecht auswerten. ;-)
Daher wäre die Lösung von Dir, den niedrigsten Long-Wert zu nutzen, sicher die sinnvollste.
Ansonsten können man noch eine "Error"-Variable nuzten, die eine Fehlernummer
zurückgibt:
type error
{
 byte num;
}
function getNumfloat (byte s[], error err) returns float
{
...
 If <Fehler xy> {err.num=44;return 0;}
...
 err.num=0; //alles OK
 return wert;
}

Da hier ein eigener Datentyp erstellt wurde, wird dieser als Referenz übergeben.
Somit sind au�er mit Return, weitere Rückgabewerte möglich.


MfG André H.



Antworten bitte nur ins Forum!
Fragen per EMail auf Forum-Postings werden nicht beantwortet!

Das macht meine Heizung gerade


    Antwort schreiben


Antworten:

Re: Grundsätzliches :-) (von m8_nix - 30.04.2007 17:14)
    Re: Grundsätzliches :-) (von André H. - 14.05.2007 10:44)