Cet article suppose Ruby, mais je pense que la même chose peut être dite pour de nombreuses langues.
Il existe de nombreuses façons de savoir combien de chiffres un entier positif «x» aura en décimal. L'un d'eux
Math.log10(x).floor + 1
Cependant, est-il vraiment possible d'obtenir la bonne réponse? Même si vous n'êtes pas bon en maths, je vais l'examiner aussi attentivement que possible afin que vous puissiez le comprendre même si vous ne savez pas grand chose sur Ruby.
Cependant, si vous voulez juste connaître la conclusion, [Est-ce que ça va? ](#% E3% 81% 9D% E3% 82% 8C% E3% 81% A7% E3% 81% 84% E3% 81% 84% E3% 81% AE% E3% 81% 8B) ..
Dans cette section, on suppose que la variable locale «x» se voit attribuer un entier positif. Ruby peut gérer n'importe quel grand entier si les conditions telles que la mémoire le permettent.
Pour les entiers Ruby (classe Integer), générez une chaîne de nombres exprimés en notation N-aire [Integer # to_s](https://docs.ruby-lang.org/ja/2.7.0/method/Integer/i Il existe une méthode appelée /inspect.html).
Si vous omettez l'argument, vous obtenez une chaîne de nombres décimaux.
p (36 + 72).to_s # => "108"
D'autre part, la classe String a une méthode appelée String # length qui compte la longueur (nombre de caractères). Il y a.
p "Ruby".length # => 4
Si vous combinez cela
x.to_s.length
Vous pouvez obtenir le nombre de chiffres avec. C'est assez simple.
Cependant, je me sens un peu mal à l'aise. N'est-il pas lent de créer une énorme chaîne d'une longueur de 100 000 pour un entier de 100 000 chiffres lorsque vous voulez simplement connaître le nombre de chiffres? C'est en fait assez rapide, mais laissons cette histoire de côté.
Ruby renvoie un tableau du nombre de chaque chiffre lorsqu'un entier non négatif (un entier supérieur ou égal à 0) est exprimé en notation N-aire Integer # digits Il existe une méthode appelée /2.7.0/method/Integer/i/digits.html).
Si l'argument est omis, il est en notation décimale.
p 1234.digits # => [4, 3, 2, 1]
Puisqu'ils sont disposés dans l'ordre à partir du bas, l'ordre d'apparition est inversé.
Si vous utilisez ceci et Array # length qui renvoie la longueur du tableau
x.digits.length
Vous pouvez obtenir le nombre de chiffres avec.
Mystery était l'idée d'un amateur, "D'une manière ou d'une autre, les entiers semblent être plus rapides que les chaînes de caractères, alors pourquoi ne pas être plus rapide que x.to_s.length
?", Mais ce n'était pas le cas. C'est vrai. Un énorme tableau est créé.
Il existe d'autres moyens, mais le sujet principal
Math.log10(x).floor + 1
Allons à. Pourquoi cela me donne-t-il le nombre de chiffres dans «x»?
Math.log10 est une méthode qui renvoie la valeur de la valeur logarithmique commune de l'argument donné.
Fonction logarithmique commune
y = \log_{10}x
Est une fonction exponentielle avec 10 comme base
x = 10^y
C'était la fonction inverse de. Cette fonction exponentielle est facile à comprendre lorsque $ y $ est un entier, mais elle est également définie pour tout nombre réel.
Voyons quand $ y $ est un entier supérieur ou égal à 0
À partir de là, on peut voir que lorsque $ y $ est un entier supérieur ou égal à 0, $ y + 1 $, c'est-à-dire que $ \ log_ {10} (x) + 1 $ est le nombre de chiffres.
Cependant, $ x $, où $ y $ est un entier, est limité. Qu'en est-il de l'entier positif le plus courant $ x $?
À titre d'essai, considérez $ x = 999 $. C'est un peu moins de 1000
Utilisez la fonction floor
[^ fl]: Notez que pour les nombres négatifs, «-1.1.floor» est «-2», et non «-1» avec la partie fractionnaire tronquée.
À propos, dans les symboles mathématiques, il semble que la fonction de plancher soit écrite comme $ \ lfloor a \ rfloor $, mais à partir de la considération ci-dessus, lorsque $ x $ est de 100 $ ou plus et de 999 $ ou moins,
\lfloor \log_{10}x \rfloor
S'avère être tout 2 $ $. En d'autres termes, cela ressemble à ceci.
Vous pouvez donc obtenir le nombre de chiffres en ajoutant 1 à $ \ lfloor \ log_ {10} x \ rfloor + 1 $. Mathématiquement.
Enfin au cœur.
Si vous écrivez $ \ lfloor \ log_ {10} x \ rfloor + 1 $ en code Ruby
Math.log10(x).floor + 1
Cependant, je me sens un peu mal à l'aise. C'était le but de cet article.
C'est parce que Math.log10
est une opération en virgule flottante de la classe Float. Les opérations en virgule flottante sont généralement accompagnées d'erreurs.
Est-il possible que les chiffres résultants soient dans le désordre en raison d'erreurs subtiles?
A quoi dois-je penser?
Où le chiffre change-t-il lorsque l'on regarde l'entier positif «x» dans l'ordre 1, 2, 3, ...? Bien sûr, c'est 9 → 10 ou 99 → 100 ou 999 → 1000. Si une erreur dans une opération de nombre à virgule flottante produit un résultat incorrect, c'est probablement à cette limite. Il est possible que quelque chose comme 10000000 soit par erreur un chiffre de moins, ou quelque chose comme 9999999999 soit fait par erreur un chiffre supplémentaire. Parmi ceux-ci, des nombres tels que 1000000 sont à l'origine sous la forme de $ 10 ^ k $, donc je pense qu'il est peu probable que des erreurs se produisent. Ensuite, expérimentons avec le nombre de 9.
Oui, j'ai écrit ce code.
1.upto(100) do |k|
puts "%3d %3d" % [k, Math.log10(10 ** k - 1).floor + 1]
end
Changez $ k $ de 1 à 100 pour calculer les chiffres de 10 $ ^ k -1 $ (c'est-à-dire le nombre de 9 arrangés en $ k $). Affichez ceci côte à côte avec $ k $. C'est une correspondance mathématique, alors voyez si les mêmes nombres sont alignés.
Le résultat est le suivant
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
C'est hors du milieu. Voici un extrait.
14 14
15 16
Jusqu'à 10 $ ^ {14} ―― 1 $ peuvent être calculés correctement, mais à 10 $ ^ {15} ―― 1 $, comme prévu, le nombre est un plus grand que la bonne réponse.
Il y avait quelque chose qui m'est venu à l'esprit ici. "La précision des nombres à virgule flottante est d'environ 15 chiffres en décimal", a-t-il déclaré. Ruby Float est en fait dépendant de l'environnement, donc la précision ne peut pas être déclarée sans équivoque, mais c'est IEEE dans un grand nombre d'environnements. Il semble que 754 "double précision" soit utilisé. Dans ce cas, la précision est d'environ 15 chiffres en décimal.
Par conséquent, il est tout à fait possible que le résultat de Math.log10 (x) .floor + 1
avec un entier de 15 9s ne soit pas le nombre correct de chiffres.
Pour les petits entiers, Math.log10 (x) .floor + 1
convient, mais pour les grands entiers, il y a une erreur.
Recommended Posts