|
|
CodeBubba wrote: I have had to clean up more than my share of messes after people who threw
code together and never ran it
There's always some branch that's too inconvenient to test or the schedule doesn't permit to be tested. I kept track at my last job.. about 90% of the bugs were with untested code. The other 10% were a mix of unexpected consequences to changes elsewhere, and design flaws/miscommunication. At a previous job, every time I exercised an error branch in my code, I discovered a crash elsewhere in the code.
We need to start making a distinction between unit tests used to test internal correctness, and those for verifying regression that test only the external interfaces and behavior of the unit. Internal-correctness tests are white-box tests, while regression tests are back-box tests. After modification, only regression tests should be expected to pass, and any internal-correctness tests should be thrown away.
In my experience, if the developer who did the internal implementation writes the unit tests, they toss in a healthy dose of the internal-correctness variety, and then keep them thinking they are regression tests, undermining the usefulness of regression unit tests through excessive maintenance.
We can program with only 1's, but if all you've got are zeros, you've got nothing.
|
|
|
|
|
Well... I think you're missing the fact that the little unit tests you write after you write you're gone gets done on a much greater scale than you think. Banking software, life critical software (medical systems, and military/commercial aircraft systems), ect. companies employ whole teams of unit testers to ensure some level of standard. Unit testing is only one type of testing that gets performed on these software systems in order to minimize failure. Yes unit testing your own stuff is good, however the real power of unit testing comes in where someone else tests your stuff, as one tends to not see your own mistakes.
The topic of proper unit testing is a completely different one. Proper unit testing can only be done if the necessary things was done before hand in order for you to write your unit tests. You should have some form of a design document (preferable not generated from code) which enables you to right your tests. You should never write your tests from the actual source. (However can also find one or two bugs this way).
Testing = Quality = Happy Customer = $$$ in an perfect world that is.
Testing = Good marketing pitch
"Program testing can be used to show the presence of bugs, but never to show their absence."
<< please vote!! >>
|
|
|
|
|
R. Erasmus wrote: Testing = Good marketing pitch
It should be:
Testing = Good marketing pitch = Happy Customer (Until it buys the product) = $$$
|
|
|
|
|
It might be due to a change that our industry is currently facing.
No other industry than ours can decorate a new version with a huge list of bug fixes and call that a feature!
Imagine your car is ready from maintenance and the report says "The breaks are now working when the car drives downhill also"...
Someone, sometime in some place must have realised that shipping quality software with little bugs (I don't say "no bugs" because that is not achivable) is an attribute that gives you a better position in business competition. Better testing is seen as a (or one) cure to that. For us as developers that means unit testing as a tool and practices like test driven development, pair programming and / or scrum / kanban.
The point why there is so much talk about unit testing IMHO is that it is relativley new to us, it is - as others already mentioned - sometimes hard to do if it should be done right and even though the management wants less bugs, they sometimes are not willing to spend the extra money that is needed to educate us in writing (good) unit tests or allow us the extra time that is (not always) needed to write the tests.
Regs,
Chris
|
|
|
|
|
Oddly enough, I don't at my work place. Never have touched unit tests. Mostly because my software controls industrial equipment, it's hard to simulate all the live sensor data that regulates the logic. I usually have some I/O in a test cabinet to work with, and a few customers to test at their facilities, but beyond that I have to write the entire code fault tolerant so if it fails, it logs the error for me and continues on.
|
|
|
|
|
Gary Huck wrote: Is such a thing not part of every programmer's everyday life?
Nope. And many who do attempt it fail to actually write complete tests especially for error scenarios. Although to be fair they often fail to code for those as well.
|
|
|
|
|
Typically, all computer math is done modulo 232 (or 2something, which the rest of my post trivially generalizes to). This leads to sometimes surprising effects, such as that the sum of a and b , while both positive, can end up being lower than min(a, b) , which is rather well-known. Less well known is that it also means that some numbers have a multiplicative inverse[^], ie a number x<sup>-1</sup> such that x<sup>-1</sup>x=1 . As mentioned in the wikipedia article, the numbers which have multiplicative inverses are precisely those coprime to the modulo. The modulo is a power of two, which means that a number has a multiplicative inverse iff it is odd.
And it turns out to be actually useful, too. One application is, as you might guess from the title, divisibility testing.
Multiplying a number by an odd number is reversible - you can take the multiplicative inverse of the odd number and then multiply by it to get the original number back. Put differently, the function f(x) = x * k (for k odd) is a bijection.
Modular multiplication is associative, so a multiple of k , say n * k multiplied by inv(k) (the multiplicative inverse of k ), is n , because
(n * k) * inv(k) =
n * (k * inv(k)) =
n * 1 =
n
That means that in x * inv(k) , the multiples of k "use up" the results from 0 through (232-1)/k , they can't be used twice because it's a bijection, leaving just the numbers bigger than (232-1)/k for non-multiples-of-k. Which suggest a very simple divisibility test:
static bool IsDivisibleByOdd(uint x, uint divisor)
{
if ((divisor & 1) == 0)
throw new ArgumentException("divisor must be odd");
uint d_inv = inv(divisor);
uint biggest = uint.MaxValue / divisor;
return (x * d_inv) <= biggest;
}
static uint inv(uint d)
{
uint x = (d * d) + d - 1;
uint t = d * x;
x *= 2 - t;
t = d * x;
x *= 2 - t;
t = d * x;
x *= 2 - t;
return x;
}
And there is a problem. It didn't avoid the division, it turned it into an other division. So this doesn't actually help - in fact it's slower than the usual way.
It also fails to work when the divisor is 1 (but that's a silly thing to ask of it anyway).
But. And there is a but. If you want to test for a lot of number whether they are divisible by some odd number1 that doesn't vary in that test (but isn't a constant2), you only have one division, one inv , and the cost per item is only a multiplication and a test. What's more, no compiler I know of automatically does this for you, so this can actually save time.
1. the principle is extendible to even numbers (except zero, of course) as well - shift it right by the number of trailing zeroes and shift left by the same amount after the multiplication. This also means it won't work for powers of two (which would become 1 after the shift), but of course for powers of two there is an even faster way anyway. Unfortunately, C# lacks _BitScanforward[^] or a replacement, making the algorithm "less nice" if it has to account for even numbers.
2. otherwise the compiler would optimize it anyway and you'd gain nothing.
ps: perhaps I should start a blog instead of dumping things like this in the Lounge every week..
edit: this post has been bloggified: http://bitmath.blogspot.com/2012/09/divisibility-and-modular-multiplication.html[^]
|
|
|
|
|
Maybe you should write an article, with so much on your mind 
|
|
|
|
|
harold aptroot wrote: C# lacks _BitScanforward[^] or a replacement, making the algorithm "less nice" if it
has to account for even numbers
Yes but quite possible to either pinvoke _BitScanForward or write a shim Win32 DLL, or possible to recreate _BitScanForward in c# using bit operations?
I'll leave that for the reader to sort out
|
|
|
|
|
Sure, I just filed those under "not nice"..
They're really nice enough I suppose, just not as nice as it would be in C++.
|
|
|
|
|
harold aptroot wrote: They're really nice enough I suppose, just not as nice as it would be in C++.
I agree and would it be faster, pinvoking verses c# implementation using bit operators who knows, it would be interesting if anything to find out.
|
|
|
|
|
Normally I would test it, but I have to go. I'll probably get back to this later.
|
|
|
|
|
harold aptroot wrote: Unfortunately, C# lacks _BitScanforward[^] or a replacement
That is annoying for me, too. If you look at the "Possible Optimizations" section in my article, SlimList, you'll see that I list BSR (bit scan reverse) as a possible optimization, but did not because it's not part of the base language (and I am guessing it is not part of all processors). A shame, as that could speed up my code by a couple orders of magnitude.
|
|
|
|
|
ARM and Itanium can count leading zero's too.. (and trailing, but it takes more than one instruction on ARM) but ok it's not part of All processors. I'm not sure why that would matter though, most processors don't have hyperbolic trig build in either, but the Math class offers it anyway. And x86 has sine, cosine and tangent instructions, but the JIT compiler doesn't use them.
So, bit scans wouldn't seem out of place to me (possibly as CLZ/CTZ, to avoid problems when feeding it a zero).
|
|
|
|
|
harold aptroot wrote: x86 has sine, cosine and tangent instructions, but the JIT compiler doesn't use them
Bastards!
|
|
|
|
|
You can try simulating a bitscanforward with a table lookup (e.g. 255 byte table, and then do that on each byte) to speed it up a little in C#.
Wout
|
|
|
|
|
Or a 32 byte table and a multiply, or other tricks..
I file it all under "less nice".
|
|
|
|
|
please, start a blog, otherwise I'll probably lose the next one
I'm brazilian and english (well, human languages in general) aren't my best skill, so, sorry by my english. (if you want we can speak in C# or VB.Net =p)
|
|
|
|
|
Well, I got nothing this week. I guess I've been slacking too much. So, nothing to miss..
|
|
|
|
|
Google and M$ gave money to the Obama campaign !
Can anyone explain this please ? Why do they support Obama ?
==================================================
The greatest trick the U.S Govt ever played on the world was getting people to think that Satellite Torture was all about crazy people...
|
|
|
|
|
I have a question. Given that Microsoft are no longer the richest software company in the world, why do you use M$?
|
|
|
|
|
Pete O'Hanlon wrote: Given that Microsoft are no longer the richest software company in the world, why do you use M$?
They don't have to be the richest company in the world to overprice their products.
|
|
|
|
|
In that case, you could include Apple, Coca Cola, MacDonalds.... That's a long, long list.
|
|
|
|
|
Could you help me find the S in Apple and Coca Cola, so I can substitute it for a $?
Make it work. Then do it better - Andrei Straut
|
|
|
|
|