Schwachsinniger Code für Zwischendurch



  • @nameless:
    ah, das gefaellt mir sehr gut.



  • @nameless
    Exakt die selben defines habe ich auch ausprobiert.

    Das einzige was mich daran stört ist, dass ich hier beliebig mischen kann:
    double d = 1 Hundred + 1 Thousand; -> Das könnte man als Hunderttausend interpretieren, deshalb führt sowas in meinem Ansatz zu einem Compiler-Fehler.
    Genauso wie die Wiederholung:
    double d = 1 Hundred + 1 Hundred + 1 Million + 1 Hundred;

    Das ist irgendwie unintuitiv. Die Templates zwingen mich immer zu einer absteigenden Anordnung ohne Wiederholung.

    Naja, vergleicht man aber Aufwand und Nutzen, dann ist die define-Variante weit vorn 🙂



  • HumeSikkins schrieb:

    Money price = 2000000000.0;
    oder:
    Money salary = 2000000.0;
    Nun neige ich dazu mich bei den vielen Nullen zu vertippen, also wollte ich die magischen Zahlen durch symbolische Konstanten ersetzen. So in etwa:
    Money price = 2 Billion;

    ja, das würde mich auch stören. deswegen hab ich auswendig gelernt, daß ne milliarde 9 und ne million 6 hat.
    Money price = 2e9;
    oder:
    Money salary = 2e6;
    man kann damit sogar in maßen mischen!
    Money salery = 2.345e6;
    oder für freaks:
    Money Salery = 2e9 + 345e6;



  • Shade Of Mine schrieb:

    Number(2,356,000);
    geht aber leider nicht - man muesste die fuehrenden 0 irgendwie wegbekommen...

    Ich denke, es geht: Zwischen zwei Kommas stehen immer 3 Stellen. Man muss also mit dem ganzen va_arg-Scheiß die "Ziffern" im 1000-er-System auswerten. Oder ohne va_arg geht wohl auch. Mit entsprechend überladenen Operatoren:
    Number/2,000,000. Die Klasse muss natürlich auch operator int() etc. haben...
    Der Fantasie sind keine Grenzen gesetzt.



  • So. Jetzt hab ich das auch implementiert...

    #include <iostream>
    
    using namespace std;
    
    class Number_t { 
    	int v; 
    public:
    	Number_t(int vv = 0) : v(vv) {}
    	Number_t operator/(int o) {
    		return o;
    	}
    	Number_t operator,(int o) {
    		return v * 1000 + o;
    	}
    	friend ostream &operator<<(ostream &s, Number_t n) {
    		s << n.v;
    	}
    	operator int() { return v; }
    } Number;
    
    int main() {
    	cout << (Number/25,000,456) << endl;
    }
    

    Und wer jetzt Bedenken wegen der Performance hat... der Compiler ist wunderbar in der Lage, das zu wegzuoptimieren.



  • HumeSikkins schrieb:

    Das einzige was mich daran stört ist, dass ich hier beliebig mischen kann:
    double d = 1 Hundred + 1 Thousand; -> Das könnte man als Hunderttausend interpretieren

    sorry aber die argumentation versteh ich nicht...
    wenn ich "1 Hundred + 1 Thousand" stehen seh dann is das für mich ne rechnung deren ergebniss 1100 ist und das als hundertausend zu interpretieren ist doch sehr weit hiergeholt, oder?
    die makros erlauben es ja sogar "1 Hundred Thousand" zu schreiben und es kommt 100'000 raus wie man er erwarten würde.



  • sorry aber die argumentation versteh ich nicht...

    Keiner verlangt von dir meinen beschränkten Verstand zu verstehen.
    Und das er beschränkt ist, hat mir Volkard mal wieder eindrücklich gezeigt. Seine Lösung ist genau die Offensichtliche, deren Existenz ich vermutete, die ich aber nicht finden konnte.



  • Hat jemand außer volkard schon meinen Denkfehler entdeckt?



  • int i = 2;
    cout << ((Number/25,000,000) / i) << endl;
    

    Liefert irgendwie nicht das Erwartete.



  • Hat jemand außer volkard schon meinen Denkfehler entdeckt?

    Du dachtest, du hättest funktionsfähigen C++ Code gepostet?
    😃



  • nee, viel lustiger.

    cout << (Number/2,468,024) << endl;
    

    das ding gibt nicht 2468024 aus.



  • HumeSikkins schrieb:

    Du dachtest, du hättest funktionsfähigen C++ Code gepostet?
    😃

    Du dachtest ich hätte gedacht? 🤡



  • volkard schrieb:

    cout << (Number/2,468,024) << endl;
    

    das ding gibt nicht 2468024 aus.

    *plonk*
    Logisch. 🙂



  • Und das er beschränkt ist, hat mir Volkard mal wieder eindrücklich gezeigt. Seine Lösung ist genau die Offensichtliche, deren Existenz ich vermutete, die ich aber nicht finden konnte.

    Oh. Ich dachte am anfang du würdest das ausschreiben, weil dir diese schreibweise nicht gefällt.

    Falls Geschwindigkeit nicht ganz so wichtig ist, könnte man ja auch einen string paresen. Dann hat man sowas Money("2.332.1213,12") oder so.



  • Was haltet ihr davon:

    #include <iostream>
    #include <cassert>
    using namespace std;
    
    class Number
    {
    public:
    	Number(unsigned int n) : _n(n) {}
    	Number operator()(Number i) const
    	{
    		assert(i._n <= _n);
    		return _n + i._n;
    	}
    	unsigned int operator()(unsigned int i = 0) const
    	{
    		assert(i < 1000);
    		return _n + i;
    	}
    private:
    	const unsigned int _n;
    };
    
    template <int n> class Number_temp {};
    
    template <int n>
    Number operator*(int i, Number_temp<n>)
    {
    	assert(i < 1000);
    	return n * i;
    }
    
    #define Billion   * Number_temp<1000000000>())(
    #define Million   * Number_temp<1000000>())(
    #define Thousand  * Number_temp<1000>())(
    
    int main()
    {
             // Funktioniert
    	unsigned int MyNumber1 = Number(1 Billion 20 Million 24 Thousand 123);
    	unsigned int MyNumber2 = Number(123 Million);
             // Wird als falsch erkannt:
    	unsigned int MyNumber3 = Number(50 Million 1 Billion);
             // Auch falsch
    	unsigned int MyNumber4 = Number(1 Billion 20 Million 24 Thousand 1892);
             // Auch falsch
    	unsigned int MyNumber5 = Number(1 Billion 1 Billion 24 Thousand 123);
             // Auch falsch
    	unsigned int MyNumber5 = Number(1 Billion 5950 Thousand 123);
    
    	cout << MyNumber1 << endl;
    	return 0;
    }
    

    Die Zahleneingabe ist intuitiv wie bei der reinen Makro-Variante, plus eine Fehlererkennung. 🙂
    Falsche Zahlen werden allerdings erst zur Laufzeit durch die Asserts erkannt.



  • Vielleicht geht's ja wirklich nur mir so, aber ich finde "123456789.12" ja noch übersichtlicher als "123 Milion 456 Thousand 769.12". Und da eine englische eingaber scheibar gefordert ist kann man meinen vorgeschlagenen Parser ja anpassen Money("123,456,789.12").

    Vor allem solche angaben sind doch bei euch immer noch möglich: 1 Million 5000 Thousand. Soll heißen 6 Millionen.



  • @Helium
    Die String-Variante ist in meiner Money-Klasse bereits drin. Natürlich mit wählbarem Grouping und Thousand-Seperator 😉



  • Frei nach Asterix: Die spinnen, die cpp-ler *g*



  • cd9000 schrieb:

    Was haltet ihr davon:
    unsigned int MyNumber5 = Number(1 Billion 1 Billion 24 Thousand 123);

    auch das ist meines erachtens nach zu gefährlich wegen
    unsigned int gibi1 = 1073741824;
    unsigned int gibi2 = Number(1 Billion 073 Million 741 Thousand 824);
    und der rätselhaften ausgabe von cout<<gibi2; mit 1059741824
    und wer läßt schon gerne auf solcherlei weise 14 millionen verschwinden?



  • Wer würde bei dieser Syntax schon Oktalzahlen schreiben?

    Dann kann man es auch gleich so machen:

    class Number
    {
      public: Number(const std::string&);
    };
    #define Number(n) Number("n")
    

    Und im Parser Oktalzahlen korrigieren. 😉


Anmelden zum Antworten