Decimal to Binary

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;
};
 
R

RobG

On 07/07/10 06:06, RobG wrote: [...]
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.

That would appear to depend on the Firefox version. Avoiding the
if-statement actually improved performance in my stand-alone
SpiderMonkey versions (tested 1.7.0 and 1.8.0rc1). The JS engine in
current Firefox versions may give different results, possibly as a
result of JIT compilation. On the other hand, the trunk version of V8
also runs the code (marginally) faster when there is no "if" statement
in the "for" loop. [...]
I think we're well into the area of engine specific optimizations now.

Yes. I ran several versions in Safari 5.0 and they were all about the
same, say +/- 5%. All of them were about 5x faster than the fastest in
Firefox 3.5.

I also tested against one of the BigInt.js libraries[1] mentioned in
another thread. It has a general conversion to any base that takes
twice as long as the bespoke version here for conversion to base 2.
Unfortunately the one I used is restricted to strings of 16 digits or
less, so it's not really suited to the library's goal of being "a
bigInt library for arbitrary-precision integers".


1. There appears to be more than one of these, I used this one:
<URL: http://www.leemon.com/crypto/BigInt.js >

But later I found this one:
<URL: http://www.onicos.com/staff/iz/amuse/javascript/expert/BigInt.txt
 
D

Dr J R Stockton

In comp.lang.javascript message <51e2706b-7d61-4472-b04c-27f5a7e19caf@x1
g2000prc.googlegroups.com>, Tue, 6 Jul 2010 21:06:58, RobG
Hopefully conversion from Boolean to number is robust (though JRS's
comments about the vagaries of number.toString(radix) have me
worried).

The aforementioned temporary page ... base-cnv.htm now includes two
versions for exact conversion of fixed-point strings from one base to
another. As well as one for truncation, one for proper rounding.

Before moving it to js-maths,htm, I'll probably "merge" them by adding a
switch for rounding actually being done.

Since Number to/from binary fixed-point string is not difficult, that
will provide a checker for Number.toString(radix).


SigSub : "ZBLIST, a Replacement for Vern Buerg's LIST.COM for
64-bit Computers" at <http://www.bizer.com/zblist/>. RIP.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,077
Messages
2,570,567
Members
47,203
Latest member
EmmaSwank1

Latest Threads

Top