Nachkommastellen auf 2 Stellen begrenzen



  • Hallo ich möchte bei folgender Operation die Nachkommastellen vom Ergebnis auf 2 Stellen begrenzen. Ich habe schon vieles ausprobiert aber es kommen immer Fehlermeldung. Falls ihr ne Lösung habt bitte auch sagen, an welchen Stellen ich den Code editieren muss bzw. hinzufügen muss.

    Hier ist der Code:

    void __fastcall TForm1::Label1Click(TObject *Sender)
    {
    Label1->Caption = FloatToStr(StrToFloat(Edit1->Text) * 100 / StrToFloat(Edit2->Text));	
    }
    

    Ich bedanke mich.



  • Hallo

    Schau dir in der Builder-Hilfe die Funktionen FloatToStrF und FormatFloat an.

    bis bald
    akari



  • siehe FormatFloat

    string FormatFloat(string Formatconst, Extended Value);
    

    ops etwas langsam lol



  • ich habe mir schon die alles möglich mit Format, sprintf, precision und und und angeguckt, aber immer wenn ich die jeweiligen Beispiele an meinem Programm anwende gibt es eine Fehlermeldung.
    Könntet ihr so nett sein und mal den jeweiligen Code in meinem Programm ergänzen?!
    Ich werde dann eine Rückmeldung geben, ob es geklappt hat. Die anderen hätten ja auch was davon



  • vom Vorsagen hat niemand was ...

    was und wie genau hast du versucht?
    welche Fehlermeldung kommt?
    hast du dir die Funktion FloatToStrF in der BCB-Hilfe mal angeschaut?

    falls dir die Fragen zu schwer sind nutz doch einfach mal die Suchfunktion mit einem der Begriffe



  • Wie wäre es eigentlich mit:

    SimpleRoundTo(DeinFloat, -2)
    

    Gruß myerscola



  • Falls Du nur die Anzeige gerundet haben willst, oder den Quotient als %- Anzeige, nimm doch TDecimalLabel.

    Der:
    rundet jeden Dezimalwert auf wählbare Stellenzahl.
    Rechnet um in Prozent- Anzeige mit Dezimalstellen freier Wahl.
    ! In Caption steht aber immer noch der Originalwert zum Weiterverwenden.
    ! Die Umrechnug erfolgt NUR für die Anzeige.

    Vor und hinter den Wert kann noch Text gesetzt werden.

    Wenn Du das zu einer Komponente machst, kann das Teil beliebig oft bequem verwendet werden.

    [Nicht wundern über den Namen DirLabel.cpp, das ist aus einer Sammlung von verschiedenen, formatierenden Labels.]

    Versuch mal rauszubekommen, wie das Teil funktioniert, dann haste auch noch was gelernt.

    //Header- Datei der Komponente
    //
    //DirLabel.h
    
    #ifndef DirLabelH
    #define DirLabelH
    //---------------------------------------------------------------------------
    #include <SysUtils.hpp>
    #include <Controls.hpp>
    #include <Classes.hpp>
    #include <Forms.hpp>
    #include <StdCtrls.hpp>
    //---------------------------------------------------------------------------
    
    class  PACKAGE TDecimalFormat : public TPersistent
    {
    private:
      Boolean FOnlyValues;
      Boolean FIsDecimal;
      Boolean FPercent;
      AnsiString FPrefix,FSuffix;
      AnsiString FFormStr;
    public:
      __fastcall TDecimalFormat(void);
    protected:
      void __fastcall SetFIsDecimal(Boolean Value);
    __published:
      __property Boolean IsDecimal={read=FIsDecimal};
      __property Boolean Percent={read=FPercent,write=FPercent,default=false};
      __property Boolean OnlyValues={read=FOnlyValues,write=FOnlyValues,default=false};
      __property AnsiString Prefix={read=FPrefix,write=FPrefix};
      __property AnsiString Suffix={read=FSuffix,write=FSuffix};
      __property AnsiString FormStr={read=FFormStr,write=FFormStr};
    };
    //---------------------------------------------------------------------------
    class PACKAGE TDecimalLabel : public TLabel
    {
    private:
           TDecimalFormat *FDecimalFormat;
           virtual System::AnsiString __fastcall GetLabelText();
    protected:
           void __fastcall WndProc(TMessage& Msg);
    public:
            __fastcall TDecimalLabel(TComponent* Owner);
            __fastcall ~TDecimalLabel();
    __published:
      __property TDecimalFormat *Format={read=FDecimalFormat,write=FDecimalFormat};
    };
    //---------------------------------------------------------------------------
    #endif
    
    //***************************************************************************
    //***************************************************************************
    
    //CPP- Datei der Komponente
    //
    //DirLabel.cpp
    
    #include <vcl.h>
    #pragma hdrstop
    
    #include "DirLabel.h"
    #pragma package(smart_init)
    
    __fastcall TDecimalFormat::TDecimalFormat(void)
                              :TPersistent()
    {
      FOnlyValues=false;
      FIsDecimal=false;
      FPrefix="";
      FSuffix="";
      FFormStr="#,##0.0";
      FPercent=false;
    }
    //---------------------------------------------------------------------------
    void __fastcall TDecimalFormat::SetFIsDecimal(Boolean Value)
    {
      FIsDecimal=Value;
    }
    //---------------------------------------------------------------------------
    static inline void ValidCtrCheck(TDecimalLabel *)
    {
            new TDecimalLabel(NULL);
    }
    //---------------------------------------------------------------------------
    __fastcall TDecimalLabel::TDecimalLabel(TComponent* Owner)
            : TLabel(Owner)
    {
      FDecimalFormat=new TDecimalFormat();
    }
    //---------------------------------------------------------------------------
    __fastcall TDecimalLabel::~TDecimalLabel()
    {
      delete FDecimalFormat;
    }
    //---------------------------------------------------------------------------
    void __fastcall TDecimalLabel::WndProc(TMessage& Msg)
    { AnsiString NewCaption;
      if (Msg.Msg==WM_SETTEXT)
      { NewCaption=AnsiString((char*)Msg.LParam).Trim();
        try
        {
          NewCaption.ToDouble();
          FDecimalFormat->SetFIsDecimal(true);
        }
        catch(...)
        {
          FDecimalFormat->SetFIsDecimal(false);
        }
        if (FDecimalFormat->OnlyValues)
        {
          if (FDecimalFormat->IsDecimal)
          {
            TLabel::WndProc(Msg);
          }
          else
          {
            //Aenderung ignorieren
          }
        }
        else
        {
          TLabel::WndProc(Msg);
        }
      }
      else
      { TLabel::WndProc(Msg);
      }
    }
    //---------------------------------------------------------------------------
    System::AnsiString __fastcall TDecimalLabel::GetLabelText()
    {
      AnsiString ValStr;
      if (FDecimalFormat->IsDecimal)
      {
        ValStr=Caption.Trim();
        if (FDecimalFormat->Percent)
        { ValStr=ValStr.FormatFloat(FDecimalFormat->FormStr,ValStr.ToDouble() * 100) + "%";
        }
        else
        { ValStr=ValStr.FormatFloat(FDecimalFormat->FormStr,ValStr.ToDouble());
        }
        return FDecimalFormat->Prefix + ValStr + FDecimalFormat->Suffix;
      }
      else
      { if (FDecimalFormat->OnlyValues)
        {  return "NoValue";
        }
        else
        { return FDecimalFormat->Prefix + Caption + FDecimalFormat->Suffix;
        }
      }
    }
    //---------------------------------------------------------------------------
    


  • danke für die Antworten. werde es mal testen vor allem den letzten Beitrag von "DerAltenburger" und hier berichten...



  • Hi Leute,

    hab mal bissl experimentiert und nun habe ich die richtige - und denke auch- die einfachste Lösung für das obige Problem:

    void __fastcall TForm1::Label1Click(TObject *Sender)
    {
    Label1->Caption = FloatToStr(StrToFloat(Edit1->Text) * 100 / StrToFloat(Edit2->Text));
    Label1->Caption = FormatFloat("#0.00",StrToFloat(Label1->Caption));
    }
    

    Dann noch eine Frage zu "DerAltenburger":
    warum soviel code wenn es einfacher geht??



  • Was hast Du eigentlich gegen diese Lösung? Da reicht eine Zeile.

    Label1->Caption = SimpleRoundTo(StrToFloat(Edit1->Text) * 100 / StrToFloat(Edit2->Text), -2);
    

    Gruß myerscola



  • oder

    Label1->Caption = FloatToStrF(StrToFloat(Edit1->Text) * 100 / StrToFloat(Edit2->Text), ffFixed, 8, 2);
    

    Ich würde das ganze aber noch in einen try/catch-Block einschliessen um Umwandlungsfehler abzufangen.



  • ja toll Leute,

    ich hatte euch um Hilfe gebeten, ob ihr mal an den jeweiligen Stellen den Code ergänzen könnt. da konntet ihr mir nix sagen, jetzt auf einmal, wo ich das Problem gelöst habe, kommt ihr auf die tour "warum machst du das nicht so etc..."



  • Tja, so ist das nun mal. 😉
    Der Hintergrund ist, das hier primär Hilfe zur Selbsthilfe gegeben wird. Du hast Dir eine funktionierende Lösung selbst erarbeitet und nun zeigt man Dir die Alternativen.
    DerAltenburger hat eine komplette Klasse vorgestellt, die schon ein bißchen mehr kann, als nur runden. So eine Klasse kann sehr hilfreich sein, wenn viele Werte anzuzeigen sind.
    Bei der Version von myerscola musst allerdings beachten, dass, wenn sie nicht wie hier gezeigt, auf einen temporären Wert angewendet wird, der Wert selbst auf 2 Stellen gerundet wird, und nicht nur die Ausgabe. Bei den anderen Alternativen wird nur die Ausgabe manipuliert, nicht der Wert selbst.



  • kenux schrieb:

    Dann noch eine Frage zu "DerAltenburger":
    warum soviel code wenn es einfacher geht??

    Wie Joe_M schon sagte: Das kann noch etwas mehr!
    - Formatiert NUR die Anzeige
    - kontrolliert, ob Text als Zahl darstellbar ist
    - rechnet ev. in % um
    - erlaubt bequeme Formateinstellung
    - erlaubt Voranstellen und Nachstellen von Text

    Macht schon Sinn, wenn das oft im Formular benötigt wird.

    UND:
    Das macht in keinem Programm, wo das eingesetzt wird viel Umstände, auch wenn alle Werte jeweils anders darzustellen sind.

    UND:
    Das geht auch für Integer, Winkelangaben, Verzeichnispfade/ Dateinamen mit Längenoptimierung. Dazu muss nur jeweils eine ähnliche Kompo draus gemacht werden mit den nötigen Änderungen => Nie wieder Ärger/ Arbeit mit formtierten Anzeigen.

    Gruss
    Frank


Anmelden zum Antworten