Help Wanted: IE/Win Script Weirdness
Published 19 years, 3 months pastOkay, JavaScript / DOM scripting gurus, I need your help. Explorer for Windows is completely baffling me and hopefully one of you out there can determine what’s making it act so peculiar. To see the problems, go to the debug version of HYDEsim in IE/Win and compare the the results to those in Firefox.
Problem #1 is that the rounding function I wrote doesn’t seem to be working right (though this could be an effect of VirtualPC). Here’s the function:
function round(x,dp) { var rt = Math.pow(10,dp); return Math.round(x*rt) / rt; }
That’s it. All it’s supposed to do is round off a number to the given number of decimal points. Thus, var test = round(3.1415926539,3)
should return 3.142
. In IE/Win, instead of the expected 0.71
, I’m getting results like 0.7100000000000001
. Huh? Where the heck did that come from? Is this fallout from that Intel rounding bug everyone was smirking about five years ago, or what?
Problem #2 is perhaps more obvious: the Great Big Circles on the map. I’m creating the GIcon
objects correctly, passing in the height and width of each one. The top left corner placement is correct for each marker. They just haven’t been resized in any way at all, and so are being drawn at their inherent 1000-by-1000 size. Is this a breakdown in IE/Win, the Google Maps API, or something else? I tried passing pre-rounded values and it didn’t seem to help. Am I stuck here, or is there a solution?
Many thanks for any help you can provide.
Comments (10)
Problem #1: I don’t understand what you’re IE is doing, that rounding function works perfectly for me in IE6, Firefox and Opera.
Ditto. #1 works fine on XP and IE6. Virtual PC I reckon.
Problem #2.
You are using a PNG in IE. Welcome to the funhouse!
The only way of making IE (pre v7!) display PNGs properly is using filters and the AlphaImageLoader. This seems to be what Google are doing, otherwise you’d get grey bits for transparency etc.
So there is a bug in the way Google does the sizing of PNGs using the AlphaImageLoader, they should be using ‘scale’ and they’re using ‘crop’. Or assuming the size of the element is the same as the size of image. I’d report it to them.
Can you set the size of the GIcon before you set the image? Or is it only available in the constructor?
Fractional numbers in computers are not stored as intuitively as we may think. As with numbers above 1, they’re stored as powers of two:
5 = 1*(2^2) + 0*(2^1) + 1*(2^0); written as 101 in binary
0.75 = 0*(2^0) + 1*(2^-1) + 1 * (2^-2) = 0.11 in binary
There is a limit to the number of bits a number can use; for pure integer numbers the limit is pretty high but with fractional numbers, there are rounding errors all over the place for numbers that at first may appear trival; 0.1 (decimal) is represented as 0.00011[0011…] so adding 10 times 0.1 will probably not give 1
Floating-point numbers are always something to avoid when possible (especially testing for equality between them). Depending on variable storage size, CPU, order of functions, errors will accumulate.
The safest way to work around the problem is to cast the float to a string, chop the string and cast back to a float – hoping this function is not used 10 times a second :)
Should you want to know more about this problem, you can scan these threads:
http://groups-beta.google.com/groups?hl=en&lr=&ie=UTF-8&num=50&q=johnh%20rounding%20%22decimal%20places%22&qt_s=Search
Thanks to information related to the results in Patrice’s comment, I discovered a method that works in Google Maps capable browsers:
toFixed(n)
. It works for the cases I need, which are the radius distances and map sizes. So that’s fixed in the -db version.As for the circle sizing, it is indeed an effect of the way markers are constructed, and the IE filter stuff Tim pointed out. I found one comment in the Google Maps discussion group about this, basically pointing out the problem but not knowing how to fix it. I didn’t see any replies, so I’d guess it’s something still to do. I’ll take a crack at fixing it on the client side, but will also propose a fix in the discussion group. (As well as ask for real honest-to-gosh circle primitives so I don’t have to mess with scaled markers any more.)
This has nothing to do with the infamous Intel math bug from ages ago. For one thing, that’s been fixed for quite some time now. Also, it didn’t manifest every time you did math on the processor, only when converting a floating point number to an integer, and then only when the number was far too large to fit in the integer anyway. As I recall it failed to handle the overflow error correctly.
Anyway, floating point numbers are always a pain. As Patrice says, computers just don’t have enough room to store all the binary digits needed to represent numbers we commonly represent with one or two decimal digits.
Here’s some code I’ve used for an order form. I probably stole it from someone many years ago, and only refer back to it when something like that creeps up, but it works. It’s designed for trimming to hundredths (for cents in USD) but I’m sure you can modify it for your needs too. One of these days, i’m gonna have to clean this up…
//this function makes sure any number is properly rounded to two decimal places
function fix(num) {
// fix that damn math rounding bug, AAARGGGGGGG!!!
string = "" + Math.round(num*Math.pow(10,2))/Math.pow(10,2);
// then massage the data to get a useful price
if (string.indexOf('.') == -1)
return string + '.00';
seperation = string.length - string.indexOf('.');
if (seperation > 3)
return string.substring(0,string.length-seperation+3);
else if (seperation == 2)
return string + '0';
return string;
}
Between Grant’s code (as well as related routines seen elsewhere) and help received on the google-maps-api discussion group, everything’s back to normal in IE/Win. Thanks for the assistance, folks!
HI
you need to write return Math.round ( (x*rt) / rt);
That’ll solve your problem.
Thanks
Sayantani from india
Read that you have fixed some issues with comments. I tried commenting on this just minutes after this post was originally posted, but got an error. The I tried mailing you, but god a bounce-back. So I’m not sure this has been received by you yet, and none of the commenters above mentioned this. Here goes:
Haha, the irony :) I’m sitting here coding JS myself, and testing in
Safari and Firefox mainly. But I need the script to work in IE as
well, of course, so I cursed IEs lacking debugging facilities a few
hours ago.. This led me to a google search aaand:
Scripting Debugging in Internet Explorer
I do not know if you are still having this trouble, but I used your page to help create a page using google maps that drew various sized circles, after working and working on getting IE to work I decided to reduce the circle size to the most common (and coincidentally the smallest) I needed. Lo and behold I discovered that increasing the PNG size in IE seems to work fine for me, its just reducing it.
You should try your code with a PNG circle the size of the smallest circle for a relatively small blast and see how it looks on IE. Of course scaling up an image hurts in when you zoom in on the map as the edges get pixelated, but for now I will just live with it, since for my application I need it to just work quickly anyway.