Je suis en train de créer une méthode de conversion d'un nombre en notation scientifique normalisée, voici le code que j'utilise pour calculer mantisse et exposant:Convertir un nombre en notation scientifique normalisée
ConvNSN 1000, M, P
MsgBox M & "e" & P
Sub ConvNSN(N, M, P)
If N = 0 Then
P = 0
M = 0
Else
P = Int(Log(Abs(N))/Log(10))
M = N/10^P
End If
End Sub
Le problème Je fais face est que ce code donne une fausse valeur d'exposant pour certains nombres, par exemple 1000, 10E + 6, 10E + 9, 10E + 12, 10E + 13, etc ... Exactement pour 1000 converti devrait être 1e3, mais pas 10e2. Il est évident que le même problème avec les nombres, dont les logarithmes sont proches d'une valeur entière, comme Log(1 - 5.55111512312578E-17)/Log(10)
, qui résulte est 0, mais 1 - 5.55111512312578E-17
moins de 1, et le résultat doit être négatif.
Comment puis-je me débarrasser de Double
Imprécision type et obtenir ce code fonctionne correctement?
MISE À JOUR
Je suppose que la méthode la plus rapide et tout à fait exact de calculer mantisse et exposant du nombre en notation scientifique normalisée peut être la suivante:
Sub ConvNSN(N, M, P)
Dim A
If N = 0 Then
P = 0
M = 0
Exit Sub
End If
A = Abs(N)
If A < 1 Then
P = Int(Log(A)/Log(10))
Else
P = Int(Log(A)/Log(10) * (2 + Log(.1)/Log(10)))
End If
M = N/10^P
End Sub
Ou un autre, basé sur @ Bob solution:
Sub ConvNSN(N, M, P)
If N = 0 Then
P = 0
M = 0
Else
P = Int(Log(Abs(N))/Log(10))
M = N/10^P
End If
If Abs(M) = "10" Then
M = M/10
P = P + 1
End If
End Sub
Première légèrement plus rapide. Les deux traitent l'exposant de -322 à 308, mais retournent une mantisse non normalisée avec des puissances de 10 inférieures à -310. Je ne les ai pas encore testés avec des nombres, dont les logarithmes sont un peu plus faibles mais très proches des valeurs entières.
MISE À JOUR 2
j'ai décidé de joindre ici un Sub ConvEN()
supplémentaire, ce qui permet de représenter un nombre en notation d'ingénierie avec des préfixes SI de "p" à "T":
N = .0000456789
ConvNSN N, M, P
M = Round(M, 2)
ConvEN M, P, R, S
MsgBox R & " " & S & "Units"
Sub ConvNSN(N, M, P)
Dim A
If N = 0 Then
P = 0
M = 0
Exit Sub
End If
A = Abs(N)
If A < 1 Then
P = Int(Log(A)/Log(10))
Else
P = Int(Log(A)/Log(10) * (2 + Log(.1)/Log(10)))
End If
M = N/10^P
End Sub
Sub ConvEN(M, P, R, S)
DIM Q, P3
Q = int(P/3)
P3 = Q * 3
If Q >= -4 And Q <= 4 Then
S = Array("p", "n", ChrW(&H03BC), "m", "", "k", "M", "G", "T")(Q + 4)
Else
S = "e" & P3 & " "
End If
R = M * 10^(P - P3)
End Sub
Que se passerait-il si 'M> = 1 et M <= 10'? Essayez 'ConvNSN 5, M, P' – JosefZ
Les nombres compris entre 1 et 10 ne sont généralement pas écrits en notation scientifique. La notation scientifique est la façon dont les scientifiques manipulent facilement de très grands nombres ou de très petits nombres. – Bob
Semble 'Round()' pourrait être utile. J'ai noté 'NSN (1e-14, 15)' renvoie '10E-13'. La seule façon d'obtenir un résultat correct est de couper les derniers chiffres, donc 'NSN (1e-14, 14)' retourne '1E-14'. Il s'adapte si la haute précision n'est pas nécessaire (comme pour afficher les valeurs), puisque la machine epsilon pour 'Double' est' 1.11e-16'. J'ai aussi essayé 'ConvNSN 1000, M, P: MsgBox M &" E "& P', et il me donne toujours' 10E2' pour moi. – omegastripes