I'm trying to display the results of an averaging function in the same decimal format of the values that were averaged. Yet, the results end up in Scientific Notation, which is not desired. So I added the Format() function to the averaging function, but it is not returning any values at all. I've been searching the net for the reason why, but have not found anything other than the fomat I'm using. What am I doing wrong? Private Function DisplayAvgATR(ByRef Ranges() As Single) As String Dim n As Long Dim sngTotal As Single Dim sngAvg As Single For n = 0 To UBound(Ranges) sngTotal = sngTotal + Ranges(n) Next n 'Return the Average sngAvg = sngTotal / (UBound(Ranges) + 1) DisplayAvgATR = Format(sngAvg, "#.#") End Function While sngAvg actually has a value, say 6.0028E-02, it is not being returned as .060028. Thanks. Webbiz
![]() |
0 |
![]() |
"Webbiz" <nospam@noway.com> wrote in message news:blo8h5l82ecd6c0efqg64j7s4smq29cgq9@4ax.com... > While sngAvg actually has a value, say 6.0028E-02, it is not being > returned as .060028. It should return ".1" in that case, which is what I am getting. You asked only for one number after the decimal point, and Format rounds to that. If you need multiple digits, you need to add another parameter, NumDecimalPlaces. Example: DisplayAvgATR = Format(sngAvg, "#." & String(NumDecimalPlaces, "#")) Also look at Round() function, but due to precision, you may get 0.060000000001 because in some cases a number cannot be precisely representing by binary values, so always use Format() function to display your data.
![]() |
0 |
![]() |
"Webbiz" <nospam@noway.com> wrote in message news:blo8h5l82ecd6c0efqg64j7s4smq29cgq9@4ax.com... > I'm trying to display the results of an averaging function in the same > decimal format of the values that were averaged. Yet, the results end > up in Scientific Notation, which is not desired. > > So I added the Format() function to the averaging function, but it is > not returning any values at all. > > I've been searching the net for the reason why, but have not found > anything other than the fomat I'm using. > > What am I doing wrong? > > Private Function DisplayAvgATR(ByRef Ranges() As Single) As String > Dim n As Long > Dim sngTotal As Single > Dim sngAvg As Single > > For n = 0 To UBound(Ranges) > sngTotal = sngTotal + Ranges(n) > Next n > > > > 'Return the Average > sngAvg = sngTotal / (UBound(Ranges) + 1) > DisplayAvgATR = Format(sngAvg, "#.#") > > End Function > > While sngAvg actually has a value, say 6.0028E-02, it is not being > returned as .060028. Why would it when your format string is "#.#'? That's going to format it to just one decimal place. Use as many # signs for the decimal part as you want decimal places. And just to nitpick a bit here, since your function is not really displaying anything, you might want to consider renaming it...for example CalcAvgATR or even just simply CalcAvg since it will calculate the average for anything that meets the parameter criteria of an array of type Single (kinda making a guess that ATR indicates a set of specific values). And one more nitpick. Your function is making an assumption that the passed in array will be 0-based. That's probably OK since that's the default for an array. But you can make it generic so that it will work regardless of what the lower bound is by doing this: Private Function CalcAvg(ByRef Ranges() As Single) As String Dim n As Long Dim sngTotal As Single Dim sngAvg As Single For n = LBound(Ranges) To UBound(Ranges) sngTotal = sngTotal + Ranges(n) Next n 'Return the Average sngAvg = sngTotal / (UBound(Ranges) - LBound(Ranges) + 1) CalcAvg = Format$(sngAvg, "#.######") End Function And one last nitpick, since the function returns a String, use the String version of the Format function, as shown above. Some people will even say there's no need for the sngAvg variable. Just do this: CalcAvg = Format$(sngTotal / (UBound(Ranges) - LBound(Ranges) + 1), "#.######") And strictly speaking they'd be right. There is no absolute reason to use a local variable to hold the result of the calculation, but when I'm debugging and stepping through code, I like to have the results of calculations assigned to variables to make it easier to get a tooltip of the result of that calculation in the IDE (and yes I know you could position the mousepointer on an opening parenthesis or select the expression to get a tooltip showing the result, but it's much easier to just position the mousepointer within a variable name). And the millisecond (or less) that the local variable is using memory...not an issue as far as I'm concerned. -- Mike
![]() |
0 |
![]() |
"MikeD" <nobody@nowhere.edu> wrote in news:u9#uQ0icKHA.1592@TK2MSFTNGP06.phx.gbl: > > > "Webbiz" <nospam@noway.com> wrote in message > news:blo8h5l82ecd6c0efqg64j7s4smq29cgq9@4ax.com... >> I'm trying to display the results of an averaging function in the >> same decimal format of the values that were averaged. Yet, the >> results end up in Scientific Notation, which is not desired. >> >> So I added the Format() function to the averaging function, but it is >> not returning any values at all. >> >> I've been searching the net for the reason why, but have not found >> anything other than the fomat I'm using. >> >> What am I doing wrong? >> >> Private Function DisplayAvgATR(ByRef Ranges() As Single) As String >> Dim n As Long >> Dim sngTotal As Single >> Dim sngAvg As Single >> >> For n = 0 To UBound(Ranges) >> sngTotal = sngTotal + Ranges(n) >> Next n >> >> >> >> 'Return the Average >> sngAvg = sngTotal / (UBound(Ranges) + 1) >> DisplayAvgATR = Format(sngAvg, "#.#") >> >> End Function >> >> While sngAvg actually has a value, say 6.0028E-02, it is not being >> returned as .060028. > > > Why would it when your format string is "#.#'? That's going to format > it to just one decimal place. Use as many # signs for the decimal > part as you want decimal places. Isn't that use # for deciaml places if needed, or use 0 for required.... x = 7.12345 format (x,"##.############") will return 7.12345 while format (x,"00.000000000000") will return 07.12345000000
![]() |
0 |
![]() |
"DanS" <t.h.i.s.n.t.h.a.t@r.o.a.d.r.u.n.n.e.r.c.o.m> wrote in message news:Xns9CD3E0AA14322thisnthatroadrunnern@216.196.97.131... > "MikeD" <nobody@nowhere.edu> wrote in > news:u9#uQ0icKHA.1592@TK2MSFTNGP06.phx.gbl: > >> >> >> "Webbiz" <nospam@noway.com> wrote in message >> news:blo8h5l82ecd6c0efqg64j7s4smq29cgq9@4ax.com... >>> I'm trying to display the results of an averaging function in the >>> same decimal format of the values that were averaged. Yet, the >>> results end up in Scientific Notation, which is not desired. >>> >>> So I added the Format() function to the averaging function, but it is >>> not returning any values at all. >>> >>> I've been searching the net for the reason why, but have not found >>> anything other than the fomat I'm using. >>> >>> What am I doing wrong? >>> >>> Private Function DisplayAvgATR(ByRef Ranges() As Single) As String >>> Dim n As Long >>> Dim sngTotal As Single >>> Dim sngAvg As Single >>> >>> For n = 0 To UBound(Ranges) >>> sngTotal = sngTotal + Ranges(n) >>> Next n >>> >>> >>> >>> 'Return the Average >>> sngAvg = sngTotal / (UBound(Ranges) + 1) >>> DisplayAvgATR = Format(sngAvg, "#.#") >>> >>> End Function >>> >>> While sngAvg actually has a value, say 6.0028E-02, it is not being >>> returned as .060028. >> >> >> Why would it when your format string is "#.#'? That's going to format >> it to just one decimal place. Use as many # signs for the decimal >> part as you want decimal places. > > Isn't that use # for deciaml places if needed, or use 0 for required.... > > x = 7.12345 > > format (x,"##.############") will return 7.12345 > > while format (x,"00.000000000000") will return > > 07.12345000000 You have to use as many placeholders in your format string as you want for minimum decimal places. He only had one decimal placeholder, so the function would only return one decimal. If the format string is "#.##" and the value to format is .12345, the formatted string is going to be ".12" whereas if the format string is "#.#####", the formatted string will be ".12345". If the format string is "#.####" the formatted string will be ".1235" because that 5 in the 5th place is going to cause the 4 to get rounded up as the format string dictates only 4 decimal places (if I did all that correctly in my head). I think your confusion might be because # works a little differently when left of the decimal place. If you have a format string of "#.##" and the value to format is 500.5, the formatted string will be "500.5" even though there was only a single # character left of the decimal point in the format string. -- Mike
![]() |
0 |
![]() |
On Mon, 30 Nov 2009 21:21:52 -0500, "MikeD" <nobody@nowhere.edu> wrote: > > >"Webbiz" <nospam@noway.com> wrote in message >news:blo8h5l82ecd6c0efqg64j7s4smq29cgq9@4ax.com... >> I'm trying to display the results of an averaging function in the same >> decimal format of the values that were averaged. Yet, the results end >> up in Scientific Notation, which is not desired. >> >> So I added the Format() function to the averaging function, but it is >> not returning any values at all. >> >> I've been searching the net for the reason why, but have not found >> anything other than the fomat I'm using. >> >> What am I doing wrong? >> >> Private Function DisplayAvgATR(ByRef Ranges() As Single) As String >> Dim n As Long >> Dim sngTotal As Single >> Dim sngAvg As Single >> >> For n = 0 To UBound(Ranges) >> sngTotal = sngTotal + Ranges(n) >> Next n >> >> >> >> 'Return the Average >> sngAvg = sngTotal / (UBound(Ranges) + 1) >> DisplayAvgATR = Format(sngAvg, "#.#") >> >> End Function >> >> While sngAvg actually has a value, say 6.0028E-02, it is not being >> returned as .060028. > > >Why would it when your format string is "#.#'? That's going to format it to >just one decimal place. Use as many # signs for the decimal part as you >want decimal places. > >And just to nitpick a bit here, since your function is not really displaying >anything, you might want to consider renaming it...for example CalcAvgATR or >even just simply CalcAvg since it will calculate the average for anything >that meets the parameter criteria of an array of type Single (kinda making a >guess that ATR indicates a set of specific values). > >And one more nitpick. Your function is making an assumption that the passed >in array will be 0-based. That's probably OK since that's the default for an >array. But you can make it generic so that it will work regardless of what >the lower bound is by doing this: > >Private Function CalcAvg(ByRef Ranges() As Single) As String >Dim n As Long >Dim sngTotal As Single >Dim sngAvg As Single > > For n = LBound(Ranges) To UBound(Ranges) > sngTotal = sngTotal + Ranges(n) > Next n > > > > 'Return the Average > sngAvg = sngTotal / (UBound(Ranges) - LBound(Ranges) + 1) > CalcAvg = Format$(sngAvg, "#.######") > >End Function > > >And one last nitpick, since the function returns a String, use the String >version of the Format function, as shown above. > >Some people will even say there's no need for the sngAvg variable. Just do >this: > >CalcAvg = Format$(sngTotal / (UBound(Ranges) - LBound(Ranges) + 1), >"#.######") > >And strictly speaking they'd be right. There is no absolute reason to use a >local variable to hold the result of the calculation, but when I'm debugging >and stepping through code, I like to have the results of calculations >assigned to variables to make it easier to get a tooltip of the result of >that calculation in the IDE (and yes I know you could position the >mousepointer on an opening parenthesis or select the expression to get a >tooltip showing the result, but it's much easier to just position the >mousepointer within a variable name). And the millisecond (or less) that the >local variable is using memory...not an issue as far as I'm concerned. What a nitpicker. LOL! Hey, I deserve it. I know. The "#.#" was something I found online. Could not find anything that helped. Okay. I'll rename the thing and make it generic. Really haven't thought of using it again, but you never know. Thanks. :-) BTW, while you've no problem 'nitpicking' <g>, got any suggestions on a snazy way to set the format pattern of the "#.####" based on the way the values are formatted in the array to begin with? Webbiz
![]() |
0 |
![]() |
On Mon, 30 Nov 2009 22:54:47 -0500, "MikeD" <nobody@nowhere.edu> wrote: >I think your confusion might be because # works a little differently when >left of the decimal place. If you have a format string of "#.##" and the >value to format is 500.5, the formatted string will be "500.5" even though >there was only a single # character left of the decimal point in the format >string. Yes. That's what confused me. ;-) Thanks Mike (and all others who chimed in.) Webbiz
![]() |
0 |
![]() |
On 01/12/2009 06:48, Webbiz wrote: > On Mon, 30 Nov 2009 21:21:52 -0500, "MikeD"<nobody@nowhere.edu> wrote: >> "Webbiz"<nospam@noway.com> wrote >>> Private Function DisplayAvgATR(ByRef Ranges() As Single) As String > > BTW, while you've no problem 'nitpicking'<g>, got any suggestions on > a snazy way to set the format pattern of the "#.####" based on the way > the values are formatted in the array to begin with? The values in the array wont have a format as they are Singles. Formatting only applies when you convert to a string for display purposes. If you want the caller to be able to control the output format, either return a single and let it format it or take the format string as a parameter. -- Dee Earley (dee.earley@icode.co.uk) i-Catcher Development Team iCode Systems
![]() |
0 |
![]() |
> BTW, while you've no problem 'nitpicking' <g>, got any suggestions on > a snazy way to set the format pattern of the "#.####" based on the way > the values are formatted in the array to begin with? Just put 15 # signs after the decimal point and VB will do the rest... it will maintain the maximum number of decimal places that are required. One thing you may want to consider (as long as you are using dots for decimal places and no thousands separators in your Format pattern) is to wrap the Format function's result with a Val function call... this will remove the trailing dot in case the average comes out to be an integer result. Or did you ask that because you want to preserve trailing zeroes in case the result had less decimal places than the number with the most decimal places that was being averaged? -- Rick (MVP - Excel)
![]() |
0 |
![]() |
"Rick Rothstein" <rick.newsNO.SPAM@NO.SPAMverizon.net> wrote >> BTW, while you've no problem 'nitpicking' <g>, got any suggestions on >> a snazy way to set the format pattern of the "#.####" based on the way >> the values are formatted in the array to begin with? > > Just put 15 # signs after the decimal point and VB will do the rest... it > will maintain the maximum number of decimal places that are required. One > thing you may want to consider (as long as you are using dots for decimal > places and no thousands separators in your Format pattern) is to wrap the > Format function's result with a Val function call... this will remove the > trailing dot in case the average comes out to be an integer result. Or did > you ask that because you want to preserve trailing zeroes in case the > result had less decimal places than the number with the most decimal > places that was being averaged? In some cases, trailing zeros are important... :-) LFS
![]() |
0 |
![]() |
Yep, that is why I added the last sentence/question. It was not entirely clear to me what Webbiz meant by "based on the way the values are formatted in the array to begin with". -- Rick (MVP - Excel) "Larry Serflaten" <serflaten@usinternet.com> wrote in message news:03F44C2F-9AF9-4FE9-9CAA-C87195AB2092@microsoft.com... > > > "Rick Rothstein" <rick.newsNO.SPAM@NO.SPAMverizon.net> wrote >>> BTW, while you've no problem 'nitpicking' <g>, got any suggestions on >>> a snazy way to set the format pattern of the "#.####" based on the way >>> the values are formatted in the array to begin with? >> >> Just put 15 # signs after the decimal point and VB will do the rest... it >> will maintain the maximum number of decimal places that are required. One >> thing you may want to consider (as long as you are using dots for decimal >> places and no thousands separators in your Format pattern) is to wrap the >> Format function's result with a Val function call... this will remove the >> trailing dot in case the average comes out to be an integer result. Or >> did you ask that because you want to preserve trailing zeroes in case the >> result had less decimal places than the number with the most decimal >> places that was being averaged? > > In some cases, trailing zeros are important... > > :-) > LFS
![]() |
0 |
![]() |
On Tue, 01 Dec 2009 08:53:00 +0000, Dee Earley <dee.earley@icode.co.uk> wrote: >On 01/12/2009 06:48, Webbiz wrote: >> On Mon, 30 Nov 2009 21:21:52 -0500, "MikeD"<nobody@nowhere.edu> wrote: >>> "Webbiz"<nospam@noway.com> wrote >>>> Private Function DisplayAvgATR(ByRef Ranges() As Single) As String >> >> BTW, while you've no problem 'nitpicking'<g>, got any suggestions on >> a snazy way to set the format pattern of the "#.####" based on the way >> the values are formatted in the array to begin with? > >The values in the array wont have a format as they are Singles. >Formatting only applies when you convert to a string for display purposes. >If you want the caller to be able to control the output format, either >return a single and let it format it or take the format string as a >parameter. I'm sorry, I didn't explain myself well. The data in the array is of a particular format although Singles. Stock and Commodity prices come in various formats. Here are some common ones: Currencies: 0.9244 Australian Dollar 1.6638 British Pound 0.9581 Canadian Dollar 1.5093 Euro 1.1539 Japanese Yen Meats: 82.625 Live Cattle 59.200 Lean Hogs Softs: 70.31 Cotton 142.75 Coffee 22.17 Sugar Financials: 122.31250 30yr T Bonds Indexes: 1108.80 SP500 Grains: 399.75 Corn 1059.50 Soybeans 562.50 Wheat Actual prices at the time of writing this. :-) So when one of these data files are loaded in, the output displays would need to display results that are also in the appropriate format. :-) Webbiz
![]() |
0 |
![]() |
On Tue, 1 Dec 2009 03:55:54 -0500, "Rick Rothstein" <rick.newsNO.SPAM@NO.SPAMverizon.net> wrote: >> BTW, while you've no problem 'nitpicking' <g>, got any suggestions on >> a snazy way to set the format pattern of the "#.####" based on the way >> the values are formatted in the array to begin with? > >Just put 15 # signs after the decimal point and VB will do the rest... it >will maintain the maximum number of decimal places that are required. One >thing you may want to consider (as long as you are using dots for decimal >places and no thousands separators in your Format pattern) is to wrap the >Format function's result with a Val function call... this will remove the >trailing dot in case the average comes out to be an integer result. Or did >you ask that because you want to preserve trailing zeroes in case the result >had less decimal places than the number with the most decimal places that >was being averaged? Hello Rick. My response to Dee's post may explain it better. But even a whole number may require the decimal point if the original data format requires it. For example, if the data is for Soybeans, it would have two digits following the decimal point even if the value is an integer, such as 1059.00. Thanks! Webbiz
![]() |
0 |
![]() |
"Webbiz" <nospam@noway.com> wrote in message news:bttah5hon83ti9i7qrsudkr5or3mh8qrno@4ax.com... > My response to Dee's post may explain it better. But even a whole > number may require the decimal point if the original data format > requires it. > > For example, if the data is for Soybeans, it would have two digits > following the decimal point even if the value is an integer, such as > 1059.00. You need more than an array of <some basic data type>. What you need is an array of classes or stuctures (VB Types) which have properties that further define the value you're storing.
![]() |
0 |
![]() |
"Webbiz" <nospam@noway.com> wrote in message news:bttah5hon83ti9i7qrsudkr5or3mh8qrno@4ax.com... > For example, if the data is for Soybeans, it would have two > digits following the decimal point [and hogs would have three] > even if the value is an integer, such as 1059.00. Dim LeanHogs As Single, Soybeans As Single LeanHogs = 59 Soybeans = 1059 Print Format(LeanHogs, "0.000") Print Format(Soybeans, "0.00") Mike
![]() |
0 |
![]() |
Let Num be **any** number from the list of numbers that you are processing and let Avg be the calculated average... Num = <<any value from list>> Avg = <<calculated average>> ' This line formats the calculated value as per a number in the list Avg = Format(Avg, "0." & String(Len(Num) - InStr(Num, "."), "0")) -- Rick (MVP - Excel) "Webbiz" <nospam@noway.com> wrote in message news:bttah5hon83ti9i7qrsudkr5or3mh8qrno@4ax.com... > On Tue, 1 Dec 2009 03:55:54 -0500, "Rick Rothstein" > <rick.newsNO.SPAM@NO.SPAMverizon.net> wrote: > >>> BTW, while you've no problem 'nitpicking' <g>, got any suggestions on >>> a snazy way to set the format pattern of the "#.####" based on the way >>> the values are formatted in the array to begin with? >> >>Just put 15 # signs after the decimal point and VB will do the rest... it >>will maintain the maximum number of decimal places that are required. One >>thing you may want to consider (as long as you are using dots for decimal >>places and no thousands separators in your Format pattern) is to wrap the >>Format function's result with a Val function call... this will remove the >>trailing dot in case the average comes out to be an integer result. Or did >>you ask that because you want to preserve trailing zeroes in case the >>result >>had less decimal places than the number with the most decimal places that >>was being averaged? > > Hello Rick. > > My response to Dee's post may explain it better. But even a whole > number may require the decimal point if the original data format > requires it. > > For example, if the data is for Soybeans, it would have two digits > following the decimal point even if the value is an integer, such as > 1059.00. > > Thanks! > > Webbiz
![]() |
0 |
![]() |
On Tue, 1 Dec 2009 15:26:45 -0500, "Jeff Johnson" <i.get@enough.spam> wrote: >"Webbiz" <nospam@noway.com> wrote in message >news:bttah5hon83ti9i7qrsudkr5or3mh8qrno@4ax.com... > >> My response to Dee's post may explain it better. But even a whole >> number may require the decimal point if the original data format >> requires it. >> >> For example, if the data is for Soybeans, it would have two digits >> following the decimal point even if the value is an integer, such as >> 1059.00. > >You need more than an array of <some basic data type>. What you need is an >array of classes or stuctures (VB Types) which have properties that further >define the value you're storing. > To answer yours and Mike's replies, the format has to be based on the data loaded and not the name of the data loaded. This is because one person may have a Lean Hogs file called LeanHogs, while someone else may load lhz10, which is also Lean Hogs, and another may load LH_Rev, etc. etc. Otherwise, the user would have to define the data loaded manually, telling the application how he wants the data displayed, etc. While this is certainly the best approach for user customization purposes, it is also an additional step that chartist like myself find tedious to do. :-) Webbiz
![]() |
0 |
![]() |
On Tue, 1 Dec 2009 15:52:07 -0500, "Rick Rothstein" <rick.newsNO.SPAM@NO.SPAMverizon.net> wrote: >Let Num be **any** number from the list of numbers that you are processing >and let Avg be the calculated average... > >Num = <<any value from list>> >Avg = <<calculated average>> >' This line formats the calculated value as per a number in the list >Avg = Format(Avg, "0." & String(Len(Num) - InStr(Num, "."), "0")) I'm going to try this one out. Thanks! Webbiz
![]() |
0 |
![]() |
On Tue, 1 Dec 2009 15:52:07 -0500, "Rick Rothstein" <rick.newsNO.SPAM@NO.SPAMverizon.net> wrote: >Let Num be **any** number from the list of numbers that you are processing >and let Avg be the calculated average... > >Num = <<any value from list>> >Avg = <<calculated average>> >' This line formats the calculated value as per a number in the list >Avg = Format(Avg, "0." & String(Len(Num) - InStr(Num, "."), "0")) Ah, tested but didn't work out because the blasted values in the array are in Scientific Notation. VB had to have done this because the actual values when loaded into the array were not in SN. What causes this and how to keep VB from doing it this way? Here is where this is happening: Values(1) = CurrPriceData.High - CurrPriceData.Low Values() is type Single. CurrPriceData.High = 0.5001 CurrPriceData.Low = 0.4963 Values(1) = 3.800005E-03 Why? Thanks. Webbiz
![]() |
0 |
![]() |
>>Let Num be **any** number from the list of numbers that you are processing >>and let Avg be the calculated average... >> >>Num = <<any value from list>> >>Avg = <<calculated average>> >>' This line formats the calculated value as per a number in the list >>Avg = Format(Avg, "0." & String(Len(Num) - InStr(Num, "."), "0")) > > > Ah, tested but didn't work out because the blasted values in the array > are in Scientific Notation. VB had to have done this because the > actual values when loaded into the array were not in SN. > > What causes this and how to keep VB from doing it this way? > > Here is where this is happening: > > Values(1) = CurrPriceData.High - CurrPriceData.Low > > Values() is type Single. > > CurrPriceData.High = 0.5001 > CurrPriceData.Low = 0.4963 > > Values(1) = 3.800005E-03 Try using one of the CurrPriceData.High or CurrPriceData.Low values for Num value in my expression as they seem like they might be in the right format (String as opposed to Single I'm guessing). If these values are really numeric values and not text String representations of those numerical values, then can you see the formatted number from the original source? If so, this is what you want to assign to the Num variable. Basically, you need a **formatted** value so you can see how many decimal places there are... if these are numerical values, then you will never know if the value you chose would have ended in zeroes when originally formatted (since numbers do not have format, they can end with zeroes after the decimal point, only formatted String representations of these numbers can do that). -- Rick (MVP - Excel)
![]() |
0 |
![]() |
"Webbiz" <nospam@noway.com> wrote in message news:ae2bh514mrcog5bovvdiuunvteeq6dgui4@4ax.com... > Ah, tested but didn't work out because the blasted values in the array > are in Scientific Notation. VB had to have done this because the > actual values when loaded into the array were not in SN. Single/Double are not stored in Scientific Notation, they are always stored in binary form. When you implicitly assign Single/Double to String, VB does the conversion for you, which may not be what you want. You have to use Format() function. Also, Round() function converts a number from one binary form to another, so it could round something from .8999999999 to .900000001, so you still have to use Format() function to display the value to insure that you get the correct number of extra digits. If you want to see what Single looks like in binary form, see here: http://en.wikipedia.org/wiki/Single_precision_floating-point_format And Double: http://en.wikipedia.org/wiki/Double_precision_floating-point_format
![]() |
0 |
![]() |
On Tue, 1 Dec 2009 17:24:43 -0500, "Nobody" <nobody@nobody.com> wrote: >"Webbiz" <nospam@noway.com> wrote in message >news:ae2bh514mrcog5bovvdiuunvteeq6dgui4@4ax.com... >> Ah, tested but didn't work out because the blasted values in the array >> are in Scientific Notation. VB had to have done this because the >> actual values when loaded into the array were not in SN. > >Single/Double are not stored in Scientific Notation, they are always stored >in binary form. When you implicitly assign Single/Double to String, VB does >the conversion for you, which may not be what you want. You have to use >Format() function. > >Also, Round() function converts a number from one binary form to another, so >it could round something from .8999999999 to .900000001, so you still have >to use Format() function to display the value to insure that you get the >correct number of extra digits. > >If you want to see what Single looks like in binary form, see here: > >http://en.wikipedia.org/wiki/Single_precision_floating-point_format > >And Double: > >http://en.wikipedia.org/wiki/Double_precision_floating-point_format > Then why are my Single values, showing in Watch as .5938 for example, showing as a Scientific Notation value after some math and assigned to another Single variable? If I send the original single value to the text box, it will show up as .5938. But do some subtraction, for example, of two of these Singles and assign to another Single, or directly to the textbox, and it displays as Scentific Notation? Webbiz
![]() |
0 |
![]() |
On Tue, 1 Dec 2009 16:49:17 -0500, "Rick Rothstein" <rick.newsNO.SPAM@NO.SPAMverizon.net> wrote: >>>Let Num be **any** number from the list of numbers that you are processing >>>and let Avg be the calculated average... >>> >>>Num = <<any value from list>> >>>Avg = <<calculated average>> >>>' This line formats the calculated value as per a number in the list >>>Avg = Format(Avg, "0." & String(Len(Num) - InStr(Num, "."), "0")) >> >> >> Ah, tested but didn't work out because the blasted values in the array >> are in Scientific Notation. VB had to have done this because the >> actual values when loaded into the array were not in SN. >> >> What causes this and how to keep VB from doing it this way? >> >> Here is where this is happening: >> >> Values(1) = CurrPriceData.High - CurrPriceData.Low >> >> Values() is type Single. >> >> CurrPriceData.High = 0.5001 >> CurrPriceData.Low = 0.4963 >> >> Values(1) = 3.800005E-03 > >Try using one of the CurrPriceData.High or CurrPriceData.Low values for Num >value in my expression as they seem like they might be in the right format >(String as opposed to Single I'm guessing). If these values are really >numeric values and not text String representations of those numerical >values, then can you see the formatted number from the original source? If >so, this is what you want to assign to the Num variable. Basically, you need >a **formatted** value so you can see how many decimal places there are... if >these are numerical values, then you will never know if the value you chose >would have ended in zeroes when originally formatted (since numbers do not >have format, they can end with zeroes after the decimal point, only >formatted String representations of these numbers can do that). The values are stored in DataArray as Singles Type DataArray dDate As Date Open As Single High As Single Low As Single Close As Single End Type So these are both Singles... CurrPriceData.High = 0.5001 CurrPriceData.Low = 0.4963 And if I send these variables directly to the TextBox, they display accordingly. However, subtract one from the other and assign to the textbox or another Single variable, and it displays as Sci-Notation. I find this very odd. Yes, I can use the original single variable to test for format, although I'll have to store it in a Global as these values are static to another function that has long lost scope. Thanks. Webbiz
![]() |
0 |
![]() |
Webbiz wrote: > Then why are my Single values, showing in Watch as .5938 for > example, showing as a Scientific Notation value after some math and > assigned to another Single variable? > > If I send the original single value to the text box, it will show up > as .5938. But do some subtraction, for example, of two of these > Singles and assign to another Single, or directly to the textbox, > and it displays as Scentific Notation? A textbox can't display a single, it can only display strings. And anything you show in Watch or Debug etc is a also string. If you want to control how something appears on the screen (i.e. in the string domain), use Format. -- Jim Mack Twisted tees at http://www.cafepress.com/2050inc "We sew confusion"
![]() |
0 |
![]() |
Webbiz wrote: .... > Then why are my Single values, showing in Watch as .5938 for example, > showing as a Scientific Notation value after some math and assigned to > another Single variable? > > If I send the original single value to the text box, it will show up > as .5938. But do some subtraction, for example, of two of these > Singles and assign to another Single, or directly to the textbox, and > it displays as Scentific Notation? Because unless you control the output format specifically, you're at the mercy of the VB RTL i/o library logic for converting the internal representation to some default character representation. What that will be will be determined by the magnitude and the implementation of the specific control or i/o operation. If you care what the output looks like, use Format$() BTW, this a generic requirement in any programming language that has the equivalent facility of providing default i/o formatting, not just VB. In Fortran, it's called "list-directed" formatting as just one example. --
![]() |
0 |
![]() |
"Webbiz" <nospam@noway.com> wrote in message news:ha6bh5ps7b8qnab20lbqpultrc567oq2lm@4ax.com... > Then why are my Single values, showing in Watch as .5938 for example, > showing as a Scientific Notation value after some math and assigned to > another Single variable? > > If I send the original single value to the text box, it will show up > as .5938. But do some subtraction, for example, of two of these > Singles and assign to another Single, or directly to the textbox, and > it displays as Scentific Notation? Because the way numbers are stored in binary form(fraction+Exponent), there can be two binary forms for the same decimal number. Kind of like saying 100/500~101/499. This has implications when testing if two values are equal, which may not be what you expect. This is true for all languages, not just VB. To solve this, use something like "If Abs(x-y)<=0.01 Then" to test for equality, or write that as IsEqual() function for easy reading. See this article and related articles in the References section: INFO: Visual Basic and Arithmetic Precision http://support.microsoft.com/kb/279755 See this sample which prints the byte values so you can see the difference. It's based on the numbers that you have posted in an earlier reply: Option Explicit Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" ( _ Destination As Any, Source As Any, ByVal Length As Long) Private Sub Form_Load() Dim x As Single Dim y As Single x = 0.5001 y = 0.4963 y = x - y Debug.Print y PrintBinaryValue y x = 0.0038 Debug.Print x PrintBinaryValue x If x = y Then Debug.Print "x = y" Else Debug.Print "x <> y" End If If Abs(x - y) < 0.01 Then Debug.Print "Almost equal" Else Debug.Print "Not equal" End If End Sub ' Print "x" in binary form Private Sub PrintBinaryValue(ByRef x As Single) Dim b(0 To 3) As Byte Dim i As Long CopyMemory b(0), x, 4 For i = 0 To 3 Debug.Print Hex(b(i)); " "; Next Debug.Print End Sub Output: 3.800005E-03 80 9 79 3B 0.0038 6C 9 79 3B x <> y Almost equal
![]() |
0 |
![]() |
On Tue, 1 Dec 2009 17:56:08 -0500, "Jim Mack" <jmack@mdxi.nospam.com> wrote: >Webbiz wrote: > >> Then why are my Single values, showing in Watch as .5938 for >> example, showing as a Scientific Notation value after some math and >> assigned to another Single variable? >> >> If I send the original single value to the text box, it will show up >> as .5938. But do some subtraction, for example, of two of these >> Singles and assign to another Single, or directly to the textbox, >> and it displays as Scentific Notation? > >A textbox can't display a single, it can only display strings. And >anything you show in Watch or Debug etc is a also string. > >If you want to control how something appears on the screen (i.e. in >the string domain), use Format. Jim, I know this. What I'm saying is that the value is changing from a regular decimal value to Scientific Notation. So when I go to display it in a text box, it shows as Scientific Notation. Yes, format is what will need to be used, and that's still in discussion in this thread. However, my question is WHY is it changing to Sci-Not? Thanks. Webbiz
![]() |
0 |
![]() |
Thanks. Reading article now. :) On Tue, 1 Dec 2009 18:20:08 -0500, "Nobody" <nobody@nobody.com> wrote: >"Webbiz" <nospam@noway.com> wrote in message >news:ha6bh5ps7b8qnab20lbqpultrc567oq2lm@4ax.com... >> Then why are my Single values, showing in Watch as .5938 for example, >> showing as a Scientific Notation value after some math and assigned to >> another Single variable? >> >> If I send the original single value to the text box, it will show up >> as .5938. But do some subtraction, for example, of two of these >> Singles and assign to another Single, or directly to the textbox, and >> it displays as Scentific Notation? > >Because the way numbers are stored in binary form(fraction+Exponent), there >can be two binary forms for the same decimal number. Kind of like saying >100/500~101/499. This has implications when testing if two values are equal, >which may not be what you expect. This is true for all languages, not just >VB. To solve this, use something like "If Abs(x-y)<=0.01 Then" to test for >equality, or write that as IsEqual() function for easy reading. See this >article and related articles in the References section: > >INFO: Visual Basic and Arithmetic Precision >http://support.microsoft.com/kb/279755 > >See this sample which prints the byte values so you can see the difference. >It's based on the numbers that you have posted in an earlier reply: > >Option Explicit > >Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" ( _ > Destination As Any, Source As Any, ByVal Length As Long) > >Private Sub Form_Load() > Dim x As Single > Dim y As Single > > x = 0.5001 > y = 0.4963 > > y = x - y > Debug.Print y > PrintBinaryValue y > > x = 0.0038 > Debug.Print x > PrintBinaryValue x > > If x = y Then > Debug.Print "x = y" > Else > Debug.Print "x <> y" > End If > > If Abs(x - y) < 0.01 Then > Debug.Print "Almost equal" > Else > Debug.Print "Not equal" > End If > >End Sub > >' Print "x" in binary form >Private Sub PrintBinaryValue(ByRef x As Single) > Dim b(0 To 3) As Byte > Dim i As Long > > CopyMemory b(0), x, 4 > For i = 0 To 3 > Debug.Print Hex(b(i)); " "; > Next > Debug.Print >End Sub > > > >Output: > > 3.800005E-03 >80 9 79 3B > 0.0038 >6C 9 79 3B >x <> y >Almost equal > >
![]() |
0 |
![]() |
"Nobody" <nobody@nobody.com> wrote in message news:uR6jXztcKHA.1028@TK2MSFTNGP06.phx.gbl... > Output: > > 3.800005E-03 > 80 9 79 3B > 0.0038 > 6C 9 79 3B > x <> y > Almost equal Here is a break down of byte values for the first number, which was a result of a calculation: > 80 9 79 3B In the correct order, this would be: 3B790980 Based on this article: http://en.wikipedia.org/wiki/Single_precision_floating-point_format Breaking to basic components(all decimal): Sign: 0 Exponent: 118 Fraction: 7932288 Equation: (-1)^Sign * 2 ^ (Exponent - 127) * (1 + Fraction / (2^23)) So the number would be(Using Windows Calculator): 0.0038000047206878662109375 And for the other number, which was entered manually in code(x = 0.0038): > 6C 9 79 3B In the correct order, this would be: 3B79096C Breaking to basic components(all decimal): Sign: 0 Exponent: 118 Fraction: 7932268 So the number would be: 0.003800000064074993133544921875 It's very close to first one. Here are the numbers again, in Hex and decimal format to the precision that Windows Calculator can handle: 3B790980 3B79096C 0.0038000047206878662109375 0.003800000064074993133544921875
![]() |
0 |
![]() |
That's a problem then... once the numbers are placed in a numeric variable, they lose all their formatting (numbers are just numbers, they have no format). The problem with using a value from the list of numbers is that none of your values might be "full". For example, what if all your numbers are **supposed** to be shown to 3 decimal points, but all your values just happen to, by rare chance, have only one or two decimal places... if you try using one of these numbers in my expression, you will not get 3-decimal places shown. You also can't just select a number from the list because you might not get a "full" number either. Where are these numbers coming from? Perhaps you can go back to the source to get a representative formatted text representation of the number and use that. -- Rick (MVP - Excel) "Webbiz" <nospam@noway.com> wrote in message news:kh6bh5hd7f52vhq97kkumhgoerl125kgl1@4ax.com... > On Tue, 1 Dec 2009 16:49:17 -0500, "Rick Rothstein" > <rick.newsNO.SPAM@NO.SPAMverizon.net> wrote: > >>>>Let Num be **any** number from the list of numbers that you are >>>>processing >>>>and let Avg be the calculated average... >>>> >>>>Num = <<any value from list>> >>>>Avg = <<calculated average>> >>>>' This line formats the calculated value as per a number in the list >>>>Avg = Format(Avg, "0." & String(Len(Num) - InStr(Num, "."), "0")) >>> >>> >>> Ah, tested but didn't work out because the blasted values in the array >>> are in Scientific Notation. VB had to have done this because the >>> actual values when loaded into the array were not in SN. >>> >>> What causes this and how to keep VB from doing it this way? >>> >>> Here is where this is happening: >>> >>> Values(1) = CurrPriceData.High - CurrPriceData.Low >>> >>> Values() is type Single. >>> >>> CurrPriceData.High = 0.5001 >>> CurrPriceData.Low = 0.4963 >>> >>> Values(1) = 3.800005E-03 >> >>Try using one of the CurrPriceData.High or CurrPriceData.Low values for >>Num >>value in my expression as they seem like they might be in the right format >>(String as opposed to Single I'm guessing). If these values are really >>numeric values and not text String representations of those numerical >>values, then can you see the formatted number from the original source? If >>so, this is what you want to assign to the Num variable. Basically, you >>need >>a **formatted** value so you can see how many decimal places there are... >>if >>these are numerical values, then you will never know if the value you >>chose >>would have ended in zeroes when originally formatted (since numbers do not >>have format, they can end with zeroes after the decimal point, only >>formatted String representations of these numbers can do that). > > > The values are stored in DataArray as Singles > > Type DataArray > dDate As Date > Open As Single > High As Single > Low As Single > Close As Single > End Type > > So these are both Singles... > > CurrPriceData.High = 0.5001 > CurrPriceData.Low = 0.4963 > > And if I send these variables directly to the TextBox, they display > accordingly. > > However, subtract one from the other and assign to the textbox or > another Single variable, and it displays as Sci-Notation. I find this > very odd. > > Yes, I can use the original single variable to test for format, > although I'll have to store it in a Global as these values are static > to another function that has long lost scope. > > Thanks. > Webbiz > >
![]() |
0 |
![]() |
Webbiz wrote: .... > question is WHY is it changing to Sci-Not? .... Unless you're formatting it, the output format is at the mercy of the default i/o VB rtl...see other response for more specifically... --
![]() |
0 |
![]() |
On Tue, 1 Dec 2009 19:41:28 -0500, "Rick Rothstein" <rick.newsNO.SPAM@NO.SPAMverizon.net> wrote: >That's a problem then... once the numbers are placed in a numeric variable, >they lose all their formatting (numbers are just numbers, they have no >format). The problem with using a value from the list of numbers is that >none of your values might be "full". For example, what if all your numbers >are **supposed** to be shown to 3 decimal points, but all your values just >happen to, by rare chance, have only one or two decimal places... if you try >using one of these numbers in my expression, you will not get 3-decimal >places shown. You also can't just select a number from the list because you >might not get a "full" number either. Where are these numbers coming from? >Perhaps you can go back to the source to get a representative formatted text >representation of the number and use that. Here's an idea Rick. The application requires a minimum of 3 years data to work properly (this is not my charting program, btw). That's at least 600 data values, all Singles. In such a scenario, it's not only rare, it's impossible to not find the full format of the dataset. So what do you think of this: Within the routine that actually loads the data into the app, note each value for the number of digits following the decimal. If I'm not mistaken, the left is not important because "#. " will expand accordingly. It's right of the decimal that needs to be determined. So as each value passes by, if any value ends up with more values right of the decimal, the format is adjusted. This format is then saved in a Global String variable. Therefore, what I'm looking for would be the maximum needed values right of the decimal, right? So if this were discovered, the string variable could be set by... Select Case DecCnt Case 0 sDataFormat = "#" Case 1 sDataFormat = "#.#" Case 2 sDataFormat = "#.##" ....etc. Or is this too clumsy? Webbiz
![]() |
0 |
![]() |
Webbiz wrote: .... > Or is this too clumsy? All depends on what you really need...if you can't a priori determine the number of decimal digits required I suppose that's one possibility if the data are always loaded from a text file. If you were to load other floating point data it's possible you would always end up w/ the full precision of the variable owing to the rounding issues previously discussed. I'd think knowing simply the actual magnitude of the numbers if these are prices would be sufficient to determine a reasonable estimate of the precision required but I suppose that may be too naive a solution. --
![]() |
0 |
![]() |
"Webbiz" <nospam@noway.com> wrote in message news:blo8h5l82ecd6c0efqg64j7s4smq29cgq9@4ax.com... > I'm trying to display the results of an averaging function in the same > decimal format of the values that were averaged. Yet, the results end > up in Scientific Notation, which is not desired. > We've had this conversation before IIRC. Frankly for your whole application you need to either use the VB Currency datatype which will provide some consistency, or write your own 'Decimal' datatype routines (probably better as you tend to flop about on precision) that are based on integer math. [OR - buy a math/financial/statistical package. Unfortunately they tend to be pricey, unless you can use C/C++. There are many open source C/C++ libraries available.which you can use to create ActiveX or standard DLLs.] No financial/statistical application that needs to be reliable, consistent, and accurate uses floating datatypes for its historical data, journals, accounts, or projections. And all math is integer unless floating math is absolutely required - and even then the specific precision is rigorously enforced going in and coming out. -ralph
![]() |
0 |
![]() |
Webbiz wrote: > Jim Mack wrote: > >> Webbiz wrote: >> >>> Then why are my Single values, showing in Watch as .5938 for >>> example, showing as a Scientific Notation value after some math >>> and assigned to another Single variable? >>> >>> If I send the original single value to the text box, it will show >>> up as .5938. But do some subtraction, for example, of two of these >>> Singles and assign to another Single, or directly to the textbox, >>> and it displays as Scentific Notation? >> >> A textbox can't display a single, it can only display strings. And >> anything you show in Watch or Debug etc is a also string. >> >> If you want to control how something appears on the screen (i.e. in >> the string domain), use Format. > > > Jim, I know this. Apparently not completely. Singles do not have a 'format'. They cannot change from 'regular' to 'scientific'. That is strictly a function of being displayed as a string. If you want them to appear a certain way then you have to format them that way. You are NOT seeing singles. You're seeing strings, which are the result of formatting. Accept the default VB formatting, and you get what VB decides. Use Format and get what you want. It's really pretty simple. -- Jim Mack Twisted tees at http://www.cafepress.com/2050inc "We sew confusion" > > What I'm saying is that the value is changing from a regular decimal > value to Scientific Notation. So when I go to display it in a text > box, it shows as Scientific Notation. Yes, format is what will need > to be used, and that's still in discussion in this thread. However, > my question is WHY is it changing to Sci-Not? > > Thanks. > > Webbiz
![]() |
0 |
![]() |
On Tue, 01 Dec 2009 19:11:17 -0600, Webbiz <nospam@noway.com> wrote: >So if this were discovered, the string variable could be set by... > >Select Case DecCnt > Case 0 > sDataFormat = "#" > Case 1 > sDataFormat = "#.#" > Case 2 > sDataFormat = "#.##" > >...etc. > >Or is this too clumsy? I'm going to answer this one myself. I wrote this function to do the above... Public Sub SetDataFormat(ByVal Digits As Long) sDataFormat = "#" If Digits > 0 Then sDataFormat = sDataFormat & "." & Right("###########", Digits) End Sub To feed it the 'Digits', I am doing the following: If DigitsRightOfDec(CStr(Price)) > nMaxNum Then nMaxNum = DigitsRightOfDec(CStr(Price)) End If And DigitsRightOfDec is done by... Public Function DigitsRightOfDec(ByVal sNum As String) As Long If InStr(1, sNum, ".") > 0 Then DigitsRightOfDec = Len(sNum) - InStr(1, sNum, ".") End If End Function That's my solution short of having the user manually enter what the format should be. Webbiz
![]() |
0 |
![]() |
On 01/12/2009 20:07, Webbiz wrote: > On Tue, 01 Dec 2009 08:53:00 +0000, Dee Earley > <dee.earley@icode.co.uk> wrote: > >> On 01/12/2009 06:48, Webbiz wrote: >>> On Mon, 30 Nov 2009 21:21:52 -0500, "MikeD"<nobody@nowhere.edu> wrote: >>>> "Webbiz"<nospam@noway.com> wrote >>>>> Private Function DisplayAvgATR(ByRef Ranges() As Single) As String >>> >>> BTW, while you've no problem 'nitpicking'<g>, got any suggestions on >>> a snazy way to set the format pattern of the "#.####" based on the way >>> the values are formatted in the array to begin with? >> >> The values in the array wont have a format as they are Singles. >> Formatting only applies when you convert to a string for display purposes. >> If you want the caller to be able to control the output format, either >> return a single and let it format it or take the format string as a >> parameter. > > > I'm sorry, I didn't explain myself well. > > The data in the array is of a particular format although Singles. > Stock and Commodity prices come in various formats. Here are some > common ones: > <SNIP> > > Actual prices at the time of writing this. :-) > > So when one of these data files are loaded in, the output displays > would need to display results that are also in the appropriate format. But the input values do not have a format by definition of being a Single value. Yes, they will have some amount of decimal places, but no specific "000.00000" format so in your example, the code will ONLY see: 82.625 Live Cattle 59.2 Lean Hogs 399.75 Corn 1059.5 Soybeans 562.5 Wheat If your calling code wants a specific format, it should format the value it gets back (which will also be unformatted) It is still much safer to pass numbers around as numbers rather than formatted strings, then only convert them for display. Another example: a=1.4444444:?a 1.4444444 b=2.0000000:?b 2 c=2.5555556:?c 2.5555556 d=3.0000000:?d 3 ?(a+b+c+d)/4 2.25 You can possibly determine the number of decimal places a number has by multiplying by 10 in a loop until it approaches 0 (Don't use exactly 0 due to floating point maths) -- Dee Earley (dee.earley@icode.co.uk) i-Catcher Development Team iCode Systems
![]() |
0 |
![]() |
On Wed, 02 Dec 2009 09:40:44 +0000, Dee Earley <dee.earley@icode.co.uk> wrote: >On 01/12/2009 20:07, Webbiz wrote: >> On Tue, 01 Dec 2009 08:53:00 +0000, Dee Earley >> <dee.earley@icode.co.uk> wrote: >> >>> On 01/12/2009 06:48, Webbiz wrote: >>>> On Mon, 30 Nov 2009 21:21:52 -0500, "MikeD"<nobody@nowhere.edu> wrote: >>>>> "Webbiz"<nospam@noway.com> wrote >>>>>> Private Function DisplayAvgATR(ByRef Ranges() As Single) As String >>>> >>>> BTW, while you've no problem 'nitpicking'<g>, got any suggestions on >>>> a snazy way to set the format pattern of the "#.####" based on the way >>>> the values are formatted in the array to begin with? >>> >>> The values in the array wont have a format as they are Singles. >>> Formatting only applies when you convert to a string for display purposes. >>> If you want the caller to be able to control the output format, either >>> return a single and let it format it or take the format string as a >>> parameter. >> >> >> I'm sorry, I didn't explain myself well. >> >> The data in the array is of a particular format although Singles. >> Stock and Commodity prices come in various formats. Here are some >> common ones: >> ><SNIP> >> >> Actual prices at the time of writing this. :-) >> >> So when one of these data files are loaded in, the output displays >> would need to display results that are also in the appropriate format. > >But the input values do not have a format by definition of being a >Single value. >Yes, they will have some amount of decimal places, but no specific >"000.00000" format so in your example, the code will ONLY see: > >82.625 Live Cattle >59.2 Lean Hogs > >399.75 Corn >1059.5 Soybeans >562.5 Wheat > >If your calling code wants a specific format, it should format the value >it gets back (which will also be unformatted) >It is still much safer to pass numbers around as numbers rather than >formatted strings, then only convert them for display. > >Another example: >a=1.4444444:?a > 1.4444444 >b=2.0000000:?b > 2 >c=2.5555556:?c > 2.5555556 >d=3.0000000:?d > 3 >?(a+b+c+d)/4 > 2.25 > >You can possibly determine the number of decimal places a number has by >multiplying by 10 in a loop until it approaches 0 (Don't use exactly 0 >due to floating point maths) What I ended up doing was to insert this code at the point where prices are extracted by database and stored into a data array. If DigitsRightOfDec(CStr(Samples(nArrCnt).High)) > nMaxNum Then nMaxNum = DigitsRightOfDec(CStr(Samples(nArrCnt).High)) End If Whatever the maximum number of digits are right of the decimal, that value is then used to create the format for all price displays for that particular data set loaded. Public Sub SetDataFormat(ByVal Digits As Long) sDataFormat = "#" If Digits > 0 Then sDataFormat = sDataFormat & "." & Right("000000000", Digits) End Sub This sDataFormat is then used for all the Format() displays of the data. Seems to be working. Thanks. Webbiz
![]() |
0 |
![]() |
On Wed, 02 Dec 2009 20:28:16 GMT, deactivated wrote: >On Tue, 01 Dec 2009 00:48:11 -0600, Webbiz <nospam@noway.com> wrote: > >>On Mon, 30 Nov 2009 21:21:52 -0500, "MikeD" <nobody@nowhere.edu> >>wrote: > >>>Private Function CalcAvg(ByRef Ranges() As Single) As String >>>Dim n As Long >>>Dim sngTotal As Single >>>Dim sngAvg As Single >>> >>> For n = LBound(Ranges) To UBound(Ranges) >>> sngTotal = sngTotal + Ranges(n) >>> Next n >>> >>> >>> >>> 'Return the Average >>> sngAvg = sngTotal / (UBound(Ranges) - LBound(Ranges) + 1) >>> CalcAvg = Format$(sngAvg, "#.######") >>> >>>End Function > >Should not a function do a single thing? > >Like calculate an average and return in the same type. > >Any user who wants to format the result can then put it in another >function that would format the string. > >That way the user can reuse that average function elsewhere as it is >almost generic. I see your point. What I've noticed in all the time I've been learning things from this newsgroup is that the mindset is geared towards programming with the idea that others may be reusing the code or needing to work with it. Why my code tends not to usually come out this way is that I'm a lone soul in a home office writing code that only I will ever use. But I agree that my mindset needs to be adjusted towards a more reusable and cooperative mentality. And so I appreciate these reminders. :-) Webbiz
![]() |
0 |
![]() |
"Webbiz" <nospam@noway.com> wrote in message news:3noih59pnegc5oa59j5h2346o9ehbi08k2@4ax.com... > What I ended up doing was to insert this code at the point where > prices are extracted by database and stored into a data array. > > If DigitsRightOfDec(CStr(Samples(nArrCnt).High)) > nMaxNum Then > nMaxNum = DigitsRightOfDec(CStr(Samples(nArrCnt).High)) > End If Avoid using CStr() in this case. I think DigitsRightOfDec() looks for "." and CStr() would use the decimal separator in Control Panel, which could be "," or any other character. Use Str() instead, which always use US-English. The same applies when using Val(). It recognizes only US-English, so use Str/Val combo, or CStr/SSng or CStr/CDbl() to translate back and forth, and when using Cxxx functions, make sure that the locale is still the same. If you intend on making users from different locales send data to each other, store the data in its binary form, or use Str/Val combo which uses fixed format to avoid locale issues.
![]() |
0 |
![]() |
On Fri, 4 Dec 2009 14:59:23 -0500, "Nobody" <nobody@nobody.com> wrote: >"Webbiz" <nospam@noway.com> wrote in message >news:3noih59pnegc5oa59j5h2346o9ehbi08k2@4ax.com... >> What I ended up doing was to insert this code at the point where >> prices are extracted by database and stored into a data array. >> >> If DigitsRightOfDec(CStr(Samples(nArrCnt).High)) > nMaxNum Then >> nMaxNum = DigitsRightOfDec(CStr(Samples(nArrCnt).High)) >> End If > >Avoid using CStr() in this case. I think DigitsRightOfDec() looks for "." >and CStr() would use the decimal separator in Control Panel, which could be >"," or any other character. Use Str() instead, which always use US-English. > >The same applies when using Val(). It recognizes only US-English, so use >Str/Val combo, or CStr/SSng or CStr/CDbl() to translate back and forth, and >when using Cxxx functions, make sure that the locale is still the same. If >you intend on making users from different locales send data to each other, >store the data in its binary form, or use Str/Val combo which uses fixed >format to avoid locale issues. > > Interesting point I didn't think of. Now I would have to be concerned whether the data being loaded itself would have a "," rather than a "." Hmmm. thanks. Webbiz
![]() |
0 |
![]() |