Pet Bugs? 1261
benreece asks: "During my few years as a programmer/developer I've come across some strange bugs. Recently I found that Microsoft's VB/VBScript(ASP) round function has problems (for example, 'round(82.845)' returns '82.84' instead of '82.85'). It took me an annoyingly long time to realize the problem wasn't mine. I'm wondering what other obscure, weird, and especially annoying bugs in languages/compilers/etc have frustrated other developers." Memorable bugs. Every developer has one. What were yours?
That's what round SHOULD do (Score:4, Informative)
Rounding (Score:3, Informative)
We all learned in grade school that fives round up, but that doesn't make it preciesely even (there isn't a clean break between same-size sets of integers). So, under some schemes you round a five up if the number preceeding it is odd, down if it's even.
There are more complex schemes too, nearly all of them leading to a five getting rounded down some of the time.
82.84499 (Score:3, Informative)
Re:Rounding (Score:3, Informative)
Re:That's what round SHOULD do (Score:4, Informative)
http://www.devguru.com/Technologies/vbscript/quic
From MSDN... (Score:3, Informative)
Re:Rounding (Score:1, Informative)
Re: Wrong (Score:1, Informative)
The mathematic function round is defined as follows:
f(x) -> y
: x.n < x.5 -> y=x
: x.n >= x.5 -> y=x+1
microft DLL unloading (Score:2, Informative)
While exiting the program, Microsft
was unloading the socket DLL before DLL's we had
created. This caused our program to always crash
on exit.
It was obvious due to some internal DLL dependencies,
NT was choosing a random order
to unload DLLs.
We spent months trying to fight with Microsoft,
but could not get a solution. In the end
we decided not to support NT as a platform
Re:First ever bug (Score:2, Informative)
It was a joke, as the term bug predates the finding of that dead fly.
Check the Jargon File for details
Re:Not a bug (Score:3, Informative)
NO!!!!!!
Please don't take this as a flame, because I'm not upset with you, just the ignoramuses that came up with this scheme. This is a stupid way define ROUND(), and I disagree entirely with the justifiction because ROUND() has to be defined in the case that the digit is a zero, right?
In other words,
digits 0,1,2,3,4 get rounded DOWN
digits 5,6,7,8,9 get rounded UP
See - it's completely even without this odd/even cockamamie bullstuff. In fact, this definition of ROUND() throws off the statistics because it inappropriately weights the UP/DOWN results (either 50/50 or 60/40) based on info that is irrelevant to the ROUND() process.
It's like the people who coded this function never studied actual math and don't understand that the trivial case (zero) counts!
I'm sorry, I don't usually go off like this but when something this simple gets this fscked up, it really frosts my wheaties.
NT Backspace Bug (Score:3, Informative)
Re:From MSDN... (Score:2, Informative)
Even PHP round() uses odd/even to deal with halves. It's just the Right Way.
VS 6.0 getline() bug (Score:3, Informative)
http://support.microsoft.com/default.aspx?scid=kb; EN-US;q240015 [microsoft.com]
Now, I wasted a lot of time, but eventually confirmed on the web that this is a known bug in the Microsoft C++ library which has persisted from Visual Studio 5 into version 6.
Apparently, the Standard C++ Library used in both products was produced by Dinkumware and they, with their illustrious author/founder P. J. Plauger, were embroiled in a multi-year copyright dispute which made it impossible for them to debug (let alone update) the library. Most of the commenters online seemed to believe that this problem could not be solved and we had to wait for the copyright battle to be resolved (it has).
My impression is that Microsoft has elected not to provide an update to the library (which includes the STL) until the release of .NET.
Actually 4(?) different IEEE rounding functions (Score:5, Informative)
The others, from memory so they may be off, are:
- round towards zero. (.45 rounds to
- round towards -infinity (.45 rounds to
- round towards +infinity (.45 rounds to
and possibly round towards infinity (.45 rounds to
You should be able to control the behavior by some obscure function that nobody ever remembers.
Re:From MSDN... (Score:3, Informative)
Round to even (Score:3, Informative)
"Collapse stories" in preferences (Score:3, Informative)
Re:OpenGL Matrix Stack (Score:2, Informative)
I know first hand that this works under WindowsXP with the nVidia drivers. Not that the drivers should have anything to do with it.
As an aside, you should call glGetError() in a loop. There may be multiple errors waiting.
So either you had a broken OpenGL implementation or just forgot to call glGetError(). Anyway, just thought I'd point out that this isn't a generic OpenGL problem.
Re:1 != 1 (precision) (Score:2, Informative)
Re:From MSDN... (Score:1, Informative)
Re:That's what round SHOULD do (Score:3, Informative)
In fixed point binary the rint() (and MS Basic) behavior is necessary to avoid drift. Imagine a simple fixed-point that can only do integers and .5. It should be obvious that user the round-up scheme 2/3 of the numbers (the integers) do not change and 1/3 (the .5's) do change by .5. Thus the average drift is +1/6. In the rint() behavior, 2/3 of the numbers do not change, 1/6 round up by .5, and 1/6 round down by .5.
Re:I know, it's a feature. (Score:4, Informative)
Re:Hidden slashdot discussions (Score:3, Informative)
I really, really hope this is something that the
Re:Wrong, wrong, wrong, wrong, wrong. (Score:3, Informative)
5678901234
Yes there are 10 numbers that go to each integer, but they go to the '0' location in the above range. It should be obvious that the '0' is not in the middle but slightly to the right.
The rint() solution is to alternate sets of 11 and 9 numbers for each integer:
56789012345
678901234
In this case the 0 is centered in each set, so there is no drift of the average.
beat a-round the bush (Score:5, Informative)
There is no "proper" way to reduce the precision of a number under all circumstances. Each method of rounding or truncating 0.5 has its own pitfalls:
So, as you can see, there's no right way per se. It just depends on what you're doing.
--JoeRe:That's what round SHOULD do (Score:3, Informative)
In your words: That's nonsense. Of course
Consider one decimal point precision (for simplicity's sake), using your idea that
.0 => 0. Difference = 0.0
.1 => 0. Difference = -0.1
.2 => 0. Difference = -0.2
.3 => 0. Difference = -0.3
.4 => 0. Difference = -0.4
.5 => 1. Difference = 0.5
.6 => 1. Difference = 0.4
.7 => 1. Difference = 0.3
.8 => 1. Difference = 0.2
.9 => 1. Difference = 0.1
Sum difference: 0.5
Re:From MSDN... (Score:3, Informative)
Re:From MSDN... (Score:4, Informative)
The flaw in your reasoning is that you consider all the "round downs" to be the same. What you really need to do is to total the error:
0: no error
1: -1
2: -2
3: -3
4: -4
5: to be determined
6: +4
7: +3
8: +2
9: +1
Right now, without the 5 everything balances out, so the average error for 5 must be zero. Since it is either +5 or -5, then you must have an equal number of ups and downs, this rounding method is the easliest way to do that.
Re:That's what round SHOULD do (Score:2, Informative)
As to the point of including 1 in the upper set is faulty. When rounding you must divide up the set [0,1). You don't have the 1 to distribute. The way to equally distribute the numbers from [0,1) is the one previously described. The fact that the 0 doesn't change is irrelavent to me. In the case you desribed above, you must deal with distributing {0, 0.5} into two cases, there 0->1 and .5 -> 1 everything else falls out. You're double counting when you generate the number. 0 is 1 in the next case. Here an example should show it. All the cases betweeen 0 and 10:
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 stay the same.
Rounding 0.5, 1.5, 2.5, 3.5, 4.5, 6.5, 7.5, 8.5, 9.5 to 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 has slight skew because 0 should occur twices.
That's just a boundary problem. However, extend that out from 10 to infinity and go to negative infinity and it all comes out in the wash, and you're system doesn't. Yours should come out with: 0, 2, 2, 4, 4, 6, 6, 8, 8, 10.
There is internal skew towards even numbers. My system has absolutely no skew towards any numbers in the global sense on the set of all integers. The problem with you're analysis is that you say I go towards 1 to much, but the 1 in this case is the 0 in the next case, so it all balances out.
If I had mod points, you'd get +1 informative. The explaintion is clear, and now I understand what why people do think that, I just politely disagree now.
Thanks, Kirby
Re:spelling of functions (Score:2, Informative)
I thought it was pretty neat.
On the other hand, in c you could have just done the following:
#define colour color
another useful shortcut is to do this:
#define str chr* #define strs chr**
int main(int argc, strs argv, str env)
helps remove a few bugs from code you write.
Re:how 'bout HTML bugs? (Score:3, Informative)
Try the Mersenne Twister (Score:5, Informative)
There are implementations in C, Java, PHP, Fortran, Excel (I assume VBA) and probably others.
I only have experience with the Java impl, and it is very good. There are two classes, MersenneTwister, which is a true descendant of java.util.Random, and there is also a MersenneTwisterFast class, which does NOT inherit from Random (same public methods, and identical algorithm though), but clocks in at about twice the speed, due to tricks like avoidance of synchronization, and method inlining and finalizing.
Re:From MSDN... (Score:1, Informative)
But if you are rounding, you cant base your error on just the one digit. You have to consider all the digits following it as well. There is a big difference between .5 and .599999999999 for instance. Its a range, so the error in the rounding is also a range of possble error.
So, if you are starting with real numbers, the actual error would be as follows:
0: 0.0000001 - 0.9999999
1: 1.0000001 - 1.9999999
2: 2.0000001 - 2.9999999
3: 3.0000001 - 3.9999999
4: 4.0000001 - 4.9999999
5: either 5.0000001 - 5.9999999 or 4.0000001 - 4.9999999 depending on MS
6: 3.0000001 - 3.9999999
7: 2.0000001 - 2.9999999
8: 1.0000001 - 1.9999999
9: 0.0000001 - 0.9999999
the digit 5 really is in the center, but only if all the digits *after* 5 are 0.
A real world example: The number 2.595745 really *is* closer to the integer 3 than it is to 2, and should be rounded accordingly.
Re:When comments are more than comments... (Score:2, Informative)
the back-slash \ at the end of the line indicates to the compiler that the following line is to be considered part of the current line, meaning the compiler (iirc, lexical analyzer) will translate the above to the following:
#include
// tom 7 was here - 1998 \typedef unsigned char uchar;
int something(uchar c);
or more precisely--
--preprocessed contents of stdio.h--
int something(uchar c);
so the "bug" (actually a compile-time error) is an undefined token 'uchar,' unless of course, uchar has a definition in stdio.
reasoning doesn't apply to most quantities (Score:3, Informative)
Round-to-even is another one of those misfeatures that have crept into modern floating point standards without much justification.
Re:From MSDN... (Score:3, Informative)
You bring up a good point. If we really were looking at real numbers it wouldn't be an issue since you never get an exact
If you are rounding off one digit, I gave the values for summing a series in another post (banker's was exact, round up too high). I modified the program to round two digits and found that banker's rounding was short exactly as much as round up was ahead. For more than two digits, the banker error gets much worse, as would be expected. You should only use banker's rounding exactly on the half interval.
IEEE defaults to round to nearest, and I believe that in the case of midpoints it selects based on the low bit, this would be banker's rounding with the changes you noted. I had a hard time finding a good explanation of IEEE 754 in a quick Google search.
My Favortie Bug (Score:2, Informative)
below is the change for anyone who might have hit this or runs this setup. Hope it can help someone avoid it and all the time it wasted. Just love problems in the STL! *** are the two lines changed.
*** _C_end_of_storage = _C_finish = _C_start + __x.size();
}
else {
*** _C_end_of_storage = _C_finish = _C_start + __x.size ();
Changed To:
*** _C_finish = _C_start + __x.size();
}
else {
copy (__x.begin (), __x.begin () + size (), begin ());
uninitialized_copy (__x.begin () + size (), __x.end (),
begin () + size (),
_RWSTD_VALUE_ALLOC_CAST (*this));
}
*** _C_end_of_storage = _C_finish = _C_start + __x.size ();
This of course was becuase _C_end_of_storage should not have been set before the calling of size() as it would be incorrect.