Blairn said:
I don't know whether you have solved this question but I use the
following and I haven't broken it yet:
Y: Round(X/10^(Int(Log(Abs(X)/Log(10))-(W-1)))*10^(Int(Log(Abs(X))/
Log(10))-(W-1))
Where:
W is the number of desired significant figures
X is the original number
Y is the number, X rounded to W significant figures
Blair Nimmo
Blairn,
Thanks for the input. Your expression looks pretty close to what I have
in SetSF, which seems to be working perfectly. The problem I am working
on is:
Given an expression that represents the numeric value to a given number
of significant figures, create a string that works in all cases that
formats that number to a number of significant figures that may be
different than the original number of significant figures. To examine
the problem in detail, I am creating a long, intuitive version (I'm not
quite done with that either) so that I can see what the issues are and
that I can understand why the output of SetSF allows for the amount of
optimization of the code that is does:
Public Function FormatSF2(ByVal dblX As Double, intPlaces As Integer) As
String
Dim intExponent As Integer
Dim intSign As Integer
Dim strDigits As String
Dim strChar As String
Dim strTemp As String
Dim I As Integer
If dblX <> 0 Then
If dblX < 0 Then
'work with positive values and put the sign in at the end
intSign = -1
dblX = -dblX
Else
intSign = 1
End If
strDigits = "111111111111111111111"
Do Until intPlaces >= Len(strDigits)
strDigits = ""
For I = 1 To Len(CStr(dblX))
strChar = Mid(CStr(dblX), I, 1)
If IsNumeric(strChar) Then strDigits = strDigits & strChar
Next I
'Get rid of any leading 0's
Do While Left(strDigits, 1) = "0"
strDigits = Right(strDigits, Len(strDigits) - 1)
Loop
If intPlaces >= Len(strDigits) Then
strTemp = strDigits & String(intPlaces - Len(strDigits), "0")
Else
'FormatSF needs to chop the number even more to make it fit
'Just chopping isn't correct
dblX = SetSF(dblX, intPlaces)
End If
Loop
'Put in the decimal point, if applicable
intExponent = Int(Log(dblX) / Log(10#) + 0.0000000001)
If intExponent > 0 Then
If Len(strDigits) > intExponent + 1 Then
strTemp = Left(strTemp, intExponent + 1) & "." & Right(strTemp,
Len(strTemp) - intExponent - 1)
Else
strTemp = Left(strTemp, intExponent + 1)
End If
ElseIf intExponent < 0 Then
strTemp = "0." & String(CLng(-intExponent), "0") & strTemp
Else
'The number is between 1 and 10
strTemp = Left(strDigits, 1) & "." & Right(strTemp, Len(strTemp) - 1)
End If
If intSign = -1 Then strTemp = "-" & strTemp
Else
strTemp = "0"
If intPlaces > 1 Then
strTemp = strTemp & "." & String(intPlaces - 1, "0")
End If
End If
FormatSF2 = strTemp
End Function
Obviously I have not tried to optimize this at all since it is merely
for didactic purposes. I suspect that the final change(s) to the
original FormatSF function to fix the problem will be minimal,
especially if the number of significant digits does not change between
the calculation and presentation.
James A. Fortune
(e-mail address removed)