Aufgabe Probleme mit C++ Methode

Alex33

Well-Known Member
#1
Hallo alle zusammen wollte fragen ,ob ich bei dieser AUfgabe die switchoff und switchoffat Methode richtig implementiert habe ?

Code:
#ifndef CTIMEOFDAY_H_
#define CTIMEOFDAY_H_

#include <string>
#include<cmath>

class CTimeOfDay {
private:
    unsigned int m_secsSinceMidnight;

    /**
     * Hilfsmethode zum Konvertieren eines Ganzzahl-Wertes
     * in eine Zeichenkette.
     */
    std::string intToString(unsigned int value);

public:
    /**
     * Erzeugt eine neue Zeitangabe mit der aktuellen Uhrzeit.
     */
    CTimeOfDay();

    /**
     * Erzeugt eine neue Zeitangabe aus der Angabe der
     * seit Mitternacht vergangenen Sekunden.
     */
    CTimeOfDay(unsigned int secsSinceMidnight);

    /**
     * Erzeugt eine neue Zeitangabe aus der Angabe einer
     * Uhrzeit im 24-Stunden Format ("hh:mm:ss", mit hh=Stunden,
     * mm=Minuten und ss=Sekunden).
     */
    CTimeOfDay(std::string timeOfDay);

    /**
     * Liefert den durch diese Zeitangabe repr�sentierten
     * Zeitpunkt als Sekunden seit Mitternacht.
     */
    long getSecsSinceMidgnight();

    /**
     * Liefert den durch diese Zeitangabe repr�sentierten
     * Zeitpunkt im 24-Stunden Format ("hh:mm:ss", mit hh=Stunden,
     * mm=Minuten und ss=Sekunden).
     */
    std::string asTime();
    int operator-(CTimeOfDay rhs);
};

#endif /* CTIMEOFDAY_H_ */
Code:
#include "CTimeOfDay.h"

#include <stdio.h>
#include <cstring>
#include <time.h>
using namespace std;

CTimeOfDay::CTimeOfDay() {
      time_t rawtime;
      struct tm * timeinfo;

      time (&rawtime);
      timeinfo = localtime (&rawtime);
      m_secsSinceMidnight = timeinfo->tm_hour * 3600
              + timeinfo->tm_min * 60 + timeinfo->tm_sec;
}

CTimeOfDay::CTimeOfDay(unsigned int secsSinceMidnight) {
    m_secsSinceMidnight = secsSinceMidnight;
}

CTimeOfDay::CTimeOfDay(std::string timeOfDay) {
    unsigned int hours;
    unsigned int minutes;
    unsigned int seconds;
    sscanf(timeOfDay.c_str(), "%02u:%02u:%02u", &hours, &minutes, &seconds);
    m_secsSinceMidnight = hours * 3600 + minutes * 60 + seconds;
}

std::string CTimeOfDay::intToString(unsigned int value) {
    string result = "";
    do {
        result = (char)('0' + value % 10) + result;
        value /= 10;
    } while (value > 0);
    return result;
}

long CTimeOfDay::getSecsSinceMidgnight() {
    return m_secsSinceMidnight;
}

std::string CTimeOfDay::asTime() {
    unsigned int hours = m_secsSinceMidnight/3600;
        unsigned int minutes = m_secsSinceMidnight/60%60 ;
        unsigned int seconds = m_secsSinceMidnight%60;
    // Ersetzen Sie die nachfolgende Anweisung!

        string xhours;
        string xminutes;
        string xseconds;
        if(hours < 10) {
        xhours = "0"+intToString(hours);
        }
        else {
        xhours = intToString(hours);
        }
        if(minutes<10){
         xminutes = "0"+intToString(minutes);
        }
        else{
            xminutes = intToString(minutes);

        }
        if(seconds< 10){
         xseconds = "0"+intToString(seconds) ;
        }
        else{
            xseconds = intToString(seconds);
        }


        //string gesamt = "0"+intToString(hours)+intToString(minutes)+intToString(seconds);
        string gesamt = xhours+":"+xminutes+":"+xseconds;
        return gesamt;
}

int CTimeOfDay::operator-(CTimeOfDay rhs){
    unsigned int zeit;

    if(m_secsSinceMidnight < 0){

        zeit = m_secsSinceMidnight*-1;


    }
    zeit = m_secsSinceMidnight - rhs.m_secsSinceMidnight;


}

Header

Code:
/*
 * CDimmerLogEntry.h
 */

#ifndef CDIMMERLOGENTRY_H_
#define CDIMMERLOGENTRY_H_



/**
 * Diese Klasse modelliert ein Einschalten des Dimmers zu einem
 * gegebenen Zeitpunkt, f�r eine bestimmte Dauer und mit einem
 * bestimmten Dimm-Faktor (ein Wert zwischen 0 (ausschlie�lich)
 * und 1 (einschlie�lich)).
 *
 * Um Speicherplatz zu sparen, werden der Einschaltzeitpunkt und
 * die Einschaltdauer mit Attributen vom Typ unsigned short
 * modelliert. Da deren Wertebereich nicht ganz ausreicht, um
 * alle Sekunden eines Tages zu rep�sentieren (24*60*60 > 2^16),
 * werden die Sekundenangaben f�r die Speicherung durch 2 geteilt
 * (und beim Auslesen der Werte wieder mit 2 multipliziert).
 * Die daduch entstehende Ungenauigkeit bei den Zeitangaben
 * ist im Rahmen der vorgesehenen Anwendungsf�lle akzeptabel.
 *
 * Auch der Dimm-Faktor soll effizient gespeichert werden. Der
 * als float �bergebene Wert zwischen 0 und 1 wird daher
 * f�r die Speicherung in einen unsigned short gewandelt.
 * Nutzen Sie den zur Verf�gung stehenden Wertebereich
 * vollst�ndig aus, d.h. speichern Sie den Faktor mit
 * m�glichst hoher Genauigkeit.
 */
class CDimmerLogEntry {
private:
    unsigned short m_startTime;
    unsigned short m_duration;
    unsigned short m_factor;

    /**
     * Setzt das Attribut m_factor nach entsprechender
     * Umrechnung des �bergebenen Wertes. Die Methode
     * wertet auch die Zusicherung (s.u.) aus.
     */
    void setFactor(float factor);

public:
    /**
     * Erzeugt einen neuen Log-Eintrag mit der angegebenen
     * Einschaltzeit, dem angegebenen Dimm-Faktor und einer
     * Einschaltdauer von 0.
     *
     * startTime: die Einschaltzeit als Sekunden seit Mitternacht.
     *            Der Wert muss kleiner sein als die Anzahl
     *            Sekunden eines Tages. Ist das nicht der Fall,
     *            wird statt dessen der Maximalwert (sp�test
     *            m�glicher Einschaltzeitpunkt an einem Tag)
     *            genommen.
     *
     * factor:    der Dimm-Faktor. Der Wert muss gr��er 0 und
     *            kleiner gleich 1 sein. Verletzt der angegebene
     *            Wert diese Bedingung, wird der Wert 1 genommen.
     */
    CDimmerLogEntry(unsigned int startTime, float factor = 0.5);

    /**
     * Erzeugt einen neuen Log-Eintrag mit der aktuellen Zeit
     * als Einschaltzeit, dem angegebenen Dimm-Faktor und einer
     * Einschaltdauer von 0.
     *
     * factor:    der Dimm-Faktor. Der Wert muss gr��er 0 und
     *            kleiner gleich 1 sein. Verletzt der angegebene
     *            Wert diese Bedingung, wird der Wert 1 genommen.
     */
    CDimmerLogEntry(float factor = 0.5);

    /**
     * Legt die Ausschaltzeit des Dimmers und damit die
     * Einschaltdauer fest.
     *
     * offTime:   die Ausschaltzeit als Sekunden seit Mitternacht.
     *            Ist der Wert kleiner als die Einschaltzeit, wird
     *            davon ausgegangen, dass der Dimmer am n�chsten
     *            Tag ausgeschaltet wurde (z.B. bedeutet bei einer
     *            Einschaltzeit 22:00:00 ein Ausschalten um 01:00:00
     *            dass der Dimmer 3 Stunden angeschaltet war).
     */
    void switchedOffAt(unsigned int offTime);

    /**
     * Legt die aktuelle Zeit als Ausschaltzeitpunkt fest.
     */
    void switchedOff();

    /**
     * Liefert den Einschaltzeitpunkt.
     */
    unsigned int getStartTime() const;

    /**
     * Liefert die Einschaltdauer.
     */
    unsigned int getDuration() const;

    /**
     * Liefert den Dimm-Faktor.
     */
    float getFactor() const;

};

#endif /* CDIMMERLOGENTRY_H_ */
Code:
#include "CTimeOfDay.h"
#include "CDimmerLogEntry.h"
#include <stdio.h>
#include <cstring>
#include <time.h>
#include<iostream>
using namespace std;

void CDimmerLogEntry::setFactor(float factor){

    m_factor = factor;
}

CDimmerLogEntry::CDimmerLogEntry(unsigned int startTime, float factor ){

    if(m_factor >= 0 && m_factor<= 1){

        setFactor(factor);
    }
    else{

        setFactor(1);
    }

    if(startTime > 86400) {
        //dann ist schlecht
        m_startTime = 86400;
    } else {
        m_startTime = startTime/2;
    }
}

unsigned int CDimmerLogEntry::getStartTime() const {
    return m_startTime*2;
}

unsigned int CDimmerLogEntry::getDuration() const {
    return m_duration*2;
}

float CDimmerLogEntry::getFactor() const {
    return m_factor;
}
void CDimmerLogEntry::switchedOff()
{

unsigned int offTime;

if(m_startTime < offTime){

 m_duration = offTime- m_startTime;
 m_duration = m_duration/24;

}
if(m_startTime >offTime){

m_duration = -1*(-offTime +m_startTime)+3600;
m_duration = m_duration/24;


}

}


void CDimmerLogEntry::switchedOffAt(unsigned int offTime){

CTimeOfDay();
   CDimmerLogEntry::switchedOff();
}
Ich weiss ,dass die zwei Methoden nicht ganz korrekt sind aber ehrlich gesagt habe ich anhand der Aufgabe auch nicht ganz verstanden was die wollten ?
Versteht ihr es .





In dieser Klausur soll ein Protokoll („Log“) für den Betrieb eines Dimmers implementiert werden. An den Dimmer ist ein Verbraucher angeschlossen. Der Verbraucher kann mit dem Dimmer ein- und ausge- schaltet werden. Ist der Verbraucher eingeschaltet, arbeitet er mit einer Leistung entsprechend dem am Dimmer eingestellten Dimm-Faktor. Beispielsweise arbeitet eine angeschlossene 100W-Glühbirne bei einem Dimm-Faktor von 1,0 tatsächlich mit 100W, bei einem Dimm-Faktor von 0,75 aber nur mit 75W. Im Protokoll wird bei jedem Einschalten ein neuer Eintrag angelegt, in dem die Einschaltzeit und der eingestellte Dimm-Faktor vermerkt sind. Beim Ausschalten des Dimmers wird dann in dem Protokoll- eintrag noch die Ausschaltzeit (bzw. die Einschaltdauer) ergänzt.



Alles andere im Anhang. Bildschirmfoto 2018-07-12 um 01.52.18.png Bildschirmfoto 2018-07-12 um 01.52.30.png
 

-AB-

Well-Known Member
c-b Team
c-b Experte
#2
Auch der Dimm-Faktor soll effizient gespeichert werden. Der
* als float �bergebene Wert zwischen 0 und 1 wird daher
* f�r die Speicherung in einen unsigned short gewandelt.
* Nutzen Sie den zur Verf�gung stehenden Wertebereich
* vollst�ndig aus, d.h. speichern Sie den Faktor mit
* m�glichst hoher Genauigkeit.
Hast du nicht gemacht. Momentan wird der float (der hoffentlich zwischen 0 und 1 ist) einfach zu einem short gecastet, ist also immer exakt 0 oder 1. Nicht das, was es tun sollte. ;)

Im CDimmerLogEntry Konstruktor greifst du auf m_factor zu, bevor du den Wert setzt. Hier willst du vermutlich eher auf den Parameter zugreifen.


Die Rumrechnerei im Konstruktor erschließt sich mir nicht ganz, insbesondere die 84k verwundern mich. Der unsigned short läuft bis 65536. (Und das doppelte des Wertes ists auch nicht.)
Als Student hätt ich aber hier auch vermutlich eine Seite darüber geschrieben, dass es Unfug ist, mit 32bit floats und ints zu rechnen, aber die Daten als shorts zu halten. In einem embedded systems Kurs vielleicht, aber dann auch bitte an allen Stellen 8 oder 16 bit verwenden. Die Aufgabenstellung macht die Aufgabe einfach nur künstlich schwer. Noch dazu könnte man die 16 bits der Duration als weiteren Speicher benutzen wozu diesen Wert ablegen, wenn man ihn eh beim Aufruf neu berechnen muss?

In getFactor() musst du natürlich auch von unsigned short wieder zu float umrechnen. Sonst bekomsmt du auch hier nur die Werte 0.f und 1.f.

Anyway, die Rechnung nochmal checken.

Welcher Wert für duration soll zurückgegeben werden, wenn der Dimmer noch läuft? 0? Soll er berechnet werden? Im Moment ist der Wert undefiniert, weil du deinen Member nicht initialisierst.

In switchedOff...
C++:
unsigned int offTime;
if(m_startTime < offTime)...
Fällt dir was auf?
An sich ist der Gedanke richtig, erstmal weg von den dummen shorts, und stattdessen als int ablegen. Bloß zuweisen musst du die Werte schon.
Hint: Wenn du die get...-Funktionen nutzt, musst du nicht mehr /2 rechnen.
Ich vermute, das "Statement ohne Effekt" CTimeOfDay(); aus switchedOffAt sollte hier irgendwo hin?

Generell: switchedOffAt nimmt einen Parameter, wann ausgeschaltet wurde. Diese Funktion sollte also die Berechnung ausführen. switchedOff stattdessen berechnet die gegenwärtige Zeit "jetzt", und ruft damit dann switchedOffAt auf.

In switchedOff - den Fall wenn m_startTime == offTime ist, ignorierst du wieder.
(Und schreib den Fall nicht wieder explizit drunter! In einen der beiden Fälle wird es wohl reinpassen, "kleiner" ist es dann eben nicht, wenns gleich ist.)

Deine Rechnung versteh ich wieder nicht ganz. Ich schätze Mal, die 84k sind die Sekunden pro Tag, aber die brauchst du gar nicht. Nutz auf beiden seiten die "nicht durch 2 geteilten" int-Variablen (notfalls die shorts *2 nehmen und als int speichern) und die Differenz berechnen. Wenn X > Y, nimmst du X-Y, else (Hint! Hint!) Y-X. Das ist die Differenz. Jeder normale Programmierer würde den Wert jetzt zurück geben, aber von mir aus kann man den auch durch 2 teilen und in m_duration ablegen.
 

Alex33

Well-Known Member
#3
Konstriktor :
Meinst du ich soll lieber m_factor = factor schreiben?

Code:
CDimmerLogEntry::CDimmerLogEntry(unsigned int startTime, float factor ){

    if(m_factor >= 0 && m_factor<= 1){

        m_factor = factor;
        //setFactor(factor);
    }
    else{

        setFactor(1);
    }

    if(startTime > 86400) {
        //dann ist schlecht
        m_startTime = 86400;
    } else {
        m_startTime = startTime/2;
    }
}
In der Aufgabe steht doch set Factor Methode nutzen?

In der get Factor Methode steht ja nur den Faktor zurückzugeben ? Auch im Header steht das ja auch ?
Wie kommst du auf das umrechnen ?


Code:
void CDimmerLogEntry::switchedOff()
{

unsigned int offTime;

if(m_startTime < offTime){

m_duration = offTime- m_startTime;
m_duration = m_duration/24;

}
if(m_startTime >offTime){

m_duration = -1*(-offTime +m_startTime)+3600;
m_duration = m_duration/24;


}
if(m_startTime == offTime){

wann soll der dann ausschalten ? Verstehe es nicht?

}

}
Wenn startTime == off...

dann einfach duration = m_startTime - offTime;
Das würde dann ja mathematisch 0 ergeben?hmmm
 

-AB-

Well-Known Member
c-b Team
c-b Experte
#4
Konstriktor :
Meinst du ich soll lieber m_factor = factor schreiben?
*Eigentlich* solltest du die Initialisierungsliste nutzen... Aber das an einem anderen Tag.
Dann nochmal...
C++:
if(m_factor >= 0 && m_factor<= 1){
Welchen Wert hat m_factor in exakt dieser Zeile?

setFactor aufzurufen ist in dem Fall ja sinnvoll. Vermutlich wäre es sinnvoller, auch den Vergleich auf kleiner 0/größer 1 in setFactor durchzuführen, sollte man die Methode jemals public machen wollen. Aber außerhalb passts auch erstmal.

Wie kommst du auf das umrechnen ?
Weils in der Aufgabe steht ;)
Nutzen Sie den zur Verf�gung stehenden Wertebereich
* vollst�ndig aus, d.h. speichern Sie den Faktor mit
* m�glichst hoher Genauigkeit.
Der zur Verfügung stehende Wertebereich ist von 0 bis 65k. Du benutzt 2 Werte, 0 und 1, das ist nicht der gesamte Bereich ;)

Gedacht ist, dass du die Werte von 0 bis 65536 als Abstufungen zwischen 0 und 1 siehst, also 0 = 0 65536tel, 1 = 1/65536, und 65536= 65536/65536=1.
Beim Zuweisen des Floats (float->short) sollte man das eben umrechnen, und beim Zurückgebend es Faktors (als float) das ganze umgekehrt.
(Das ist sogar halbwegs sinnvoll.)

Wenn startTime == off...

dann einfach duration = m_startTime - offTime;
Das würde dann ja mathematisch 0 ergeben?hmmm
Klar, wenn du es an- und innerhalb von <2 Sekunden wieder ausschaltest. Dann ist die Differenz (dank des durch 2 Teilens) = 0.

Sagte ich nicht, NICHT den dritten Fall einfach drunter schreiben?

Ein Konstrukt wie
C++:
if(a < b)
    //do something
if(b < a)
    //do something else
//noch schlimmer:
if(a==b)
    //do a third thing
ist immer Fehleranfällig.
Erstens: Es gibt keinen default-Case.
Du magst zwar denken, du hast alle Fälle abgedeckt, aber angenommen, du wechselt mit a und b zu float oder double - schon kann einer der Werte NaN sein, und ein vergleich mit NaN evaluiert immer zu false.
Sprich, jeder Vergleich rauscht durch, und am Ende landest du in Code, den du nie aufrufen wolltest, gibst "nichts" zurück, auch wenn du es wolltest, und so weiter. Klassischer, schwer zu debuggender Fehler.

Natürlich sollte einer der beiden Fälle <= enthalten, um (mathematisch, NaN ausgenommen) alle Fälle abzudecken.

Und immer sinnvoller ist es, statt eines zweiten Vergleiches (der immerhin erneut evaluiert werden muss, also in obigem Beispiel 3 Rechenschritte statt einem) ein if..else zu schreiben.

Dann muss kein Mensch 3 Statements lesen und sich fragen, ob nicht vielleicht im ersten die Werte geändert werden, und man dann doch in den zweiten reinrutschen kann, oder oder oder. 1 Statement, 1 Vergleich, alles klar. In jedem anderen Fall (auch NaN ist abgedeckt) wird eben der else-Teil ausgeführt.


Ach ja. Mit der switchedOff-Methode sagst du nicht, wann das Ding ausschalten soll. Du sagst dem Ding, wann es ausgeschaltet hat. Hilft vielleicht ein Bisschen dem Verständnis.
 

Alex33

Well-Known Member
#5
Ach ja. Mit der switchedOff-Methode sagst du nicht, wann das Ding ausschalten soll. Du sagst dem Ding, wann es ausgeschaltet hat. Hilft vielleicht ein Bisschen dem Verständnis.

Meinst du damit, dass ich die switch off Methoden falsch rum implementiert habe ?
 

-AB-

Well-Known Member
c-b Team
c-b Experte
#7
Meinst du damit, dass ich die switch off Methoden falsch rum implementiert habe ?
Das war nur auf
Alex33 hat gesagt.:
wann soll der dann ausschalten ? Verstehe es nicht?
bezogen. Das klang so als würdest du nicht genau wissen, was die Funktion machen soll.

Letztendlich sollst du nur die Differenz zwischen start und end/jetzt berechnen und (in Doppel-Sekunden geteilt) abspeichern. :)
 

Alex33

Well-Known Member
#8
Code:
void CDimmerLogEntry::switchedOff()
{

unsigned int offTime;

if(m_startTime < offTime){

m_duration = offTime- m_startTime;
m_duration = m_duration/24;

}
if(m_startTime >offTime){

m_duration = -1*(-offTime +m_startTime)+3600;
m_duration = m_duration/24;


}
else{
m_duration = (m_startTime-offTime)/(3600) ;

}
Ehrlich gesagt habe ich immer noch nicht verstanden was die switch off und at machen soll:D.
Aber jetzt nach deinen Erklärungen ein wenig verstanden.

That s it?:D

Und jetzt bei switchoffAt die switch off aufrufen?
 

-AB-

Well-Known Member
c-b Team
c-b Experte
#9
Und jetzt bei switchoffAt die switch off aufrufen?
Umgekehrt:
Generell: switchedOffAt nimmt einen Parameter, wann ausgeschaltet wurde. Diese Funktion sollte also die Berechnung ausführen. switchedOff stattdessen berechnet die gegenwärtige Zeit "jetzt", und ruft damit dann switchedOffAt auf.

C++:
void CDimmerLogEntry::switchedOff()
{
unsigned int offTime; //sollte das hier vielleicht ein Parameter sein?

if(m_startTime < offTime){

m_duration = offTime- m_startTime;
m_duration = m_duration/24; // warum durch 24?

}
if(m_startTime >offTime){

m_duration = -1*(-offTime +m_startTime)+3600; //rechne das nochmal nach, das kann unmöglich richtig sein ;)
m_duration = m_duration/24; // auch hier, warum /24?


}
else{ //du hast immer noch 3 Fälle für etwas, was eigentlich nur 2 Fälle sind.
m_duration = (m_startTime-offTime)/(3600) ; //warum teilst du hier Sekunden durch 3600?

}
Zur Berechnung in der Mitte...

Wenn um 2xxx Sekunden angeschaltet wird, und um 1xxx Sekunden ausgeschaltet wird, ein Tag YYYY Sekunden dauert, wie lange war es dann an? Die Differenz der beiden (größeres minus kleineres - welches welches ist, wurde im if schon geklärt - ) und ein Tag... Das sollte es eigentlich sein.
 

Alex33

Well-Known Member
#10
Ich wollte durch 24 in h umwandeln hmmm
Code:
void CDimmerLogEntry::switchedOff()
{
unsigned int offTime; //sollte das hier vielleicht ein Parameter sein? Ja Parameter erstellt wegen Fehlermeldung

if(m_startTime < offTime){

m_duration = offTime- m_startTime;
 // warum durch 24?

}
if(m_startTime >offTime){

m_duration = (-offTime +m_startTime); //rechne das nochmal nach, das kann unmöglich richtig sein ;)
m_duration = m_duration; // auch hier, warum /24? Ja war blöd gemerkt-


}
 //du hast immer noch 3 Fälle für etwas, was eigentlich nur 2 Fälle sind.
m_duration = (m_startTime-offTime); //warum teilst du hier Sekunden durch 3600?
Stimmt es sind ja schon Sekunden. Besser ?

}

Besser ?
 

-AB-

Well-Known Member
c-b Team
c-b Experte
#11
Wir nähern uns dem ganzen....
- offTime sollte immer noch ein Parameter sein, und dann tauschst du die off und offAt-Funktionen. Denn Momentan machen sie beide noch das falsche.
- Immer noch 3 Fälle. Du kannst ja nur start - off oder off - start rechnen, wozu dann 3 Fälle?
- beim unären Minus (-offTime) und unsigned-Datentypen wäre ich vorsichtig. Es wrappt zwar rum, ist aber ein Quell für spätere Fehler. Außerdem sinds mehr Zeichen für denselben Effekt. Wenn ich die Differenz zwischen 5 und 8 haben will, kann ich ja auch einfach 8-5 rechnen, und muss nicht -5+8 rechnen.
- Dann hätten wir die Differenz. Beispielsweise mal Stunden: Ich schalte um 3 Uhr an, und um 2 Uhr aus. Differenz eine Stunde - ABER es ist ein neuer Tag. Insgesamt sind 24h minus eine Stunde vergangen. also in etwa 86400 - (start-off)
- Zu guter Letzt: An jeder Stelle, wo du m_duration zuweist, noch vorher durch 2 teilen. Das ist, weil ihr wegen dem short ja nur Doppelsekunden speichert...
 

Alex33

Well-Known Member
#12
Hier mein Code Fehler zeigt er ja nicht an .

Das mit dem /2 habe ich eingebaut , aber verstehe es nicht .
Gut wenn ich start - off rechne muss das ergebnis ja in sekunden sein ?
ABer was bringt mir das durch 2?
Oder bin ich blöd:D:mauer:
Code:
void CDimmerLogEntry::switchedOff()
{


    CTimeOfDay();
       CDimmerLogEntry::switchedOff();

}


void CDimmerLogEntry::switchedOffAt(unsigned int offTime){


    if(m_startTime < offTime){

    m_duration = (offTime - m_startTime)/2;


    }
    if(m_startTime >offTime){

    m_duration = m_startTime -offTime; //rechne das nochmal nach, das kann unmöglich richtig sein ;)
    m_duration = (m_duration)/(2); // auch hier, warum /24? Ja war blöd gemerkt-


    }
    


}
 

asc

Well-Known Member
c-b Experte
#13
Aufgabe nicht ganz gelesen?

Code:
* Um Speicherplatz zu sparen, werden der Einschaltzeitpunkt und
 * die Einschaltdauer mit Attributen vom Typ unsigned short
 * modelliert. Da deren Wertebereich nicht ganz ausreicht, um
 * alle Sekunden eines Tages zu rep�sentieren (24*60*60 > 2^16),
 * werden die Sekundenangaben f�r die Speicherung durch 2 geteilt
 * (und beim Auslesen der Werte wieder mit 2 multipliziert).
 * Die daduch entstehende Ungenauigkeit bei den Zeitangaben
 * ist im Rahmen der vorgesehenen Anwendungsf�lle akzeptabel.
 

Alex33

Well-Known Member
#14
Ah ok . Mist . :mauer::p

Aber die 2 Methoden passen jetzt ? Dann könnte ich mich an den nächsten Aufgabenteil machen?Will jetzt langsam fertig machen;)
Was im Rahmen einer Möglichkeiten noch geht
 

-AB-

Well-Known Member
c-b Team
c-b Experte
#15
- switchedOff ruft sich selbst auf statt switchedOffAt
- immer noch 2 ifs für etwas, für das ein einziges if statement reicht...
- aus demselben Grund, aus dem die duration durch 2 geteilt werden soll, wurde natürlich auch die startTime durch 2 geteilt. Bevor du die verwendest, müsstest du sie noch schnell in eine unsigned int Variable abspeichern, und wieder mit 2 multiplizieren.
(Vermutlich könnte man auch gleich überall mit Doppelsekunden arbeiten. Aber man könnte ja auch einfach eine sinnvolle Aufgabe schreiben, grr.)
Und
- Dann hätten wir die Differenz. Beispielsweise mal Stunden: Ich schalte um 3 Uhr an, und um 2 Uhr aus. Differenz eine Stunde - ABER es ist ein neuer Tag. Insgesamt sind 24h minus eine Stunde vergangen. also in etwa 86400 - (start-off)
 

Alex33

Well-Known Member
#16
Bevor du die verwendest, müsstest du sie noch schnell in eine unsigned int Variable abspeichern, und wieder mit 2 multiplizieren.
Hier kann ich dir nicht folgen ?Warum wieso das ?:eek:

Code:
void CDimmerLogEntry::switchedOff()
{


    CTimeOfDay();
       CDimmerLogEntry::switchedOffAt();

}


void CDimmerLogEntry::switchedOffAt(unsigned int offTime){


    if(m_startTime < offTime){

    m_duration = 86400-((offTime - m_startTime)/2);


    }
    if(m_startTime >offTime){

    m_duration = 86400-((m_startTime -offTime)/(2)); //rechne das nochmal nach, das kann unmöglich richtig sein ;)
     // auch hier, warum /24? Ja war blöd gemerkt-


    }



}
 

-AB-

Well-Known Member
c-b Team
c-b Experte
#17
Jetzt kompiliert es nicht, weil switchedOffAt einen Parameter will, den du ihm nicht gibst.

Nnnnneiiin. Nicht in BEIDEN Fällen die Differenz von 24h abziehen, logischerweise nur in dem Fall, in dem die Ausschaltzeit kleiner als die Startzeit ist.

Hier kann ich dir nicht folgen ?Warum wieso das ?:eek:
Weil m_startTime nicht in Sekunden, sondern in Doppelsekunden angegeben ist. Gleicher Grund wie für die Duration. (Siehe Aufgabenstellung, die asc oben nochmal zitiert hat). Du könntest auch mit getStartTime() arbeiten, dann sparst du dir das Umrechnen an dieser Stelle. (Naja, den Code, umgerechnet wird es trotzdem)
 

Alex33

Well-Known Member
#18
Ich habe für offtime ,duration eingetragen ?

Das klingt logisch oder?

Jetzt endlich richtig oder?:D



Code:
void CDimmerLogEntry::switchedOff()
{


    CTimeOfDay();
       CDimmerLogEntry::switchedOffAt(m_duration);

}


void CDimmerLogEntry::switchedOffAt(unsigned int offTime){


    if(m_startTime < offTime){

    m_duration = (offTime - m_startTime)/2;


    }
    if(m_startTime >offTime){

    m_duration = 86400-(m_startTime -offTime)/(2); //rechne das nochmal nach, das kann unmöglich richtig sein ;)
     // auch hier, warum /24? Ja war blöd gemerkt-


    }



}
 

-AB-

Well-Known Member
c-b Team
c-b Experte
#19
Öhm.... nee...

Erstmal passt der Datentyp schon nicht, switchedOffAt will einen unsigned int, und du übergibst einen unsigned short. Da müssten schon alle Alarmglocken läuten.

Welchen Wert hat denn m_duration, wenn du ihn switchedOffAt übergibst?

Erklär mir doch mal, was die Zeile CTimeOfDay(); macht.
 

Alex33

Well-Known Member
#20
unsigned int secsSinceMidnight soll ich das secs... übergeben?

switchedOffAt will einen unsigned int:

Daran hatte ich gar net gedacht:D

Das macht die Funktion:

* Erzeugt eine neue Zeitangabe aus der Angabe der
* seit Mitternacht vergangenen Sekunden.
*/
CTimeOfDay(unsigned int secsSinceMidnight);

Besser ?
 
Oben