
Width of stripes in bathroom
(This sounds hypothetical, but it really isn't.)<BR><BR>Ok, my wife has decided she's going to paint the bath room. She wants to do evenly sized vertical strips, approximately 6" wide.<BR><BR>I want them all to be a uniform size, so I told her to measure the room. Take that total and find a number that evenly goes into it.<BR><BR>Our room's total size is 247 inches. I came up with 6.5" by writing a program to loop from 5.5 to 7.5, stepping by 0.05 and checking to see which number evenly divides into it.<BR><BR>I found 6.5" by looking at the debugging output of the program, but the logic didn't pick it up.<BR><BR>The code:<BR>Dim RoomSize<BR> RoomSize = 247<BR>Dim InchTest<BR>Dim StripeCount, StripeCountWholeNumber<BR><BR>Dim ClosestStripeCount, ClosestStripeCountWholeNumberDiff<BR> ClosestStripeCountWholeNumberDiff = 99<BR> <BR> For InchTest = 5.5 To 7.5 Step .05<BR> StripeCount = RoomSize / InchTest<BR> StripeCountWholeNumber = Int(StripeCount)<BR> <BR> If (StripeCount  StripeCountWholeNumber) < ClosestStripeCountWholeNumberDiff Then<BR> ClosestStripeCountWholeNumberDiff = StripeCount  StripeCountWholeNumber<BR> ClosestStripeCount = InchTest<BR> End If<BR> Response.Write "InchTest=" & InchTest & "; StripeCount=" & StripeCount & "; StripeCountWholeNumber=" & StripeCountWholeNumber & "; Diff=" & (StripeCount  StripeCountWholeNumber) & "<br />" & vbCrLf<BR> <BR> If StripeCount  StripeCountWholeNumber = 0 Then<BR> Response.Write "***" & InchTest & "<br />" & vbCrLf<BR> End If<BR> Next<BR> <BR> Response.Write "<hr />" & vbCrLf<BR> Response.Write "ClosestStripeCount = " & ClosestStripeCount & "<br />"<BR> Response.Write "ClosestStripeCountWholeNumberDiff = " & ClosestStripeCountWholeNumberDiff & "<br />"<BR><BR>Now, my question. When I do the test for 6.5, do I get the following results?<BR>InchTest=6.5; StripeCount=38; StripeCountWholeNumber=38; Diff=2.1316282072803E14<BR><BR>Shouldn't the diff be 0?<BR><BR>Or, am I missing something with variable types?<BR><BR>And, should I be checking for a whole number in a different manner?

Wow...
I can't wait to see the answer to this. I've been messing with this code for nearly an hour. Everything seems AOK, except for the fact that it doesn't work. <BR><BR>I've checked varType's, I replaced int() with split(StripeCount,".") and countless other tweaks here and there. I cannot understand why 38  38 doesn't equal zero. <BR><BR>A brainbuster.

RE: Wow...
I seem to recall Bill Wilkinson posting a message on this subject, damned if I can find it though.  it's basically because VBScript is not a high precision mathematical language (in fact, IIRC, pretty much ALL highlevel languages have trouble with this sort of stuff, and even some lowlevel languages)  you'd probably get more accurate results by translating the values into binary values manually than letting the script engine do it for you...<BR><BR><BR>

I agree...
If you loop through the FOR LOOP with a step say .5, it gives you the expected result.<BR><BR>It is only when the step is .1 or .05 (meaning more visits through the FOR LOOP), the calculations go for a toss.<BR><BR>I remember playing with an electronic calculator once. Started trying to find the square root of 10. I got the answer but just for fun I kept going on for further square roots of the results I was getting.<BR><BR>Well, the last number in the series was 1. <BR><BR>~Roy

Roy is on the right track...
The problem is that 0.1 (and any subdivisions of 0.1, such as 0.05) is *NOT* exactly representable in binary arithmetic.<BR><BR>The easiest way to understand this is to consider an equivalent problem with decimal numbers. To wit:<BR><BR>How do you *accurately* represent 1/3 (onethird) in decimal notation? Hmmm??? Go ahead, I'm waiting.<BR><BR>Of course, I would wait an *infinitely* long time, because the correct answer is 0.333333333333333... repeating ad infinitum.<BR><BR>We all learned that in elementary school, no doubt.<BR><BR>So, now, what is the correct representation of 0.1 (1/10) in binary arithmetic? I'm waiting....<BR><BR>And I'll go on waiting. Because it is 0.000110011001100110011... repeating ad infinitum!<BR><BR>But just as *you* can't write and remember an infinite number of digits, neither can the computer. So let's say you can remember 10 digits to the right of the decimal point. And let's make you into a human decimal computer:<BR><BR><% LANGUAGE="HUMAN DECIMAL" %><BR><%<BR>fraction = 1.0/3.0<BR>sum = 0<BR>For i = 1 To 3<BR> sum = sum + fraction<BR> Response.Write sum<BR>Next<BR>%><BR><BR>Okay...YOU be the computer. YOU use pencil and paper and work this out. REALLY. Don't cheat. Really do it.<BR><BR>See you in the next message!<BR>

Read other message first!
Don't cheat! Read the other message and do the "homework".<BR><BR>Did you do it? Good for you!<BR><BR>And what did you end up "Response.Write"ing? If you did it right, you wrote:<BR><BR>0.3333333333<BR>0.6666666666<BR>0.99 99999999<BR><BR>OOPS! DID YOU SEE THAT! You just calculated that<BR> 3 * ( 1 / 3 )<BR>is *NOT* 1.0!!!! You are OFF by 1 in the last place, aren't you?<BR><BR>In other words, you have an error of 1E10 (same as 0.0000000001).<BR><BR>So this is *exactly* the problem the computer has when it has to use binary arithmetic to do:<BR><BR><% LANGUAGE="VBScript" %> <BR><% <BR>fraction = 1.0/10.0<BR>sum = 0 <BR>For i = 1 To 10<BR> sum = sum + fraction <BR> Response.Write sum <BR>Next <BR>%> <BR><BR>Wellll...not quite! Because VBScript (and most other computer languages, though there are major exceptions!) *KNOWS* that it can't do decimal arithmetic 100% accurately. So it *automatically* ROUNDS the results that it shows you! And, indeed, the last "sum" that it shows you will show up as<BR> 1.0<BR>or probably just as<BR> 1<BR><BR>But internally, it isn't *REALLY* 1.0! <BR><BR>To illustrate the problem, I wrote a little VBS program to see how accurately that VBS (well...actually, the INTEL or AMD hardware, which conforms to the IEEE floating point standards...so this truly is a universal characteristic) manages to represent 1/10. This is what I got:<BR><BR>0.000110011001100110011001100110011001 100110011001100110100000<BR><BR>That is 60 binary digits. And look at that! It is only accurate to 54 of those digits!<BR><BR>0.000110011001100110011001100110011 001100110011001100110[hl="yellow"]100000[/hl]<BR><BR>See? The representation give 54 binary digits and then rounds the 55th one and then the rest are all zero.<BR><BR>And 54 binary digits is just a little more accurate than 0.000000000000001 or 1E15.<BR><BR>So if you accumulate an error of 1E15 about 40 times (as Doug was doing), it's not surprising that you end up with a cumulative error of 2.1316282072803E14, is it? (In fact, that's 20 times 1E15, or 40 times 0.5E15, which confirms what I said about 54 binary digits.)<BR><BR>Enough said?<BR><BR>

And one more thing...
Even though I confirmed the "54 binary digits" via my little program (which I'll show you below), I already expected that answer.<BR><BR>Because I know that a doubleprecision floating point number takes 8 bytes of memory. And 8 bytes is 64 bits. But a floating point number is made up of both a "mantissa" and an "exponent". In other words, just as we might write<BR> 7.35E4<BR>to mean <BR> 0.000735<BR>or <BR> 9.13E+9<BR>to mean<BR> 9130000000.0<BR>the computer "writes" (internally)<BR> 1.001100110011B0101<BR>to mean<BR> 0.00001001100110011<BR><BR>And it so happens that IEEE floating point specs call for an 11 binary digit exponent. Leaving 53 bits for the "mantissa" (the fraction that is multplied by the exponent).<BR><BR>Well...not quite. Actually, you need one bit to indicate the sign of the number (0 for +, 1 for ). So now we are down to 52 bits. So how come we manage to get *almost* 55 bits of accuracy out of 52 bits??? Simple: because the first 3 bits of that mantissa are zero!<BR>0.[hl="yellow"000[/hl]11001100110011001100110011001100110011001100110011 0100000<BR><BR>And the system is smart enough to start at the first "1" bit, knowing that the rest will be zero. In other words, the number<BR>0.00011001100110011001100110011001100110 01100110011001101<BR>is represented as<BR>0.110011001100110011001100110011001100110011 0011001101B0011<BR><BR>So, indeed, we have shown, two very different ways (and confirmed, via Doug's experimentation, in a third way) that double precision floating point numbers have 54 binary bits of accuracy.<BR><BR>Aren't numbers fun?<BR><BR>

Oops...forgot the little program:
See if you can figure out how/why it works!<BR><BR>******** fractions.asp **********<BR><HTML><BODY><BR> <%<BR>f = CDBL(1)/CDBL(10)<BR><BR>h = 0.5<BR><BR>Response.Write "0."<BR><BR>For i = 1 to 60<BR> If h > f Then<BR> Response.Write "0"<BR> Else <BR> Response.Write "1"<BR> f = f  h<BR> End If<BR> h = h / 2<BR>Next<BR>%><BR></BODY></HTML><BR>

Actually...
...you can get exact results using any fraction that is exactly representable in powers of two.<BR><BR>So 0.5 (1/2), 0.25 (1/4), 0.125 (1/8), 0.0625 (1/16), etc.<BR><BR>But also 0.75 (1/2 + 1/4), 0.625 (1/2 + 1/8), 0.875 (1/2 + 1/8 + 1/8 + 1/8).<BR><BR>After reading my other gobbledygook, does that make sense now?<BR><BR>

Thanks.
I've read the responses and I understand the explaination of why it doesn't work. Even have a piece of paper where I did Bill's test.<BR><BR>Bill's little VBS program doesn't make a lick of sense to me, but, I might give it a go a little later, when I'm a little more awake.
Posting Permissions
 You may not post new threads
 You may not post replies
 You may not post attachments
 You may not edit your posts

Forum Rules

