If you've ever gone shopping for digital cameras, you'll know that the resolution of the image sensors keeps going up, and keeps being featured prominently on the packaging. Way back on the early days, this was good: you need at least one or two megapixels if you want to print photos at large sizes, and if you do any cropping before printing you'll lose a bit of resolution there. So the jump up from sub-megapixel resolution was a very good thing.
But we've long since passed the point where any more resolution is useful. Take a look at the PowerShot G10 (picked more or less at random). It takes a 14.7 megapixel picture (4416 x 3312 pixels). You could take a shot of a crowd, zoom in to one person's face, blow it up to poster size and it would still look fine. Except that it wouldn't, because by now you're probably past the ability of the optics to focus anyway. Enough with the megapixels already!
I know this isn't a new complaint. Nearly every review at dpreview.com complains about the manufacturers increasing resolution with every new camera, often at the expense of other aspects of image quality. The problem is that camera makers need a big number to put on the box to make the new camera seem better than the last one, so even if the extra resolution is useless for photography, it's good for marketing.
So here's a suggestion for the camera marketers: Put the light sensitivity on the box. In big print. Bigger print than the resolution. It's easy to measure, it gives you a nice big number to stick on there, and it would actually be useful information.
See, when I go shopping for a camera, that's the one thing I want to know: how good is it for low-light shots? I'm not a serious photographer; I just want to take pictures of my kids and vacation spots and the things like that. But I'm tired of having to use the flash in anything less than full daylight. I can guarantee that if could somehow find out which cameras were better in low-light conditions, that would influence my purchasing. But I can't, so it doesn't.
Sunday, December 7, 2008
Thursday, December 4, 2008
Random things that annoy me
I've been putting off this post for ages, because even though it's a straightforward problem, I find it difficult to explain clearly. But I guess I'm never going to get the hang of that unless I start posting once in a while. So here goes.
The modulus operation in C, C++, C#, F#, Java, and a host of other programming languages is broken and stupid.
Here's how modulus mathematics works: you do some integer operation mod N, and the result stays in range [0,N). Where it would normally fall outside that range, it just "wraps around" to the other side. Simple.
Now let's translate that into C:
What's happening is that in C,
The reason it matters is that we almost always want to constrain the result to a certain range, just like the mathematical modulus does. For example, suppose we want to add an offset to an array index:
The same problem shows up if you're manipulating days of the week, or angles that you want to constrain to a circle, or any other number you want to constrain to a certain range.
Now, one might argue that it's a tradeoff: sometimes you want one behavior, sometimes you want the other, and the language designer has to pick one. Except that in over twenty years of programming, and hundreds of places I've seen or written the modulus operator, I haven't yet encountered one case where the C behavior simplified the code. Sometimes it makes the code more ugly and complex and slow, sometimes it doesn't matter one way or other other; it's never actually better.
For C this behavior was forgivable, because it was just doing a direct mapping to the native division/modulus operation of whatever the underlying platform was, and in hardware it's easier to implement that way. But for all the later languages, boo hiss.
Just for the record, Python gets it right:
Hooray!
And Haskell gives you both the useful version and the stupid one:
Also, IEEE 754 (float) arithmetic can give you either behavior, depending in a sensible way on the rounding mode. Unfortunately most languages go to some pain to hide this, and make sure the fmod() function jumps through extra hoops to always return a stupid result.
Here's another way to look at it. Plotted, the modulus function looks like this:
![plot of (a mod 10) for a in [30,30]](//2.bp.blogspot.com/_B1qW_llHr0E/STjRYPkXfHI/AAAAAAAAAAU/VWt1tWtjJW0/s400/mod_good.png)
Nothing much to see, just little diagonals over and over to infinity. Here's the C mod function:
![plot of (a mod 10) for a in [30,30] with stupid mod](//2.bp.blogspot.com/_B1qW_llHr0E/STjRI0WwpWI/AAAAAAAAAAM/2pKUDu31GDk/s400/mod_bad.png)
Little diagonals repeated to infinity again, except... an arbitrary change at the origin. Why? Just to cause pain.
And that's all.
The modulus operation in C, C++, C#, F#, Java, and a host of other programming languages is broken and stupid.
Here's how modulus mathematics works: you do some integer operation mod N, and the result stays in range [0,N). Where it would normally fall outside that range, it just "wraps around" to the other side. Simple.
0 + 1 (mod 3) = 1
1 + 1 (mod 3) = 2
2 + 1 (mod 3) = 0
and so on...
2 - 1 (mod 3) = 1
1 - 1 (mod 3) = 0
0 - 1 (mod 3) = 2
Now let's translate that into C:
(0 + 1) % 3 == 1
(1 + 1) % 3 == 2
(2 + 1) % 3 == 0
looks good so far...
(2 - 1) % 3 == 1
(1 - 1) % 3 == 0
(0 - 1) % 3 == -1
what the heck?What's happening is that in C,
(a % b) takes the sign of a, rather than the sign of b. There are historical reasons for C to act this way. For all the other languages, I think it falls more under "lack of thought." Or at least, "lack of giving a damn about your programming language."The reason it matters is that we almost always want to constrain the result to a certain range, just like the mathematical modulus does. For example, suppose we want to add an offset to an array index:
// no good! offset might be negative
i = (i + offset) % array.size
// here's what you have to use instead.
i = ((i + offset) % array.size + array.size) % array.size
// or this:
i = (i + offset) % array.size
if(i < 0) i += array.size
The same problem shows up if you're manipulating days of the week, or angles that you want to constrain to a circle, or any other number you want to constrain to a certain range.
Now, one might argue that it's a tradeoff: sometimes you want one behavior, sometimes you want the other, and the language designer has to pick one. Except that in over twenty years of programming, and hundreds of places I've seen or written the modulus operator, I haven't yet encountered one case where the C behavior simplified the code. Sometimes it makes the code more ugly and complex and slow, sometimes it doesn't matter one way or other other; it's never actually better.
For C this behavior was forgivable, because it was just doing a direct mapping to the native division/modulus operation of whatever the underlying platform was, and in hardware it's easier to implement that way. But for all the later languages, boo hiss.
Just for the record, Python gets it right:
>>> (-1) % 3
2
Hooray!
And Haskell gives you both the useful version and the stupid one:
Prelude> (-1) `rem` 3
-1
Prelude> (-1) `mod` 3
2
Also, IEEE 754 (float) arithmetic can give you either behavior, depending in a sensible way on the rounding mode. Unfortunately most languages go to some pain to hide this, and make sure the fmod() function jumps through extra hoops to always return a stupid result.
Here's another way to look at it. Plotted, the modulus function looks like this:
![plot of (a mod 10) for a in [30,30]](http://2.bp.blogspot.com/_B1qW_llHr0E/STjRYPkXfHI/AAAAAAAAAAU/VWt1tWtjJW0/s400/mod_good.png)
Nothing much to see, just little diagonals over and over to infinity. Here's the C mod function:
![plot of (a mod 10) for a in [30,30] with stupid mod](http://2.bp.blogspot.com/_B1qW_llHr0E/STjRI0WwpWI/AAAAAAAAAAM/2pKUDu31GDk/s400/mod_bad.png)
Little diagonals repeated to infinity again, except... an arbitrary change at the origin. Why? Just to cause pain.
And that's all.
Friday, August 29, 2008
Pause this!
Try this: start watching video with the youtube video player (or other streaming video player) over a moderately slow internet connection—slow enough that the video playback goes faster than the download.
The video playback will of course catch up to the buffering every few seconds, so there's no more data and playback has to pause. There are at least a couple of reasonable options for the player UI now:
The pause issue would at least be ameliorated if I could just drag the scrubber back a few seconds, to get a bit of playback time with which to battle the UI. But that's broken too: if I try that, odds are excellent that the playback will freeze for some mysterious network hijinx and I'll have to start all over. Why? The data should already be there. Just play it. Why on earth should that have any effect on the download process?
And finally: why is it that sometimes when the scrubber shows that the movie is buffered ahead of the current play position, it won't play until it buffers even farther? The whole point of the buffer indicator is to show me how many seconds of playback have been downloaded. If they aren't available, then don't show them.
These are rhetorical questions, by the way. There is no good reason for any of these behaviors.
(I pick on youtube only because they're popular. Most, though not quite all, other video players have the same problems.)
The video playback will of course catch up to the buffering every few seconds, so there's no more data and playback has to pause. There are at least a couple of reasonable options for the player UI now:
- Pause the video, just as if I'd hit the 'pause' button myself. Leave it paused until I hit play again.
- If you're not going to leave it paused, then don't change the damned play button to claim that you are. Leave the button alone, and leave it active so I can press it to pause the video for real.
The pause issue would at least be ameliorated if I could just drag the scrubber back a few seconds, to get a bit of playback time with which to battle the UI. But that's broken too: if I try that, odds are excellent that the playback will freeze for some mysterious network hijinx and I'll have to start all over. Why? The data should already be there. Just play it. Why on earth should that have any effect on the download process?
And finally: why is it that sometimes when the scrubber shows that the movie is buffered ahead of the current play position, it won't play until it buffers even farther? The whole point of the buffer indicator is to show me how many seconds of playback have been downloaded. If they aren't available, then don't show them.
These are rhetorical questions, by the way. There is no good reason for any of these behaviors.
(I pick on youtube only because they're popular. Most, though not quite all, other video players have the same problems.)
Wednesday, June 11, 2008
I've finally started working on some web games. The first thing I did was spend a bit of time investigating what platforms are available. And it really was a bit of time, because it looks like Flash is still the beginning and then end of choices if you want a reasonable fraction of people to be able to actually play your game. So I downloaded the Flex demo and started playing around.
Actionscript 3 is a hybrid language, trying to mix mediocre static typing (like C# or Java before generics) with the dynamic typing of previous versions. It seems to me like it really tries to push you toward the static side, though. For example, in the default configuration, Flex requires type declarations on everything, so if you want a plain old dynamic object, you have to write
where it used to be just
On the whole this is more annoying than useful. I'd rather have it do type deduction, so that
Other languages (C# 3.0, C++, VB, etc.) are going this way, and it really works much better. Maybe ActionScript couldn't do this for backwards compatibility, but it would have been nice.
Ok, so this wasn't insightful. At least I got another post up.
Actionscript 3 is a hybrid language, trying to mix mediocre static typing (like C# or Java before generics) with the dynamic typing of previous versions. It seems to me like it really tries to push you toward the static side, though. For example, in the default configuration, Flex requires type declarations on everything, so if you want a plain old dynamic object, you have to write
var x:Object = {...}where it used to be just
var x = {...}On the whole this is more annoying than useful. I'd rather have it do type deduction, so that
var x = {...} // same as x:Object = {...}
var s = "..." // same as s:String = "..."
Other languages (C# 3.0, C++, VB, etc.) are going this way, and it really works much better. Maybe ActionScript couldn't do this for backwards compatibility, but it would have been nice.
Ok, so this wasn't insightful. At least I got another post up.
Sunday, April 6, 2008
Sludge for teh win
Over a month since my last (and first) post. This is not going well.
Here's the problem. My intention was to fill this blog with clear and insightful analysis of all sorts of programming-related topics. I have a long list of topics to rant about, so there's no shortage of material. But when I sit down to write about one of them--let's say some low-hanging fruit like how much iostreams sucks--I get worried about the accuracy of the things I'm saying. I mean, this is the internet. You can't just say things that might be wrong. So I start double checking my facts and three hours later I realize I've wasted my entire allotted time reloading reddit and rotting my brain with fluff.
So then I figure, all right, the blog is also a way to practice my writing. So I'll just write about how I don't have anything to write about, and at least that will develop the habit and hopefully over time I'll manage to shift over to meatier stuff.
But I don't want to have a blog like that, a miserable swamp of unreadable wannabe writer sludge. So I don't write that either. And then it's over a month since I posted and the thing is looking dead. I don't want a left-for-dead-after-one-post blog either!
So for now I guess "miserable swamp of unreadable wannabe writer sludge" is the winner. Hooray?
Next time: what I found when I looked under my toenails!
Here's the problem. My intention was to fill this blog with clear and insightful analysis of all sorts of programming-related topics. I have a long list of topics to rant about, so there's no shortage of material. But when I sit down to write about one of them--let's say some low-hanging fruit like how much iostreams sucks--I get worried about the accuracy of the things I'm saying. I mean, this is the internet. You can't just say things that might be wrong. So I start double checking my facts and three hours later I realize I've wasted my entire allotted time reloading reddit and rotting my brain with fluff.
So then I figure, all right, the blog is also a way to practice my writing. So I'll just write about how I don't have anything to write about, and at least that will develop the habit and hopefully over time I'll manage to shift over to meatier stuff.
But I don't want to have a blog like that, a miserable swamp of unreadable wannabe writer sludge. So I don't write that either. And then it's over a month since I posted and the thing is looking dead. I don't want a left-for-dead-after-one-post blog either!
So for now I guess "miserable swamp of unreadable wannabe writer sludge" is the winner. Hooray?
Next time: what I found when I looked under my toenails!
Friday, February 29, 2008
Illumination
Oh dear. Another blog has been inflicted on the world.
But I have no doubt that someday it will be read by uncountably many people—that's eleven according to my fingers—and of course they will search back through the archives to find this first posting that explains the purpose and motivation of the whole thing. So explain I shall.
First, the name. I wanted a domain name where I could publish some web games, so I went looking for one that wasn't taken. I don't remember what my top choice was, or my second, or my third; I do remember that after a couple hours of looking for any halfway decent name that wasn't already taken, my standards were getting pretty low. So that's how I ended up with bogweasel.com. It's what was left.
So when I needed a blog name I thought I'd save myself some time and just stick with the whole weasel theme.
I only got around to making one web game, the result of one weekend spent learning flash. Behold.
Where was I... oh, me. The author. I'm a programmer with a tendency to go off on rants about all sorts of topics, mostly but not exclusively related to programming. Somewhere around 1994 or 1995, I had a brilliant idea: I should write these rants down as essays and post them on the internet for people to read! Then I could enlighten the masses while saving my coworkers the pain of having to listen to all my crap. Plus I needed the writing practice.
Unfortunately, I'm a bit of a procrastinator, so it took me thirteen years to get around to starting, and now everyone is doing it. Oh well, better late than never, and I still need the writing practice.
But I have no doubt that someday it will be read by uncountably many people—that's eleven according to my fingers—and of course they will search back through the archives to find this first posting that explains the purpose and motivation of the whole thing. So explain I shall.
First, the name. I wanted a domain name where I could publish some web games, so I went looking for one that wasn't taken. I don't remember what my top choice was, or my second, or my third; I do remember that after a couple hours of looking for any halfway decent name that wasn't already taken, my standards were getting pretty low. So that's how I ended up with bogweasel.com. It's what was left.
So when I needed a blog name I thought I'd save myself some time and just stick with the whole weasel theme.
I only got around to making one web game, the result of one weekend spent learning flash. Behold.
Where was I... oh, me. The author. I'm a programmer with a tendency to go off on rants about all sorts of topics, mostly but not exclusively related to programming. Somewhere around 1994 or 1995, I had a brilliant idea: I should write these rants down as essays and post them on the internet for people to read! Then I could enlighten the masses while saving my coworkers the pain of having to listen to all my crap. Plus I needed the writing practice.
Unfortunately, I'm a bit of a procrastinator, so it took me thirteen years to get around to starting, and now everyone is doing it. Oh well, better late than never, and I still need the writing practice.
Subscribe to:
Comments (Atom)