R
RobG
On Jul 6, 3:29 am, Stefan Weiss wrote: [...]
without introducing at least one if-statement.
<snip>
What is wrong with the - if - statement?
Nothing, if it's faster than the alternative (and it is). Using the
shift operator is easily the fastest way to divide and round, that was
simple to implement. However, your suggestion of adding high bits and
subtracting 3 had me tossed for a while but then I realised it's the
same as right-shift then add 5. That didn't help (or hinder) IE but
did help Firefox.
The version below has what seem to be the best optimisations from
previous suggestions tested in IE 6 and Firefox. It is nearly the
fastest in IE and easily the fastest (so far) in Firefox. It uses a
combination of array and string methods, the fastest were selected
based on tests in the two browsers mentioned. I'll test more widely
later.
Optimisations worth mentioning are:
1. IE much prefers storing values to indexed lookups - even removing
one lookup had a big effect.
2. Replacing the if statement with a ternary operator is very slow in
IE, so more code is faster in this case.
3. Replacing the if statement to see if offset needed incrementing
with a type-conversion assignment made not much difference in IE but
really helped Firefox, i.e. the line:
offset += !bigInt[offset];
Hopefully conversion from Boolean to number is robust (though JRS's
comments about the vagaries of number.toString(radix) have me
worried).
var toBin = function(numStr) {
var bigInt = numStr.split(""),
len = bigInt.length,
result = "",
offset = 0,
rem, divPart, i, n;
do {
// Progressively halve number one digit at a time
for (rem=0, i=offset; i < len; ++i) {
n = bigInt;
// If previous digit was odd, halve this number
// and round down (trim rh bit) and add 5
if (rem) {
bigInt = (n >>> 1) + 5;
// Otherwise, just halve (trim rh bit)
} else {
bigInt = n >>> 1;
}
// Remember if this digit was odd for next loop
rem = n & 1;
}
// If digit is now zero, move to next
offset += !bigInt[offset];
// Prepend 1 to result if number was odd, otherwise 0
result = rem + result;
} while (offset < len);
return result;
};