Hypercell ein ] Hypercell aus ] Zeige Navigation ] Verstecke Navigation ]
c++.de  
   

Die mobilen Seiten von c++.de:
http://m.c-plusplus.de
Infos hier [BETA]

  
c++.de ::  C++ (auch C++0x und C++11) ::  einzelne Ziffern einer Zahl auslesen
Antwort schreiben
Benutzername:
Titel:
Nachrichtentext:
  :)  :D  ;)  :(  :p  :mad:  :rolleyes:  :eek:  :confused:  :cool:  :o)  :leak:  :live:  :die:  :idea:  :arrow:  :warning: 
                             
                         
         
           
                             
                             
                             
             


BBCode in diesem Beitrag deaktivieren [BBCode]
Smilies in diesem Beitrag deaktivieren
einzelne Ziffern einer Zahl auslesen and 298088
     


Themen-Überblick 
(Aktualisieren)
Autor Nachricht
seldon
13:06:01 14.01.2012   Titel:   Zitieren

Ah. Ja, der Kommentar ist falsch. Gemeint ist 8 / (ln(10) / ln(2)).

ln(10) / ln(2) ist der Logarithmus von 10 zur Basis 2. Eine Zahl, die in Radix 10 mit n Ziffern darstellbar ist, ist in Basis 2 mit ungefähr ln(10) / ln(2) * n Ziffern darstellbar, das ist die Idee.
Ethon
13:00:16 14.01.2012   Titel:   Zitieren

Dann sollte man es schlicht mit numeric_limits versuchen bzw es einfach nachprogrammieren. Da gibts ja den digits-Member.
cooky451
12:50:27 14.01.2012   Titel:   Zitieren

Jo, das habe ich dann auch gemerkt. Wobei ich ln(10) / ln(2) immer noch nich so ganz nachvollziehen kann. Zumal das bei mir ~3.32 ergibt.
seldon
12:39:38 14.01.2012   Titel:   Zitieren

Da kommt die +3 her. sizeof(T) * 241 / 100 ist höchstens 1 unter der benötigten Ziffernzahl, dann +1, um immer genug zu haben, +1 für das Vorzeichen und +1 für den Sentinel. Bleibt sizeof(T) * 241 / 100 + 3.
cooky451
12:16:44 14.01.2012   Titel:   Zitieren

seldon schrieb:
Naja, wenn man schon davon ausgeht, dass Bytes immer 8 Bit breit sind, dann kann man auch die benötigte Bufferlänge direkt ausrechnen:
So etwas wollte ich auch gerade bauen, aber ich muss leider feststellen: 2 * 2.41 = 4.82 < 5. Habe ich mich irgendwie verrechnet?
Edit: Oups + 1 vergessen?
seldon
11:58:52 14.01.2012   Titel:   Zitieren

Naja, wenn man schon davon ausgeht, dass Bytes immer 8 Bit breit sind, dann kann man auch die benötigte Bufferlänge direkt ausrechnen:
C++:
template<int IntSize>
struct number_string_buffer {
  // ln(10) / ln(2) ~ 2.41
  char value[IntSize * 241 / 100 + 3];
};

Und wenn wir schon so weit sind, dann kann man sich auch die Mühe machen, die Umdreherei unnötig zu machen:
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
#include <iostream>
 
template<typename T>
class number_string_buffer {
public:
  number_string_buffer(T x) {
    value_ = buffer_.data + bufsize - 1;
    *value_ = '\0';
 
    // Wenn man signed-Datentypen auch erlaubt, muss ggf. ein Vorzeichen
    // behandelt werden.
    bool vz;
    if(x < 0) {
      vz = true;
      x = -x;
    } else {
      vz = false;
    }
 
    do {
      *--value_ = '0' + x % 10;
      x /= 10;
    } while(x != 0);
 
    if(vz) {
      *--value_ = '-';
    }
  }
 
  number_string_buffer(number_string_buffer const &other)
    : buffer_(other.buffer_),
      value_(buffer_.data + (other.value_ - other.buffer_.data))
  { }
 
  char const *value() const { return value_; }
 
private:
  // Wenn wir schon davon ausgehen, dass immer 1 Byte = 8 Bit:
  static int const bufsize = sizeof(T) * 241 / 100 + 3;
 
  struct { char data[bufsize]; } buffer_;
  char *value_;
};
 
template<typename T>
std::ostream &operator<<(std::ostream &out, number_string_buffer<T> const &buf) {
  return out << buf.value();
}
 
template<typename T>
number_string_buffer<T> to_digits(T x) { return number_string_buffer<T>(x); }
 
int main() {
  std::cout
    << to_digits(char(123)) << '\n'
    << to_digits(short(12345)) << '\n'
    << to_digits(int(1234567890)) << '\n'
    << to_digits(123456789012345ll) << '\n'
    ;
}

Jetzt sollte man natürlich eigentlich noch prüfen, ob T ein integraler Basistyp ist, aber das macht ohne Standardbibliothek nun wirklich keinen Spaß mehr.
Ethon__
10:47:28 14.01.2012   Titel:   Zitieren

Eigentlich genauso wie Cookie, nur ohne weiter über Funktionen nachzudenken, die zählen und einen dynamischen String anlegen.

Aber ich hab Cookies Lösung mal so angepasst wie ich es am Angenehmsten fände:

C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#include <iostream>
 
template<int IntSize>
struct number_string_buffer
{ };
 
template<>
struct number_string_buffer<1>
{
    char value[5];
};
 
template<>
struct number_string_buffer<2>
{
    char value[7];
};
 
template<>
struct number_string_buffer<4>
{
    char value[12];
};
 
template<>
struct number_string_buffer<8>
{
    char value[22];
};
 
template<typename IntT>
number_string_buffer<sizeof(IntT)> to_digits(IntT value)
{
    number_string_buffer<sizeof(IntT)> result;
    char* put = result.value, *begin = result.value;
 
    do
    {
        *put++ = '0' + value % 10;
        value /= 10;
    } while (value != 0);
   
    *put = '\0';
    while(put > begin) // std::reverse() oO
    {
        char c = *begin;
        *begin++ = *(--put);
        *put = c;
    }
   
    return result;
}
 
int main()
{
    std::cout   << to_digits(char(123)).value << '\n'
                << to_digits(short(12345)).value << '\n'
                << to_digits(int(1234567890)).value << '\n'
                << to_digits(123456789012345ll).value << '\n';
               
}
314159265358979
10:29:19 14.01.2012   Titel:   Zitieren

Zeig mir doch mal, wie du die Funktion nun schreiben würdest.
Ethon__
10:26:46 14.01.2012   Titel:   Zitieren

Statische Allokation im Gegensatz zur Dynamisch Allokation. Hat garnichts mit dem static-Keyword zu tun, an das du gerade denkst. ;)

C++:
char statisch[12]
char* dynamisch = new char[12];
314159265358979
10:21:43 14.01.2012   Titel:   Zitieren

Dein Vorschlag ist mit Abstand der schlechteste, da 1) Seiteneffekte und 2) nicht threadsafe. Ich würde es wie cooky machen.

Powered by phpBB © 2001, 2002 phpBB Group :: FI Theme

c++.de ist Teilnehmer des Partnerprogramms von Amazon Europe S.à.r.l. und Partner des Werbeprogramms, das zur Bereitstellung eines Mediums für Websites konzipiert wurde, mittels dessen durch die Platzierung von Werbeanzeigen und Links zu amazon.de Werbekostenerstattung verdient werden kann.

Die Vervielfältigung der auf den Seiten www.c-plusplus.de, www.c-plusplus.info und www.c-plusplus.net enthaltenen Informationen ohne eine schriftliche Genehmigung des Seitenbetreibers ist untersagt (vgl. §4 Urheberrechtsgesetz). Die Nutzung und Änderung der vorgestellten Strukturen und Verfahren in privaten und kommerziellen Softwareanwendungen ist ausdrücklich erlaubt, soweit keine Rechte Dritter verletzt werden. Der Seitenbetreiber übernimmt keine Gewähr für die Funktion einzelner Beiträge oder Programmfragmente, insbesondere übernimmt er keine Haftung für eventuelle aus dem Gebrauch entstehenden Folgeschäden.