[RUBY] Kann die Anzahl der Ziffern Math.log10 (x) .floor + 1 sein?

Dieser Artikel geht von Ruby aus, aber ich denke, dasselbe gilt für viele Sprachen.

Worüber redest du?

Es gibt viele Möglichkeiten herauszufinden, wie viele Stellen eine positive Ganzzahl x dezimal haben wird. Einer von ihnen

Math.log10(x).floor + 1

Ist es jedoch wirklich möglich, die richtige Antwort zu erhalten? Selbst wenn Sie nicht gut in Mathe sind, werde ich es mir so genau wie möglich ansehen, damit Sie es verstehen können, auch wenn Sie nicht viel über Ruby wissen.

Wenn Sie jedoch nur die Schlussfolgerung wissen möchten, [Ist das in Ordnung? ](#% E3% 81% 9D% E3% 82% 8C% E3% 81% A7% E3% 81% 84% E3% 81% 84% E3% 81% AE% E3% 81% 8B) ..

Verschiedene Möglichkeiten, um die Anzahl der Ziffern zu ermitteln

In diesem Abschnitt wird davon ausgegangen, dass der lokalen Variablen "x" eine positive Ganzzahl zugewiesen ist. Ruby kann jede große Ganzzahl verarbeiten, wenn Bedingungen wie der Speicher dies zulassen.

Stringifizierung

Generieren Sie für Ruby-Ganzzahlen (Integer-Klasse) eine Zeichenfolge in N-ary-Notation Integer # to_s Es gibt eine Methode namens /inspect.html).

Wenn Sie das Argument weglassen, erhalten Sie eine Folge von Dezimalzahlen.

p (36 + 72).to_s # => "108"

Andererseits verfügt die String-Klasse über eine Methode namens String # length, die die Länge (Anzahl der Zeichen) zählt. Es gibt.

p "Ruby".length # => 4

Wenn Sie dies kombinieren

x.to_s.length

Sie können die Anzahl der Ziffern mit abrufen. Es ist ziemlich einfach.

Ich fühle mich jedoch etwas unwohl. Ist es nicht langsam, eine große Zeichenfolge mit einer Länge von 100.000 für eine 100.000-stellige Ganzzahl zu erstellen, wenn Sie nur die Anzahl der Ziffern wissen möchten? Es ist eigentlich ziemlich schnell, aber lassen wir diese Geschichte beiseite.

Holen Sie sich ein Array von Ziffern für Ziffern

Ruby gibt ein Array mit der Nummer jeder Ziffer zurück, wenn eine nicht negative Ganzzahl (eine Ganzzahl größer oder gleich 0) in N-facher Notation Integer # digits ausgedrückt wird. Es gibt eine Methode namens /2.7.0/method/Integer/i/digits.html).

Wenn das Argument weggelassen wird, erfolgt es in Dezimalschreibweise.

p 1234.digits # => [4, 3, 2, 1]

Da sie von unten in der Reihenfolge angeordnet sind, ist die Reihenfolge des Auftretens umgekehrt.

Wenn Sie dies und Array # length verwenden, wird die Länge des Arrays zurückgegeben

x.digits.length

Sie können die Anzahl der Ziffern mit abrufen.

Das Geheimnis war die Idee eines Amateurs: "Irgendwie scheinen ganze Zahlen schneller zu sein als Zeichenketten. Warum also nicht schneller als" x.to_s.length "?", Aber das war nicht der Fall. Korrekt. Ein riesiges Array wird erstellt.

Und Math.log10 (x) .floor + 1

Es gibt andere Möglichkeiten, aber das Hauptthema

Math.log10(x).floor + 1

Lass uns gehen zu. Warum gibt mir das die Anzahl der Ziffern in "x"?

Math.log10 ist eine Methode, die den Wert des allgemeinen logarithmischen Werts eines bestimmten Arguments zurückgibt.

Gemeinsame logarithmische Funktion

y = \log_{10}x

Ist eine Exponentialfunktion mit 10 als base </ ruby>

x = 10^y

Es war die umgekehrte Funktion von. Diese Exponentialfunktion ist leicht zu verstehen, wenn $ y $ eine ganze Zahl ist, sie wird jedoch auch für jede reelle Zahl definiert.

Mal sehen, wann $ y $ eine ganze Zahl größer oder gleich 0 ist

y = \log_{10}x x = 10^y
0 1
1 10
2 100
3 1000
4 10000

Daraus ist ersichtlich, dass, wenn $ y $ eine ganze Zahl größer oder gleich 0 ist, $ y + 1 $, dh $ \ log_ {10} (x) + 1 $, die Anzahl der Ziffern ist.

$ X $, wobei $ y $ eine ganze Zahl ist, ist jedoch begrenzt. Was ist mit der häufigeren positiven Ganzzahl $ x $?

Betrachten Sie als Test $ x = 999 $. Dies ist etwas weniger als $ 1000 . Da die logarithmische Funktion monoton zunimmt ( y $ steigt mit zunehmendem $ x $), sollte $ \ log_ {10} 999 $ ** etwas kleiner ** als $ 3 $ sein. Wenn Sie es daher durch ** Kürzung ** in eine Ganzzahl konvertieren, erhalten Sie $ 2 $.

Verwenden Sie zum Abschneiden die Funktion floor Yuka </ ruby>. Dies schneidet die Gewinnchancen links von der geraden Zahl ab (negative Unendlichkeit). In diesem Fall werden keine negativen Zahlen angezeigt, sodass Sie sich das als "Abschneiden des Bruchteils" [^ fl] vorstellen können.

[^ fl]: Beachten Sie, dass für negative Zahlen "-1.1.floor" "-2" ist, nicht "-1", wobei der Bruchteil abgeschnitten ist.

Übrigens scheint es in mathematischen Symbolen so zu sein, dass die Bodenfunktion als $ \ lfloor a \ rfloor $ geschrieben ist, aber aus der obigen Überlegung, wenn $ x $ 100 $ oder mehr und 999 $ oder weniger ist,

\lfloor \log_{10}x \rfloor

Es stellt sich heraus, dass alle $ 2 $ sind. Mit anderen Worten, es sieht so aus.

x \lfloor \log_{10}x \rfloor
19 0
1099 1
100999 2
10009999 3
1000099999 4

Sie können also die Anzahl der Ziffern ermitteln, indem Sie 1 zu $ \ lfloor \ log_ {10} x \ rfloor + 1 $ hinzufügen. Mathematisch.

Ist das in Ordnung?

Endlich im Kern.

Wenn Sie $ \ lfloor \ log_ {10} x \ rfloor + 1 $ in Ruby-Code schreiben

Math.log10(x).floor + 1

Ich fühle mich jedoch etwas unwohl. Darum ging es in diesem Artikel.

Das liegt daran, dass Math.log10 eine Gleitkommaoperation der Float-Klasse ist. Gleitkommaoperationen gehen normalerweise mit Fehlern einher. Ist es möglich, dass die resultierenden Ziffern aufgrund subtiler Fehler nicht in Ordnung sind?

Woran soll ich denken?

Wo ändert sich die Ziffer, wenn man die positive ganze Zahl "x" in der Reihenfolge 1, 2, 3, ... betrachtet? Natürlich ist es 9 → 10 oder 99 → 100 oder 999 → 1000. Wenn ein Fehler in einer Gleitkommazahloperation zu einem falschen Ergebnis führt, liegt er wahrscheinlich an dieser Grenze. Es ist möglich, dass etwas wie 10000000 fälschlicherweise eine Ziffer weniger oder etwas wie 9999999999 fälschlicherweise eine weitere Ziffer gemacht wird. Von diesen Zahlen wie 1000000 sind ursprünglich $ 10 ^ k $, daher halte ich es für unwahrscheinlich, dass Fehler auftreten. Dann experimentieren wir mit der Zahl 9s.

Ja, ich habe diesen Code geschrieben.

1.upto(100) do |k|
  puts "%3d %3d" % [k, Math.log10(10 ** k - 1).floor + 1]
end

Ändern Sie $ k $ von 1 auf 100, um die Ziffern von $ 10 ^ k -1 $ (dh $ k $ von 9s) zu berechnen. Zeigen Sie diese Seite an Seite mit $ k $ an. Es ist eine mathematische Übereinstimmung, also sehen Sie, ob die gleichen Zahlen in einer Reihe stehen.

Das Ergebnis ist wie folgt

  1   1
  2   2
  3   3
  4   4
  5   5
  6   6
  7   7
  8   8
  9   9
 10  10
 11  11
 12  12
 13  13
 14  14
 15  16
 16  17
 17  18
 18  19
 19  20
 20  21
 21  22
 22  23
 23  24
 24  25
 25  26
 26  27
 27  28
 28  29
 29  30
 30  31
 31  32
 32  33
 33  34
 34  35
 35  36
 36  37
 37  38
 38  39
 39  40
 40  41
 41  42
 42  43
 43  44
 44  45
 45  46
 46  47
 47  48
 48  49
 49  50
 50  51
 51  52
 52  53
 53  54
 54  55
 55  56
 56  57
 57  58
 58  59
 59  60
 60  61
 61  62
 62  63
 63  64
 64  65
 65  66
 66  67
 67  68
 68  69
 69  70
 70  71
 71  72
 72  73
 73  74
 74  75
 75  76
 76  77
 77  78
 78  79
 79  80
 80  81
 81  82
 82  83
 83  84
 84  85
 85  86
 86  87
 87  88
 88  89
 89  90
 90  91
 91  92
 92  93
 93  94
 94  95
 95  96
 96  97
 97  98
 98  99
 99 100
100 101

Es ist aus der Mitte. Hier ist ein Auszug.

 14  14
 15  16

Bis zu $ 10 ^ {14} ―― 1 $ können korrekt berechnet werden, aber bei $ 10 ^ {15} ―― 1 $ ist die Zahl erwartungsgemäß um eins größer als die richtige Antwort.

Hier kam mir etwas in den Sinn. "Die Genauigkeit von Gleitkommazahlen beträgt etwa 15 Dezimalstellen", sagte er. Rubys Float ist tatsächlich umweltabhängig, daher kann die Genauigkeit nicht eindeutig angegeben werden, es handelt sich jedoch um IEEE in einer großen Anzahl von Umgebungen. Es scheint, dass 754 "doppelte Genauigkeit" verwendet wird. In diesem Fall beträgt die Genauigkeit etwa 15 Dezimalstellen.

Daher ist es durchaus möglich, dass das Ergebnis von "Math.log10 (x) .floor + 1" mit einer Ganzzahl von 15 9s nicht die richtige Anzahl von Ziffern war.

Fazit

Für kleine Ganzzahlen ist "Math.log10 (x) .floor + 1" in Ordnung, für große Ganzzahlen liegt jedoch ein Fehler vor.

Recommended Posts

Kann die Anzahl der Ziffern Math.log10 (x) .floor + 1 sein?
Zählen Sie die Anzahl der Stellen nach dem Dezimalpunkt in Java
Anzahl der Ziffern des numerischen Typs
So bestimmen Sie die Anzahl der Parallelen
Über die Anzahl der Threads von Completable Future
[Java] Überprüfen Sie die Anzahl der Zeichen
[Java] Achten Sie auf den Schlüsseltyp der Karte
Ich habe die Anzahl der Taxis mit Ruby überprüft